From 27fd05320e4ab91e0e7bfbc2db04b369c02a9d4f Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 17 Aug 2009 14:10:03 +0200 Subject: [PATCH] button: use new object system Signed-off-by: Julien Danjou --- button.c | 184 ++++++++++++++------------------- button.h | 8 +- event.c | 14 +-- lib/awful/button.lua.in | 11 +- lib/awful/widget/common.lua.in | 6 +- luaa.c | 5 +- window.c | 2 +- 7 files changed, 99 insertions(+), 131 deletions(-) diff --git a/button.c b/button.c index 6d5cc1a5..8ee117f7 100644 --- a/button.c +++ b/button.c @@ -20,18 +20,12 @@ */ #include "button.h" - -#include "common/tokenize.h" +#include "luaa.h" +#include "key.h" /** Create a new mouse button bindings. * \param L The Lua VM state. * \return The number of elements pushed on stack. - * \luastack - * \lparam A table with modifiers keys, or a button to clone. - * \lparam A mouse button number, or 0 to match any button. - * \lparam A function to execute on click events. - * \lparam A function to execute on release events. - * \lreturn A mouse button binding. */ static int luaA_button_new(lua_State *L) @@ -39,26 +33,43 @@ luaA_button_new(lua_State *L) xcb_button_t xbutton; button_t *button; - lua_settop(L, 5); + /* compat code */ + if(lua_istable(L, 2) && lua_isnumber(L, 3)) + { + luaA_deprecate(L, "new syntax"); - luaA_checktable(L, 2); - /* arg 3 is mouse button */ - xbutton = luaL_checknumber(L, 3); + lua_settop(L, 5); - /* arg 4 and 5 are callback functions, check they are functions... */ - if(!lua_isnil(L, 4)) - luaA_checkfunction(L, 4); - if(!lua_isnil(L, 5)) - luaA_checkfunction(L, 5); + luaA_checktable(L, 2); + /* arg 3 is mouse button */ + xbutton = luaL_checknumber(L, 3); - button = button_new(L); + /* arg 4 and 5 are callback functions, check they are functions... */ + if(!lua_isnil(L, 4)) + luaA_checkfunction(L, 4); + if(!lua_isnil(L, 5)) + luaA_checkfunction(L, 5); - button->press = luaA_object_ref_item(L, -1, 4); - button->release = luaA_object_ref_item(L, -1, 4); - button->button = xbutton; - button->mod = luaA_tomodifiers(L, 2); + button = button_new(L); + button->button = xbutton; + button->modifiers = luaA_tomodifiers(L, 2); - return 1; + if(!lua_isnil(L, 4)) + { + lua_pushvalue(L, 4); + luaA_object_add_signal(L, -2, "press", -1); + } + + if(!lua_isnil(L, 5)) + { + lua_pushvalue(L, 5); + luaA_object_add_signal(L, -2, "release", -1); + } + + return 1; + } + + return luaA_class_new(L, &button_class); } /** Set a button array with a Lua table. @@ -104,98 +115,53 @@ luaA_button_array_get(lua_State *L, int oidx, button_array_t *buttons) return 1; } -/** Button object. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - * \lfield press The function called when button press event is received. - * \lfield release The function called when button release event is received. - * \lfield button The mouse button number, or 0 for any button. - * \lfield modifiers The modifier key table that should be pressed while the - * button is pressed. - */ +LUA_OBJECT_EXPORT_PROPERTY(button, button_t, button, lua_pushnumber); +LUA_OBJECT_EXPORT_PROPERTY(button, button_t, modifiers, luaA_pushmodifiers); + static int -luaA_button_index(lua_State *L) +luaA_button_set_modifiers(lua_State *L, button_t *b) { - if(luaA_usemetatable(L, 1, 2)) - return 1; - - size_t len; - button_t *button = luaL_checkudata(L, 1, "button"); - const char *attr = luaL_checklstring(L, 2, &len); - - switch(a_tokenize(attr, len)) - { - case A_TK_PRESS: - return luaA_object_push_item(L, 1, button->press); - case A_TK_RELEASE: - return luaA_object_push_item(L, 1, button->release); - case A_TK_BUTTON: - lua_pushnumber(L, button->button); - break; - case A_TK_MODIFIERS: - luaA_pushmodifiers(L, button->mod); - break; - default: - return 0; - } - - return 1; -} - -/** Button object. - * \param L The Lua VM state. - * \return The number of elements pushed on stack. - * \luastack - */ -static int -luaA_button_newindex(lua_State *L) -{ - if(luaA_usemetatable(L, 1, 2)) - return 1; - - size_t len; - button_t *button = luaL_checkudata(L, 1, "button"); - const char *attr = luaL_checklstring(L, 2, &len); - - switch(a_tokenize(attr, len)) - { - case A_TK_PRESS: - luaA_checkfunction(L, 3); - luaA_object_unref_item(L, 1, button->press); - button->press = luaA_object_ref_item(L, 1, 3); - break; - case A_TK_RELEASE: - luaA_checkfunction(L, 3); - luaA_object_unref_item(L, 1, button->release); - button->release = luaA_object_ref_item(L, 1, 3); - break; - case A_TK_BUTTON: - button->button = luaL_checknumber(L, 3); - break; - case A_TK_MODIFIERS: - button->mod = luaA_tomodifiers(L, 3); - break; - default: - break; - } - + b->modifiers = luaA_tomodifiers(L, -1); + luaA_object_emit_signal(L, -3, "property::modifiers", 0); return 0; } -const struct luaL_reg awesome_button_methods[] = +static int +luaA_button_set_button(lua_State *L, button_t *b) { - LUA_CLASS_METHODS(button) - { "__call", luaA_button_new }, - { NULL, NULL } -}; -const struct luaL_reg awesome_button_meta[] = + b->button = luaL_checknumber(L, -1); + luaA_object_emit_signal(L, -3, "property::button", 0); + return 0; +} + +void +button_class_setup(lua_State *L) { - LUA_OBJECT_META(button) - { "__index", luaA_button_index }, - { "__newindex", luaA_button_newindex }, - { "__gc", luaA_object_gc }, - { NULL, NULL } -}; + static const struct luaL_reg button_methods[] = + { + LUA_CLASS_METHODS(button) + { "__call", luaA_button_new }, + { NULL, NULL } + }; + + static const struct luaL_reg button_meta[] = + { + LUA_OBJECT_META(button) + LUA_CLASS_META + { "__gc", luaA_object_gc }, + { NULL, NULL } + }; + + luaA_class_setup(L, &button_class, "button", (lua_class_allocator_t) button_new, + button_methods, button_meta); + luaA_class_add_property(&button_class, A_TK_BUTTON, + (lua_class_propfunc_t) luaA_button_set_button, + (lua_class_propfunc_t) luaA_button_get_button, + (lua_class_propfunc_t) luaA_button_set_button); + luaA_class_add_property(&button_class, A_TK_MODIFIERS, + (lua_class_propfunc_t) luaA_button_set_modifiers, + (lua_class_propfunc_t) luaA_button_get_modifiers, + (lua_class_propfunc_t) luaA_button_set_modifiers); +} // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/button.h b/button.h index 59d731c5..246def30 100644 --- a/button.h +++ b/button.h @@ -29,13 +29,9 @@ struct button_t { LUA_OBJECT_HEADER /** Key modifiers */ - uint16_t mod; + uint16_t modifiers; /** Mouse button number */ xcb_button_t button; - /** Lua function to execute on press. */ - void *press; - /** Lua function to execute on release. */ - void *release; }; lua_class_t button_class; @@ -44,6 +40,8 @@ ARRAY_FUNCS(button_t *, button, DO_NOTHING) int luaA_button_array_get(lua_State *, int, button_array_t *); void luaA_button_array_set(lua_State *, int, int, button_array_t *); +void button_class_setup(lua_State *); #endif + // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/event.c b/event.c index 8a5dd830..0d10fabd 100644 --- a/event.c +++ b/event.c @@ -81,13 +81,6 @@ lua_pop(globalconf.L, nargs); \ } -static bool -event_button_match(xcb_button_press_event_t *ev, button_t *b, void *data) -{ - return ((!b->button || ev->detail == b->button) - && (b->mod == XCB_BUTTON_MASK_ANY || b->mod == ev->state)); -} - static bool event_key_match(xcb_key_press_event_t *ev, keyb_t *k, void *data) { @@ -98,6 +91,13 @@ event_key_match(xcb_key_press_event_t *ev, keyb_t *k, void *data) && (k->modifiers == XCB_BUTTON_MASK_ANY || k->modifiers == ev->state)); } +static bool +event_button_match(xcb_button_press_event_t *ev, button_t *b, void *data) +{ + return ((!b->button || ev->detail == b->button) + && (b->modifiers == XCB_BUTTON_MASK_ANY || b->modifiers == ev->state)); +} + DO_EVENT_HOOK_CALLBACK(button_t, button, button, XCB_BUTTON, button_array_t, event_button_match) DO_EVENT_HOOK_CALLBACK(keyb_t, key, key, XCB_KEY, key_array_t, event_key_match) diff --git a/lib/awful/button.lua.in b/lib/awful/button.lua.in index 38caf9d2..33635336 100644 --- a/lib/awful/button.lua.in +++ b/lib/awful/button.lua.in @@ -26,11 +26,18 @@ ignore_modifiers = { "Lock", "Mod2" } -- CapsLock off. -- @see capi.button -- @return A table with one or several button objects. -function new(mod, ...) +function new(mod, button, press, release) local ret = {} local subsets = util.subsets(ignore_modifiers) for _, set in ipairs(subsets) do - ret[#ret + 1] = capi.button(util.table.join(mod, set), ...) + ret[#ret + 1] = capi.button({ modifiers = util.table.join(mod, set), + button = button }) + if press then + ret[#ret]:add_signal("press", function(bobj, ...) press(...) end) + end + if release then + ret[#ret]:add_signal("release", function (bobj, ...) release(...) end) + end end return ret end diff --git a/lib/awful/widget/common.lua.in b/lib/awful/widget/common.lua.in index a301b086..e52ec3ee 100644 --- a/lib/awful/widget/common.lua.in +++ b/lib/awful/widget/common.lua.in @@ -9,8 +9,8 @@ local math = math local type = type local ipairs = ipairs local setmetatable = setmetatable -local capi = { widget = widget, - button = button } +local capi = { widget = widget } +local abutton = require("awful.button") --- Common widget code module("awful.widget.common") @@ -62,7 +62,7 @@ function list_update(w, buttons, label, data, widgets, objects) local press, release if bpress then press = function() bpress(o) end end if brelease then release = function () brelease(o) end end - data[o][kb] = capi.button(b.modifiers, b.button, press, release) + data[o][kb] = abutton(b.modifiers, b.button, press, release) end end w[k]:buttons(data[o]) diff --git a/luaa.c b/luaa.c index 7748c740..520f15d6 100644 --- a/luaa.c +++ b/luaa.c @@ -51,8 +51,6 @@ extern const struct luaL_reg awesome_hooks_lib[]; extern const struct luaL_reg awesome_keygrabber_lib[]; extern const struct luaL_reg awesome_mousegrabber_lib[]; extern const struct luaL_reg awesome_root_lib[]; -extern const struct luaL_reg awesome_button_methods[]; -extern const struct luaL_reg awesome_button_meta[]; extern const struct luaL_reg awesome_image_methods[]; extern const struct luaL_reg awesome_image_meta[]; extern const struct luaL_reg awesome_mouse_methods[]; @@ -740,8 +738,7 @@ luaA_init(xdgHandle* xdg) luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta); /* Export button */ - luaA_class_setup(L, &button_class, "button", (lua_class_allocator_t) button_new, - awesome_button_methods, awesome_button_meta); + button_class_setup(L); /* Export image */ luaA_class_setup(L, &image_class, "image", (lua_class_allocator_t) image_new, diff --git a/window.c b/window.c index a8c48396..23ce5e0a 100644 --- a/window.c +++ b/window.c @@ -106,7 +106,7 @@ window_buttons_grab(xcb_window_t win, button_array_t *buttons) foreach(b, *buttons) xcb_grab_button(globalconf.connection, false, win, BUTTONMASK, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, - (*b)->button, (*b)->mod); + (*b)->button, (*b)->modifiers); } /** Get the opacity of a window.