[lua] Add new keybinding interface
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
ebb56ce6b1
commit
b6e31563d0
|
@ -122,6 +122,7 @@ awesome_SOURCES = \
|
|||
cnode.c cnode.h \
|
||||
event.c event.h \
|
||||
layout.c layout.h \
|
||||
keybinding.c keybinding.h \
|
||||
awesome.c \
|
||||
tag.c tag.h \
|
||||
lua.c lua.h \
|
||||
|
|
|
@ -112,64 +112,64 @@ for s = 1, screen.count() do
|
|||
end
|
||||
|
||||
for i = 1, keynumber do
|
||||
awesome.key({ modkey }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewonly(tags[screen][i])
|
||||
end
|
||||
end)
|
||||
awesome.key({ modkey, "Control" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
tags[i]:view(not tags[screen][i]:isselected())
|
||||
end
|
||||
end)
|
||||
awesome.key({ modkey, "Shift" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.client.movetotag(tags[screen][i])
|
||||
end
|
||||
end)
|
||||
awesome.key({ modkey, "Control", "Shift" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.client.toggletag(tags[screen][i])
|
||||
end
|
||||
end)
|
||||
keybinding.new({ modkey }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.tag.viewonly(tags[screen][i])
|
||||
end
|
||||
end):add()
|
||||
keybinding.new({ modkey, "Control" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
tags[i]:view(not tags[screen][i]:isselected())
|
||||
end
|
||||
end):add()
|
||||
keybinding.new({ modkey, "Shift" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.client.movetotag(tags[screen][i])
|
||||
end
|
||||
end):add()
|
||||
keybinding.new({ modkey, "Control", "Shift" }, i,
|
||||
function ()
|
||||
local screen = mouse.screen_get()
|
||||
if tags[screen][i] then
|
||||
awful.client.toggletag(tags[screen][i])
|
||||
end
|
||||
end):add()
|
||||
end
|
||||
|
||||
awesome.key({ modkey }, "Left", awful.tag.viewprev)
|
||||
awesome.key({ modkey }, "Right", awful.tag.viewnext)
|
||||
keybinding.new({ modkey }, "Left", awful.tag.viewprev):add()
|
||||
keybinding.new({ modkey }, "Right", awful.tag.viewnext):add()
|
||||
|
||||
-- Standard program
|
||||
awesome.key({ modkey }, "Return", function () awful.spawn(terminal) end)
|
||||
keybinding.new({ modkey }, "Return", function () awful.spawn(terminal) end):add()
|
||||
|
||||
awesome.key({ modkey, "Control" }, "r", awesome.restart)
|
||||
awesome.key({ modkey, "Shift" }, "q", awesome.quit)
|
||||
keybinding.new({ modkey, "Control" }, "r", awesome.restart):add()
|
||||
keybinding.new({ modkey, "Shift" }, "q", awesome.quit):add()
|
||||
|
||||
-- Client manipulation
|
||||
awesome.key({ modkey, "Shift" }, "c", function () client.focus_get():kill() end)
|
||||
awesome.key({ modkey }, "j", function () awful.client.focus(1); client.focus_get():raise() end)
|
||||
awesome.key({ modkey }, "k", function () awful.client.focus(-1); client.focus_get():raise() end)
|
||||
awesome.key({ modkey, "Shift" }, "j", function () awful.client.swap(1) end)
|
||||
awesome.key({ modkey, "Shift" }, "k", function () awful.client.swap(-1) end)
|
||||
awesome.key({ modkey, "Control" }, "j", function () awful.screen.focus(1) end)
|
||||
awesome.key({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end)
|
||||
awesome.key({ modkey, "Control" }, "space", function () awful.client.togglefloating() end)
|
||||
keybinding.new({ modkey, "Shift" }, "c", function () client.focus_get():kill() end):add()
|
||||
keybinding.new({ modkey }, "j", function () awful.client.focus(1); client.focus_get():raise() end):add()
|
||||
keybinding.new({ modkey }, "k", function () awful.client.focus(-1); client.focus_get():raise() end):add()
|
||||
keybinding.new({ modkey, "Shift" }, "j", function () awful.client.swap(1) end):add()
|
||||
keybinding.new({ modkey, "Shift" }, "k", function () awful.client.swap(-1) end):add()
|
||||
keybinding.new({ modkey, "Control" }, "j", function () awful.screen.focus(1) end):add()
|
||||
keybinding.new({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end):add()
|
||||
keybinding.new({ modkey, "Control" }, "space", function () awful.client.togglefloating() end):add()
|
||||
|
||||
-- Layout manipulation
|
||||
awesome.key({ modkey }, "l", function () awful.tag.incmwfact(0.05) end)
|
||||
awesome.key({ modkey }, "h", function () awful.tag.incmwfact(-0.05) end)
|
||||
awesome.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(1) end)
|
||||
awesome.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end)
|
||||
awesome.key({ modkey, "Control" }, "h", function () awful.tag.incncol(1) end)
|
||||
awesome.key({ modkey, "Control" }, "l", function () awful.tag.incncol(1) end)
|
||||
awesome.key({ modkey }, "space", function () awful.layout.inc(layouts, 1) end)
|
||||
awesome.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end)
|
||||
keybinding.new({ modkey }, "l", function () awful.tag.incmwfact(0.05) end):add()
|
||||
keybinding.new({ modkey }, "h", function () awful.tag.incmwfact(-0.05) end):add()
|
||||
keybinding.new({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(1) end):add()
|
||||
keybinding.new({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end):add()
|
||||
keybinding.new({ modkey, "Control" }, "h", function () awful.tag.incncol(1) end):add()
|
||||
keybinding.new({ modkey, "Control" }, "l", function () awful.tag.incncol(1) end):add()
|
||||
keybinding.new({ modkey }, "space", function () awful.layout.inc(layouts, 1) end):add()
|
||||
keybinding.new({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end):add()
|
||||
-- }}}
|
||||
|
||||
-- {{{ Hooks
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* keybinding.c - Key bindings configuration management
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* XStringToKeysym() */
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "structs.h"
|
||||
#include "lua.h"
|
||||
#include "window.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
||||
static void
|
||||
__luaA_keystore(keybinding_t *key, const char *str)
|
||||
{
|
||||
xcb_keycode_t kc;
|
||||
int ikc;
|
||||
|
||||
if(!a_strlen(str))
|
||||
return;
|
||||
else if(a_strncmp(str, "#", 1))
|
||||
key->keysym = XStringToKeysym(str);
|
||||
else
|
||||
{
|
||||
ikc = atoi(str + 1);
|
||||
memcpy(&kc, &ikc, sizeof(KeyCode));
|
||||
key->keycode = kc;
|
||||
}
|
||||
}
|
||||
|
||||
/** Define a global key binding. This key binding will always be available.
|
||||
* \param A table with modifier keys.
|
||||
* \param A key name.
|
||||
* \param A function to execute.
|
||||
*/
|
||||
static int
|
||||
luaA_keybinding_new(lua_State *L)
|
||||
{
|
||||
size_t i, len;
|
||||
keybinding_t *k, **keyb;
|
||||
const char *key;
|
||||
|
||||
/* arg 1 is key mod table */
|
||||
luaA_checktable(L, 1);
|
||||
/* arg 2 is key */
|
||||
key = luaL_checkstring(L, 2);
|
||||
/* arg 3 is cmd to run */
|
||||
luaA_checkfunction(L, 3);
|
||||
|
||||
/* get the last arg as function */
|
||||
k = p_new(keybinding_t, 1);
|
||||
__luaA_keystore(k, key);
|
||||
k->fct = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
len = lua_objlen(L, 1);
|
||||
for(i = 1; i <= len; i++)
|
||||
{
|
||||
lua_rawgeti(L, 1, i);
|
||||
k->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1));
|
||||
}
|
||||
|
||||
keyb = lua_newuserdata(globalconf.L, sizeof(client_t *));
|
||||
*keyb = k;
|
||||
keybinding_ref(keyb);
|
||||
return luaA_settype(L, "keybinding");
|
||||
}
|
||||
|
||||
/** Add a global key binding. This key binding will always be available.
|
||||
*/
|
||||
static int
|
||||
luaA_keybinding_add(lua_State *L)
|
||||
{
|
||||
keybinding_t *key, **k = luaL_checkudata(L, 1, "keybinding");
|
||||
|
||||
/* Check that the keybinding has not been already added. */
|
||||
for(key = globalconf.keys; key; key = key->next)
|
||||
if(key == *k)
|
||||
luaL_error(L, "keybinding already added");
|
||||
|
||||
keybinding_list_push(&globalconf.keys, *k);
|
||||
|
||||
keybinding_ref(k);
|
||||
|
||||
window_root_grabkey(*k);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Remove a global key binding.
|
||||
*/
|
||||
static int
|
||||
luaA_keybinding_remove(lua_State *L)
|
||||
{
|
||||
keybinding_t **k = luaL_checkudata(L, 1, "keybinding");
|
||||
|
||||
keybinding_list_detach(&globalconf.keys, *k);
|
||||
|
||||
keybinding_unref(k);
|
||||
|
||||
window_root_ungrabkey(*k);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Handle keybinding garbage collection.
|
||||
*/
|
||||
static int
|
||||
luaA_keybinding_gc(lua_State *L)
|
||||
{
|
||||
keybinding_t **keybinding = luaL_checkudata(L, 1, "keybinding");
|
||||
keybinding_unref(keybinding);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Convert a keybinding to a printable string.
|
||||
* \return A string.
|
||||
*/
|
||||
static int
|
||||
luaA_keybinding_tostring(lua_State *L)
|
||||
{
|
||||
keybinding_t **p = luaL_checkudata(L, 1, "keybinding");
|
||||
lua_pushfstring(L, "[keybinding udata(%p)]", *p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct luaL_reg awesome_keybinding_methods[] =
|
||||
{
|
||||
{ "new", luaA_keybinding_new },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
const struct luaL_reg awesome_keybinding_meta[] =
|
||||
{
|
||||
{"add", luaA_keybinding_add },
|
||||
{"remove", luaA_keybinding_remove },
|
||||
{"__tostring", luaA_keybinding_tostring },
|
||||
{"__gc", luaA_keybinding_gc },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* keybinding.h - Key bindings configuration management header
|
||||
*
|
||||
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_KEYBINDING_H
|
||||
#define AWESOME_KEYBINDING_H
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
67
lua.c
67
lua.c
|
@ -29,15 +29,12 @@
|
|||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
|
||||
/* XStringToKeysym() */
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "structs.h"
|
||||
#include "lua.h"
|
||||
#include "window.h"
|
||||
#include "tag.h"
|
||||
#include "client.h"
|
||||
#include "window.h"
|
||||
#include "layouts/tile.h"
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
@ -56,24 +53,8 @@ extern const struct luaL_reg awesome_widget_methods[];
|
|||
extern const struct luaL_reg awesome_widget_meta[];
|
||||
extern const struct luaL_reg awesome_statusbar_methods[];
|
||||
extern const struct luaL_reg awesome_statusbar_meta[];
|
||||
|
||||
static void
|
||||
__luaA_keystore(keybinding_t *key, const char *str)
|
||||
{
|
||||
xcb_keycode_t kc;
|
||||
int ikc;
|
||||
|
||||
if(!a_strlen(str))
|
||||
return;
|
||||
else if(a_strncmp(str, "#", 1))
|
||||
key->keysym = XStringToKeysym(str);
|
||||
else
|
||||
{
|
||||
ikc = atoi(str + 1);
|
||||
memcpy(&kc, &ikc, sizeof(KeyCode));
|
||||
key->keycode = kc;
|
||||
}
|
||||
}
|
||||
extern const struct luaL_reg awesome_keybinding_methods[];
|
||||
extern const struct luaL_reg awesome_keybinding_meta[];
|
||||
|
||||
/** Define a global mouse binding. This binding will be available wehn you
|
||||
* click on root window.
|
||||
|
@ -113,44 +94,6 @@ luaA_mouse(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Define a global key binding. This key binding will always be available.
|
||||
* \param A table with modifier keys.
|
||||
* \param A key name.
|
||||
* \param A function to execute.
|
||||
*/
|
||||
static int
|
||||
luaA_key(lua_State *L)
|
||||
{
|
||||
size_t i, len;
|
||||
keybinding_t *k;
|
||||
const char *key;
|
||||
|
||||
/* arg 1 is key mod table */
|
||||
luaA_checktable(L, 1);
|
||||
/* arg 2 is key */
|
||||
key = luaL_checkstring(L, 2);
|
||||
/* arg 3 is cmd to run */
|
||||
luaA_checkfunction(L, 3);
|
||||
|
||||
/* get the last arg as function */
|
||||
k = p_new(keybinding_t, 1);
|
||||
__luaA_keystore(k, key);
|
||||
k->fct = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
len = lua_objlen(L, 1);
|
||||
for(i = 1; i <= len; i++)
|
||||
{
|
||||
lua_rawgeti(L, 1, i);
|
||||
k->mod |= xutil_keymask_fromstr(luaL_checkstring(L, -1));
|
||||
}
|
||||
|
||||
keybinding_list_push(&globalconf.keys, k);
|
||||
|
||||
window_root_grabkey(k);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Set the floating placement algorithm. This will be used to compute the
|
||||
* initial floating position of floating windows.
|
||||
* \param An algorith name, either `none', `smart' or `mouse'.
|
||||
|
@ -431,7 +374,6 @@ luaA_parserc(const char *rcfile)
|
|||
{ "restart", luaA_restart },
|
||||
{ "floating_placement_set", luaA_floating_placement_set },
|
||||
{ "padding_set", luaA_padding_set },
|
||||
{ "key", luaA_key },
|
||||
{ "mouse", luaA_mouse },
|
||||
{ "resizehints_set", luaA_resizehints_set },
|
||||
{ "font_set", luaA_font_set },
|
||||
|
@ -488,6 +430,9 @@ luaA_parserc(const char *rcfile)
|
|||
/* Export titlebar */
|
||||
luaA_openlib(L, "titlebar", awesome_titlebar_methods, awesome_titlebar_meta);
|
||||
|
||||
/* Export keys */
|
||||
luaA_openlib(L, "keybinding", awesome_keybinding_methods, awesome_keybinding_meta);
|
||||
|
||||
lua_pushliteral(L, "AWESOME_VERSION");
|
||||
lua_pushliteral(L, VERSION);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
|
|
@ -79,6 +79,8 @@ DO_RCNT(titlebar_t, titlebar, titlebar_delete)
|
|||
typedef struct keybinding_t keybinding_t;
|
||||
struct keybinding_t
|
||||
{
|
||||
/** Ref count */
|
||||
int refcount;
|
||||
/** Key modifier */
|
||||
unsigned long mod;
|
||||
/** Keysym */
|
||||
|
@ -92,6 +94,7 @@ struct keybinding_t
|
|||
};
|
||||
|
||||
DO_SLIST(keybinding_t, keybinding, p_delete)
|
||||
DO_RCNT(keybinding_t, keybinding, p_delete)
|
||||
|
||||
/** Mouse buttons bindings */
|
||||
typedef struct button_t button_t;
|
||||
|
|
30
window.c
30
window.c
|
@ -209,7 +209,6 @@ window_root_grabkey(keybinding_t *k)
|
|||
|
||||
if((kc = k->keycode)
|
||||
|| (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym))))
|
||||
{
|
||||
do
|
||||
{
|
||||
s = xcb_aux_get_screen(globalconf.connection, phys_screen);
|
||||
|
@ -225,7 +224,34 @@ window_root_grabkey(keybinding_t *k)
|
|||
phys_screen++;
|
||||
} while(!globalconf.screens_info->xinerama_is_active
|
||||
&& phys_screen < globalconf.screens_info->nscreen);
|
||||
}
|
||||
}
|
||||
|
||||
/** Ungrab key on the root windows.
|
||||
* \param k The keybinding.
|
||||
*/
|
||||
void
|
||||
window_root_ungrabkey(keybinding_t *k)
|
||||
{
|
||||
int phys_screen = globalconf.default_screen;
|
||||
xcb_screen_t *s;
|
||||
xcb_keycode_t kc;
|
||||
|
||||
if((kc = k->keycode)
|
||||
|| (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym))))
|
||||
do
|
||||
{
|
||||
s = xcb_aux_get_screen(globalconf.connection, phys_screen);
|
||||
xcb_ungrab_key(globalconf.connection, kc, s->root,
|
||||
k->mod);
|
||||
xcb_ungrab_key(globalconf.connection, kc, s->root,
|
||||
k->mod | XCB_MOD_MASK_LOCK);
|
||||
xcb_ungrab_key(globalconf.connection, kc, s->root,
|
||||
k->mod | globalconf.numlockmask);
|
||||
xcb_ungrab_key(globalconf.connection, kc, s->root,
|
||||
k->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK);
|
||||
phys_screen++;
|
||||
} while(!globalconf.screens_info->xinerama_is_active
|
||||
&& phys_screen < globalconf.screens_info->nscreen);
|
||||
}
|
||||
|
||||
/** Set shape property on window.
|
||||
|
|
1
window.h
1
window.h
|
@ -31,6 +31,7 @@ void window_grabbuttons(xcb_window_t, int);
|
|||
void window_root_grabbutton(button_t *);
|
||||
void window_root_grabbuttons(void);
|
||||
void window_root_grabkey(keybinding_t *);
|
||||
void window_root_ungrabkey(keybinding_t *);
|
||||
void window_setshape(xcb_window_t, int);
|
||||
void window_settrans(xcb_window_t, double);
|
||||
|
||||
|
|
Loading…
Reference in New Issue