[lua] Add new keybinding interface

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-05-28 12:15:00 +02:00
parent ebb56ce6b1
commit b6e31563d0
8 changed files with 271 additions and 112 deletions

View File

@ -122,6 +122,7 @@ awesome_SOURCES = \
cnode.c cnode.h \ cnode.c cnode.h \
event.c event.h \ event.c event.h \
layout.c layout.h \ layout.c layout.h \
keybinding.c keybinding.h \
awesome.c \ awesome.c \
tag.c tag.h \ tag.c tag.h \
lua.c lua.h \ lua.c lua.h \

View File

@ -112,64 +112,64 @@ for s = 1, screen.count() do
end end
for i = 1, keynumber do for i = 1, keynumber do
awesome.key({ modkey }, i, keybinding.new({ modkey }, i,
function () function ()
local screen = mouse.screen_get() local screen = mouse.screen_get()
if tags[screen][i] then if tags[screen][i] then
awful.tag.viewonly(tags[screen][i]) awful.tag.viewonly(tags[screen][i])
end end
end) end):add()
awesome.key({ modkey, "Control" }, i, keybinding.new({ modkey, "Control" }, i,
function () function ()
local screen = mouse.screen_get() local screen = mouse.screen_get()
if tags[screen][i] then if tags[screen][i] then
tags[i]:view(not tags[screen][i]:isselected()) tags[i]:view(not tags[screen][i]:isselected())
end end
end) end):add()
awesome.key({ modkey, "Shift" }, i, keybinding.new({ modkey, "Shift" }, i,
function () function ()
local screen = mouse.screen_get() local screen = mouse.screen_get()
if tags[screen][i] then if tags[screen][i] then
awful.client.movetotag(tags[screen][i]) awful.client.movetotag(tags[screen][i])
end end
end) end):add()
awesome.key({ modkey, "Control", "Shift" }, i, keybinding.new({ modkey, "Control", "Shift" }, i,
function () function ()
local screen = mouse.screen_get() local screen = mouse.screen_get()
if tags[screen][i] then if tags[screen][i] then
awful.client.toggletag(tags[screen][i]) awful.client.toggletag(tags[screen][i])
end end
end) end):add()
end end
awesome.key({ modkey }, "Left", awful.tag.viewprev) keybinding.new({ modkey }, "Left", awful.tag.viewprev):add()
awesome.key({ modkey }, "Right", awful.tag.viewnext) keybinding.new({ modkey }, "Right", awful.tag.viewnext):add()
-- Standard program -- 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) keybinding.new({ modkey, "Control" }, "r", awesome.restart):add()
awesome.key({ modkey, "Shift" }, "q", awesome.quit) keybinding.new({ modkey, "Shift" }, "q", awesome.quit):add()
-- Client manipulation -- Client manipulation
awesome.key({ modkey, "Shift" }, "c", function () client.focus_get():kill() end) keybinding.new({ modkey, "Shift" }, "c", function () client.focus_get():kill() end):add()
awesome.key({ modkey }, "j", function () awful.client.focus(1); client.focus_get():raise() end) keybinding.new({ modkey }, "j", function () awful.client.focus(1); client.focus_get():raise() end):add()
awesome.key({ modkey }, "k", function () awful.client.focus(-1); client.focus_get():raise() end) keybinding.new({ modkey }, "k", function () awful.client.focus(-1); client.focus_get():raise() end):add()
awesome.key({ modkey, "Shift" }, "j", function () awful.client.swap(1) end) keybinding.new({ modkey, "Shift" }, "j", function () awful.client.swap(1) end):add()
awesome.key({ modkey, "Shift" }, "k", function () awful.client.swap(-1) end) keybinding.new({ modkey, "Shift" }, "k", function () awful.client.swap(-1) end):add()
awesome.key({ modkey, "Control" }, "j", function () awful.screen.focus(1) end) keybinding.new({ modkey, "Control" }, "j", function () awful.screen.focus(1) end):add()
awesome.key({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end) keybinding.new({ modkey, "Control" }, "k", function () awful.screen.focus(-1) end):add()
awesome.key({ modkey, "Control" }, "space", function () awful.client.togglefloating() end) keybinding.new({ modkey, "Control" }, "space", function () awful.client.togglefloating() end):add()
-- Layout manipulation -- Layout manipulation
awesome.key({ modkey }, "l", function () awful.tag.incmwfact(0.05) end) keybinding.new({ modkey }, "l", function () awful.tag.incmwfact(0.05) end):add()
awesome.key({ modkey }, "h", function () awful.tag.incmwfact(-0.05) end) keybinding.new({ modkey }, "h", function () awful.tag.incmwfact(-0.05) end):add()
awesome.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(1) end) keybinding.new({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(1) end):add()
awesome.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end) keybinding.new({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end):add()
awesome.key({ modkey, "Control" }, "h", function () awful.tag.incncol(1) end) keybinding.new({ modkey, "Control" }, "h", function () awful.tag.incncol(1) end):add()
awesome.key({ modkey, "Control" }, "l", function () awful.tag.incncol(1) end) keybinding.new({ modkey, "Control" }, "l", function () awful.tag.incncol(1) end):add()
awesome.key({ modkey }, "space", function () awful.layout.inc(layouts, 1) end) keybinding.new({ modkey }, "space", function () awful.layout.inc(layouts, 1) end):add()
awesome.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end) keybinding.new({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1) end):add()
-- }}} -- }}}
-- {{{ Hooks -- {{{ Hooks

157
keybinding.c Normal file
View File

@ -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 },
};

26
keybinding.h Normal file
View File

@ -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
View File

@ -29,15 +29,12 @@
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_aux.h> #include <xcb/xcb_aux.h>
/* XStringToKeysym() */
#include <X11/Xlib.h>
#include "config.h" #include "config.h"
#include "structs.h" #include "structs.h"
#include "lua.h" #include "lua.h"
#include "window.h"
#include "tag.h" #include "tag.h"
#include "client.h" #include "client.h"
#include "window.h"
#include "layouts/tile.h" #include "layouts/tile.h"
extern awesome_t globalconf; 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_widget_meta[];
extern const struct luaL_reg awesome_statusbar_methods[]; extern const struct luaL_reg awesome_statusbar_methods[];
extern const struct luaL_reg awesome_statusbar_meta[]; extern const struct luaL_reg awesome_statusbar_meta[];
extern const struct luaL_reg awesome_keybinding_methods[];
static void extern const struct luaL_reg awesome_keybinding_meta[];
__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 mouse binding. This binding will be available wehn you /** Define a global mouse binding. This binding will be available wehn you
* click on root window. * click on root window.
@ -113,44 +94,6 @@ luaA_mouse(lua_State *L)
return 0; 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 /** Set the floating placement algorithm. This will be used to compute the
* initial floating position of floating windows. * initial floating position of floating windows.
* \param An algorith name, either `none', `smart' or `mouse'. * \param An algorith name, either `none', `smart' or `mouse'.
@ -431,7 +374,6 @@ luaA_parserc(const char *rcfile)
{ "restart", luaA_restart }, { "restart", luaA_restart },
{ "floating_placement_set", luaA_floating_placement_set }, { "floating_placement_set", luaA_floating_placement_set },
{ "padding_set", luaA_padding_set }, { "padding_set", luaA_padding_set },
{ "key", luaA_key },
{ "mouse", luaA_mouse }, { "mouse", luaA_mouse },
{ "resizehints_set", luaA_resizehints_set }, { "resizehints_set", luaA_resizehints_set },
{ "font_set", luaA_font_set }, { "font_set", luaA_font_set },
@ -488,6 +430,9 @@ luaA_parserc(const char *rcfile)
/* Export titlebar */ /* Export titlebar */
luaA_openlib(L, "titlebar", awesome_titlebar_methods, awesome_titlebar_meta); 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, "AWESOME_VERSION");
lua_pushliteral(L, VERSION); lua_pushliteral(L, VERSION);
lua_settable(L, LUA_GLOBALSINDEX); lua_settable(L, LUA_GLOBALSINDEX);

View File

@ -79,6 +79,8 @@ DO_RCNT(titlebar_t, titlebar, titlebar_delete)
typedef struct keybinding_t keybinding_t; typedef struct keybinding_t keybinding_t;
struct keybinding_t struct keybinding_t
{ {
/** Ref count */
int refcount;
/** Key modifier */ /** Key modifier */
unsigned long mod; unsigned long mod;
/** Keysym */ /** Keysym */
@ -92,6 +94,7 @@ struct keybinding_t
}; };
DO_SLIST(keybinding_t, keybinding, p_delete) DO_SLIST(keybinding_t, keybinding, p_delete)
DO_RCNT(keybinding_t, keybinding, p_delete)
/** Mouse buttons bindings */ /** Mouse buttons bindings */
typedef struct button_t button_t; typedef struct button_t button_t;

View File

@ -209,7 +209,6 @@ window_root_grabkey(keybinding_t *k)
if((kc = k->keycode) if((kc = k->keycode)
|| (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym)))) || (k->keysym && (kc = xcb_key_symbols_get_keycode(globalconf.keysyms, k->keysym))))
{
do do
{ {
s = xcb_aux_get_screen(globalconf.connection, phys_screen); s = xcb_aux_get_screen(globalconf.connection, phys_screen);
@ -225,7 +224,34 @@ window_root_grabkey(keybinding_t *k)
phys_screen++; phys_screen++;
} while(!globalconf.screens_info->xinerama_is_active } while(!globalconf.screens_info->xinerama_is_active
&& phys_screen < globalconf.screens_info->nscreen); && 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. /** Set shape property on window.

View File

@ -31,6 +31,7 @@ void window_grabbuttons(xcb_window_t, int);
void window_root_grabbutton(button_t *); void window_root_grabbutton(button_t *);
void window_root_grabbuttons(void); void window_root_grabbuttons(void);
void window_root_grabkey(keybinding_t *); void window_root_grabkey(keybinding_t *);
void window_root_ungrabkey(keybinding_t *);
void window_setshape(xcb_window_t, int); void window_setshape(xcb_window_t, int);
void window_settrans(xcb_window_t, double); void window_settrans(xcb_window_t, double);