key, button: use as simple table

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-07-28 10:44:54 +02:00
parent f6d2aa3064
commit d7454f4307
22 changed files with 130 additions and 337 deletions

View File

@ -158,11 +158,11 @@ for s = 1, screen.count() do
-- Create an imagebox widget which will contains an icon indicating which layout we're using. -- Create an imagebox widget which will contains an icon indicating which layout we're using.
-- We need one layoutbox per screen. -- We need one layoutbox per screen.
mylayoutbox[s] = awful.widget.layoutbox(s) mylayoutbox[s] = awful.widget.layoutbox(s)
mylayoutbox[s]:buttons(awful.util.table.join( mylayoutbox[s].buttons = awful.util.table.join(
awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end), awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end), awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end))) awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end))
-- Create a taglist widget -- Create a taglist widget
mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons) mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.label.all, mytaglist.buttons)
@ -191,11 +191,10 @@ end
-- }}} -- }}}
-- {{{ Mouse bindings -- {{{ Mouse bindings
root.buttons(awful.util.table.join( root.buttons = awful.util.table.join(
awful.button({ }, 3, function () mymainmenu:toggle() end), awful.button({ }, 3, function () mymainmenu:toggle() end),
awful.button({ }, 4, awful.tag.viewnext), awful.button({ }, 4, awful.tag.viewnext),
awful.button({ }, 5, awful.tag.viewprev) awful.button({ }, 5, awful.tag.viewprev))
))
-- }}} -- }}}
-- {{{ Key bindings -- {{{ Key bindings
@ -318,7 +317,7 @@ for i = 1, keynumber do
end end
-- Set keys -- Set keys
root.keys(globalkeys) root.keys = globalkeys
-- }}} -- }}}
-- {{{ Hooks -- {{{ Hooks
@ -369,11 +368,10 @@ awful.hooks.manage.register(function (c, startup)
awful.titlebar.add(c, { modkey = modkey }) awful.titlebar.add(c, { modkey = modkey })
end end
-- Add mouse bindings -- Add mouse bindings
c:buttons(awful.util.table.join( c.buttons = awful.util.table.join(
awful.button({ }, 1, function (c) client.focus = c; c:raise() end), awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
awful.button({ modkey }, 1, awful.mouse.client.move), awful.button({ modkey }, 1, awful.mouse.client.move),
awful.button({ modkey }, 3, awful.mouse.client.resize) awful.button({ modkey }, 3, awful.mouse.client.resize))
))
-- New client may not receive focus -- New client may not receive focus
-- if they're not focusable, so set border anyway. -- if they're not focusable, so set border anyway.
c.border_width = beautiful.border_width c.border_width = beautiful.border_width
@ -404,7 +402,7 @@ awful.hooks.manage.register(function (c, startup)
client.focus = c client.focus = c
-- Set key bindings -- Set key bindings
c:keys(clientkeys) c.keys = clientkeys
-- Set the windows at the slave, -- Set the windows at the slave,
-- i.e. put it at the end of others instead of setting it master. -- i.e. put it at the end of others instead of setting it master.

View File

@ -63,49 +63,6 @@ luaA_button_new(lua_State *L)
return 1; return 1;
} }
/** Set a button array with a Lua table.
* \param L The Lua VM state.
* \param oidx The index of the object to store items into.
* \param idx The index of the Lua table.
* \param buttons The array button to fill.
*/
void
luaA_button_array_set(lua_State *L, int oidx, int idx, button_array_t *buttons)
{
luaA_checktable(L, idx);
foreach(button, *buttons)
luaA_object_unref_item(L, oidx, *button);
button_array_wipe(buttons);
button_array_init(buttons);
lua_pushnil(L);
while(lua_next(L, idx))
if(luaA_toudata(L, -1, "button"))
button_array_append(buttons, luaA_object_ref_item(L, oidx, -1));
else
lua_pop(L, 1);
}
/** Push an array of button as an Lua table onto the stack.
* \param L The Lua VM state.
* \param oidx The index of the object to get items from.
* \param buttons The button array to push.
* \return The number of elements pushed on stack.
*/
int
luaA_button_array_get(lua_State *L, int oidx, button_array_t *buttons)
{
lua_createtable(L, buttons->len, 0);
for(int i = 0; i < buttons->len; i++)
{
luaA_object_push_item(L, oidx, buttons->tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
/** Button object. /** Button object.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.

View File

@ -38,11 +38,7 @@ struct button_t
void *release; void *release;
}; };
ARRAY_FUNCS(button_t *, button, DO_NOTHING)
LUA_OBJECT_FUNCS(button_t, button, "button") LUA_OBJECT_FUNCS(button_t, button, "button")
int luaA_button_array_get(lua_State *, int, button_array_t *);
void luaA_button_array_set(lua_State *, int, int, button_array_t *);
#endif #endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View File

@ -51,8 +51,6 @@ static int
luaA_client_gc(lua_State *L) luaA_client_gc(lua_State *L)
{ {
client_t *c = luaL_checkudata(L, 1, "client"); client_t *c = luaL_checkudata(L, 1, "client");
button_array_wipe(&c->buttons);
key_array_wipe(&c->keys);
xcb_get_wm_protocols_reply_wipe(&c->protocols); xcb_get_wm_protocols_reply_wipe(&c->protocols);
p_delete(&c->class); p_delete(&c->class);
p_delete(&c->startup_id); p_delete(&c->startup_id);
@ -1552,6 +1550,14 @@ luaA_client_newindex(lua_State *L)
c->skiptb = luaA_checkboolean(L, 3); c->skiptb = luaA_checkboolean(L, 3);
hook_property(client, c, "skip_taskbar"); hook_property(client, c, "skip_taskbar");
break; break;
case A_TK_KEYS:
luaA_object_unref_item(L, 1, c->keys);
c->keys = luaA_object_ref_item(L, 1, 3);
break;
case A_TK_BUTTONS:
luaA_object_unref_item(L, 1, c->buttons);
c->buttons = luaA_object_ref_item(L, 1, 3);
break;
default: default:
return 0; return 0;
} }
@ -1893,6 +1899,10 @@ luaA_client_index(lua_State *L)
} }
} }
break; break;
case A_TK_KEYS:
return luaA_object_push_item(L, 1, c->keys);
case A_TK_BUTTONS:
return luaA_object_push_item(L, 1, c->buttons);
default: default:
return 0; return 0;
} }
@ -1900,46 +1910,6 @@ luaA_client_index(lua_State *L)
return 1; return 1;
} }
/** Get or set mouse buttons bindings for a client.
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lvalue A client.
* \lparam An array of mouse button bindings objects, or nothing.
* \return The array of mouse button bindings objects of this client.
*/
static int
luaA_client_buttons(lua_State *L)
{
client_t *client = luaA_client_checkudata(L, 1);
button_array_t *buttons = &client->buttons;
if(lua_gettop(L) == 2)
luaA_button_array_set(L, 1, 2, buttons);
return luaA_button_array_get(L, 1, buttons);
}
/** Get or set keys bindings for a client.
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lvalue A client.
* \lparam An array of key bindings objects, or nothing.
* \return The array of key bindings objects of this client.
*/
static int
luaA_client_keys(lua_State *L)
{
client_t *c = luaA_client_checkudata(L, 1);
key_array_t *keys = &c->keys;
if(lua_gettop(L) == 2)
luaA_key_array_set(L, 1, 2, keys);
return luaA_key_array_get(L, 1, keys);
}
/* Client module. /* Client module.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of pushed elements. * \return The number of pushed elements.
@ -1996,8 +1966,6 @@ const struct luaL_reg awesome_client_meta[] =
{ "isvisible", luaA_client_isvisible }, { "isvisible", luaA_client_isvisible },
{ "geometry", luaA_client_geometry }, { "geometry", luaA_client_geometry },
{ "struts", luaA_client_struts }, { "struts", luaA_client_struts },
{ "buttons", luaA_client_buttons },
{ "keys", luaA_client_keys },
{ "tags", luaA_client_tags }, { "tags", luaA_client_tags },
{ "kill", luaA_client_kill }, { "kill", luaA_client_kill },
{ "swap", luaA_client_swap }, { "swap", luaA_client_swap },

View File

@ -139,9 +139,9 @@ struct client_t
/** Titlebar */ /** Titlebar */
wibox_t *titlebar; wibox_t *titlebar;
/** Button bindings */ /** Button bindings */
button_array_t buttons; void *buttons;
/** Key bindings */ /** Key bindings */
key_array_t keys; void *keys;
/** Icon */ /** Icon */
image_t *icon; image_t *icon;
/** Size hints */ /** Size hints */

View File

@ -14,6 +14,7 @@ border_padding
border_width border_width
bottom bottom
button button
buttons
button_press button_press
button_release button_release
center center
@ -49,6 +50,7 @@ image
imagebox imagebox
instance instance
key key
keys
key_press key_press
key_release key_release
keysym keysym

61
event.c
View File

@ -42,25 +42,34 @@
#include "common/atoms.h" #include "common/atoms.h"
#include "common/xutil.h" #include "common/xutil.h"
#define DO_EVENT_HOOK_CALLBACK(type, prefix, xcbtype, xcbeventprefix, arraytype, match) \ #define DO_EVENT_HOOK_CALLBACK(type, prefix, xcbtype, xcbeventprefix, match) \
static int \ static int \
event_##xcbtype##_callback(xcb_##xcbtype##_press_event_t *ev, \ event_##xcbtype##_callback(xcb_##xcbtype##_press_event_t *ev, \
arraytype *arr, \ void *arr, \
int oud, \ int oud, \
int nargs, \ int nargs, \
void *data) \ void *data) \
{ \ { \
int abs_oud = oud < 0 ? ((lua_gettop(globalconf.L) + 1) + oud) : oud; \ int abs_oud = oud < 0 ? ((lua_gettop(globalconf.L) + 1) + oud) : oud; \
int item_matching = 0, item_matched = 0; \ int item_matching = 0, item_matched = 0; \
foreach(item, *arr) \ if(oud) \
if(match(ev, *item, data)) \ luaA_object_push_item(globalconf.L, abs_oud, arr); \
else \
luaA_object_push(globalconf.L, arr); \
lua_pushnil(globalconf.L); \
while(luaA_next(globalconf.L, -2)) \
{ \
type *item = luaA_toudata(globalconf.L, -1, #prefix); \
if(item && match(ev, item, data)) \
{ \ { \
if(oud) \ lua_insert(globalconf.L, -3); \
luaA_object_push_item(globalconf.L, abs_oud, *item); \
else \
prefix##_push(globalconf.L, *item); \
item_matching++; \ item_matching++; \
} \ } \
else \
lua_pop(globalconf.L, 1); \
} \
/* remove the table */ \
lua_pop(globalconf.L, 1); \
for(item_matched = item_matching; item_matching > 0; item_matching--) \ for(item_matched = item_matching; item_matching > 0; item_matching--) \
{ \ { \
type *item = luaL_checkudata(globalconf.L, -1, #prefix); \ type *item = luaL_checkudata(globalconf.L, -1, #prefix); \
@ -71,14 +80,7 @@
{ \ { \
for(int i = 0; i < nargs; i++) \ for(int i = 0; i < nargs; i++) \
lua_pushvalue(globalconf.L, - nargs - item_matching); \ lua_pushvalue(globalconf.L, - nargs - item_matching); \
if(oud) \ luaA_object_push_item(globalconf.L, - nargs - 1, item->press); \
{ \
luaA_object_push_item(globalconf.L, abs_oud, item); \
luaA_object_push_item(globalconf.L, -1, item->press); \
lua_remove(globalconf.L, -2); \
} \
else \
prefix##_push_item(globalconf.L, item, item->press); \
luaA_dofunction(globalconf.L, nargs, 0); \ luaA_dofunction(globalconf.L, nargs, 0); \
} \ } \
break; \ break; \
@ -87,14 +89,7 @@
{ \ { \
for(int i = 0; i < nargs; i++) \ for(int i = 0; i < nargs; i++) \
lua_pushvalue(globalconf.L, - nargs - item_matching); \ lua_pushvalue(globalconf.L, - nargs - item_matching); \
if(oud) \ luaA_object_push_item(globalconf.L, - nargs - 1, item->release); \
{ \
luaA_object_push_item(globalconf.L, abs_oud, item); \
luaA_object_push_item(globalconf.L, -1, item->release); \
lua_remove(globalconf.L, -2); \
} \
else \
prefix##_push_item(globalconf.L, item, item->release); \
luaA_dofunction(globalconf.L, nargs, 0); \ luaA_dofunction(globalconf.L, nargs, 0); \
} \ } \
break; \ break; \
@ -122,8 +117,8 @@ event_key_match(xcb_key_press_event_t *ev, keyb_t *k, void *data)
&& (k->mod == XCB_BUTTON_MASK_ANY || k->mod == ev->state)); && (k->mod == XCB_BUTTON_MASK_ANY || k->mod == ev->state));
} }
DO_EVENT_HOOK_CALLBACK(button_t, button, button, XCB_BUTTON, button_array_t, event_button_match) DO_EVENT_HOOK_CALLBACK(button_t, button, button, XCB_BUTTON, event_button_match)
DO_EVENT_HOOK_CALLBACK(keyb_t, key, key, XCB_KEY, key_array_t, event_key_match) DO_EVENT_HOOK_CALLBACK(keyb_t, key, key, XCB_KEY, event_key_match)
/** Handle an event with mouse grabber if needed /** Handle an event with mouse grabber if needed
* \param x The x coordinate. * \param x The x coordinate.
@ -185,7 +180,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
} }
wibox_push(globalconf.L, wibox); wibox_push(globalconf.L, wibox);
event_button_callback(ev, &wibox->buttons, -1, 1, NULL); event_button_callback(ev, wibox->buttons, -1, 1, NULL);
/* then try to match a widget binding */ /* then try to match a widget binding */
widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets, widget_t *w = widget_getbycoords(wibox->sw.orientation, &wibox->widgets,
@ -196,13 +191,13 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
{ {
widget_push(globalconf.L, w); widget_push(globalconf.L, w);
wibox_push(globalconf.L, wibox); wibox_push(globalconf.L, wibox);
event_button_callback(ev, &w->buttons, -2, 2, NULL); event_button_callback(ev, w->buttons, -2, 2, NULL);
} }
} }
else if((c = client_getbywin(ev->event))) else if((c = client_getbywin(ev->event)))
{ {
client_push(globalconf.L, c); client_push(globalconf.L, c);
event_button_callback(ev, &c->buttons, -1, 1, NULL); event_button_callback(ev, c->buttons, -1, 1, NULL);
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_REPLAY_POINTER, XCB_ALLOW_REPLAY_POINTER,
XCB_CURRENT_TIME); XCB_CURRENT_TIME);
@ -211,7 +206,7 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
for(screen = 0; screen < nb_screen; screen++) for(screen = 0; screen < nb_screen; screen++)
if(xutil_screen_get(connection, screen)->root == ev->event) if(xutil_screen_get(connection, screen)->root == ev->event)
{ {
event_button_callback(ev, &globalconf.buttons, 0, 0, NULL); event_button_callback(ev, globalconf.buttons, 0, 0, NULL);
return 0; return 0;
} }
@ -603,15 +598,15 @@ event_handle_key(void *data __attribute__ ((unused)),
if((c = client_getbywin(ev->event))) if((c = client_getbywin(ev->event)))
{ {
client_push(globalconf.L, c); client_push(globalconf.L, c);
if(!event_key_callback(ev, &c->keys, -1, 1, &keysym)) if(!event_key_callback(ev, c->keys, -1, 1, &keysym))
if(!event_key_callback(ev, &globalconf.keys, 0, 0, &keysym)) if(!event_key_callback(ev, globalconf.keys, 0, 0, &keysym))
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_REPLAY_KEYBOARD, XCB_ALLOW_REPLAY_KEYBOARD,
XCB_CURRENT_TIME); XCB_CURRENT_TIME);
} }
else else
event_key_callback(ev, &globalconf.keys, 0, 0, &keysym); event_key_callback(ev, globalconf.keys, 0, 0, &keysym);
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_SYNC_KEYBOARD, XCB_ALLOW_SYNC_KEYBOARD,

43
key.c
View File

@ -999,49 +999,6 @@ luaA_key_new(lua_State *L)
return 1; return 1;
} }
/** Set a key array with a Lua table.
* \param L The Lua VM state.
* \param oidx The index of the object to store items into.
* \param idx The index of the Lua table.
* \param keys The array key to fill.
*/
void
luaA_key_array_set(lua_State *L, int oidx, int idx, key_array_t *keys)
{
luaA_checktable(L, idx);
foreach(key, *keys)
luaA_object_unref_item(L, oidx, *key);
key_array_wipe(keys);
key_array_init(keys);
lua_pushnil(L);
while(lua_next(L, idx))
if(luaA_toudata(L, -1, "key"))
key_array_append(keys, luaA_object_ref_item(L, oidx, -1));
else
lua_pop(L, 1);
}
/** Push an array of key as an Lua table onto the stack.
* \param L The Lua VM state.
* \param oidx The index of the object to get items from.
* \param keys The key array to push.
* \return The number of elements pushed on stack.
*/
int
luaA_key_array_get(lua_State *L, int oidx, key_array_t *keys)
{
lua_createtable(L, keys->len, 0);
for(int i = 0; i < keys->len; i++)
{
luaA_object_push_item(L, oidx, keys->tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
/** Push a modifier set to a Lua table. /** Push a modifier set to a Lua table.
* \param L The Lua VM state. * \param L The Lua VM state.
* \param modifiers The modifier. * \param modifiers The modifier.

4
key.h
View File

@ -39,15 +39,11 @@ typedef struct keyb_t
void *release; void *release;
} keyb_t; } keyb_t;
DO_ARRAY(keyb_t *, key, DO_NOTHING)
LUA_OBJECT_FUNCS(keyb_t, key, "key") LUA_OBJECT_FUNCS(keyb_t, key, "key")
bool key_press_lookup_string(xcb_keysym_t, char *, ssize_t); bool key_press_lookup_string(xcb_keysym_t, char *, ssize_t);
xcb_keysym_t key_getkeysym(xcb_keycode_t, uint16_t); xcb_keysym_t key_getkeysym(xcb_keycode_t, uint16_t);
void luaA_key_array_set(lua_State *, int, int, key_array_t *);
int luaA_key_array_get(lua_State *, int, key_array_t *);
int luaA_pushmodifiers(lua_State *, uint16_t); int luaA_pushmodifiers(lua_State *, uint16_t);
uint16_t luaA_tomodifiers(lua_State *L, int ud); uint16_t luaA_tomodifiers(lua_State *L, int ud);

View File

@ -200,7 +200,7 @@ local function add_item(data, num, item_info)
label.bg_image = icon label.bg_image = icon
end end
item:buttons(bindings) item.buttons = bindings
function label.mouse_enter() item_enter(data, num, true) end function label.mouse_enter() item_enter(data, num, true) end
function item.mouse_enter() item_enter(data, num, true) end function item.mouse_enter() item_enter(data, num, true) end
@ -210,7 +210,7 @@ local function add_item(data, num, item_info)
if type(item_info[2]) == "table" then if type(item_info[2]) == "table" then
submenu = widget({ type = "imagebox" }) submenu = widget({ type = "imagebox" })
submenu.image = data.theme.submenu_icon and image(data.theme.submenu_icon) submenu.image = data.theme.submenu_icon and image(data.theme.submenu_icon)
submenu:buttons(bindings) submenu.buttons = bindings
function submenu.mouse_enter() item_enter(data, num, true) end function submenu.mouse_enter() item_enter(data, num, true) end
end end

View File

@ -80,11 +80,10 @@ function add(c, args)
end end
-- Redirect relevant events to the client the titlebar belongs to -- Redirect relevant events to the client the titlebar belongs to
local bts = util.table.join( title.buttons = util.table.join(
button({ }, 1, button_callback_focus_raise_move), button({ }, 1, button_callback_focus_raise_move),
button({ args.modkey }, 1, button_callback_move), button({ args.modkey }, 1, button_callback_move),
button({ args.modkey }, 3, button_callback_resize)) button({ args.modkey }, 3, button_callback_resize))
title:buttons(bts)
local appicon = capi.widget({ type = "imagebox" }) local appicon = capi.widget({ type = "imagebox" })
appicon.image = c.icon appicon.image = c.icon
@ -173,8 +172,6 @@ end
-- @param theme The theme from beautifull. Used to get the image paths -- @param theme The theme from beautifull. Used to get the image paths
-- @param state The state the button is associated to. Containse path the action and info about the image -- @param state The state the button is associated to. Containse path the action and info about the image
local function button_new(c, name, modkey, theme, state) local function button_new(c, name, modkey, theme, state)
local bts = button({ }, 1, nil, state.action)
-- get the image path from the theme. Only return a button if we find an image -- get the image path from the theme. Only return a button if we find an image
local img local img
img = "titlebar_" .. name .. "_button_" .. state.img img = "titlebar_" .. name .. "_button_" .. state.img
@ -187,13 +184,9 @@ local function button_new(c, name, modkey, theme, state)
local bname = name .. "_" .. state.idx local bname = name .. "_" .. state.idx
local button = widget.button({ image = img }) local button = widget.button({ image = img })
if not button then return end if not button then return end
local rbts = button:buttons()
for k, v in pairs(rbts) do button.buttons = util.table.join(button.buttons, button({ }, 1, nil, state.action))
bts[#bts + 1] = v
end
button:buttons(bts)
button.visible = false button.visible = false
return button return button
end end

View File

@ -32,7 +32,7 @@ function new(args)
args.type = "imagebox" args.type = "imagebox"
local w = capi.widget(args) local w = capi.widget(args)
w.image = img_release w.image = img_release
w:buttons(button({}, 1, function () w.image = img_press end, function () w.image = img_release end)) w.buttons = button({}, 1, function () w.image = img_press end, function () w.image = img_release end)
function w.mouse_leave(s) w.image = img_release end function w.mouse_leave(s) w.image = img_release end
function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.image = img_press end end function w.mouse_enter(s) if capi.mouse.coords().buttons[1] then w.image = img_press end end
return w return w

View File

@ -65,8 +65,8 @@ function list_update(w, buttons, label, data, widgets, objects)
data[o][kb] = capi.button(b.modifiers, b.button, press, release) data[o][kb] = capi.button(b.modifiers, b.button, press, release)
end end
end end
w[k]:buttons(data[o]) w[k].buttons = data[o]
w[k + 1]:buttons(data[o]) w[k + 1].buttons = data[o]
end end
local text, bg, bg_image, icon = label(o) local text, bg, bg_image, icon = label(o)

View File

@ -21,12 +21,11 @@ function new(args)
if not w then return end if not w then return end
if args.command then if args.command then
b = util.table.join(w:buttons(), button({}, 1, nil, function () util.spawn(args.command) end)) w.buttons = util.table.join(w.buttons, button({}, 1, nil, function () util.spawn(args.command) end))
elseif args.menu then elseif args.menu then
b = util.table.join(w:buttons(), button({}, 1, nil, function () args.menu:toggle() end)) w.buttons = util.table.join(w.buttons, button({}, 1, nil, function () args.menu:toggle() end))
end end
w:buttons(b)
return w return w
end end

View File

@ -312,7 +312,7 @@ function notify(args)
-- create textbox -- create textbox
local textbox = capi.widget({ type = "textbox", align = "flex" }) local textbox = capi.widget({ type = "textbox", align = "flex" })
textbox:buttons(util.table.join(button({ }, 1, run), button({ }, 3, die))) textbox.buttons = util.table.join(button({ }, 1, run), button({ }, 3, die))
textbox:margin({ right = margin, left = margin, bottom = 2 * margin }) textbox:margin({ right = margin, left = margin, bottom = 2 * margin })
textbox.text = string.format('<span font_desc="%s"><b>%s</b>%s</span>', font, title, text) textbox.text = string.format('<span font_desc="%s"><b>%s</b>%s</span>', font, title, text)
if hover_timeout then textbox.mouse_enter = hover_destroy end if hover_timeout then textbox.mouse_enter = hover_destroy end
@ -328,7 +328,7 @@ function notify(args)
-- if we have an icon, use it -- if we have an icon, use it
if icon then if icon then
iconbox = capi.widget({ type = "imagebox", align = "left" }) iconbox = capi.widget({ type = "imagebox", align = "left" })
iconbox:buttons(util.table.join(button({ }, 1, run), button({ }, 3, die))) iconbox.buttons = util.table.join(button({ }, 1, run), button({ }, 3, die))
local img local img
if type(icon) == "string" then if type(icon) == "string" then
img = capi.image(icon) img = capi.image(icon)

8
luaa.c
View File

@ -49,7 +49,8 @@ extern const struct luaL_reg awesome_dbus_lib[];
extern const struct luaL_reg awesome_hooks_lib[]; extern const struct luaL_reg awesome_hooks_lib[];
extern const struct luaL_reg awesome_keygrabber_lib[]; extern const struct luaL_reg awesome_keygrabber_lib[];
extern const struct luaL_reg awesome_mousegrabber_lib[]; extern const struct luaL_reg awesome_mousegrabber_lib[];
extern const struct luaL_reg awesome_root_lib[]; extern const struct luaL_reg awesome_root_methods[];
extern const struct luaL_reg awesome_root_meta[];
extern const struct luaL_reg awesome_button_methods[]; extern const struct luaL_reg awesome_button_methods[];
extern const struct luaL_reg awesome_button_meta[]; extern const struct luaL_reg awesome_button_meta[];
extern const struct luaL_reg awesome_image_methods[]; extern const struct luaL_reg awesome_image_methods[];
@ -682,9 +683,8 @@ luaA_init(xdgHandle* xdg)
/* Export awesome lib */ /* Export awesome lib */
luaA_openlib(L, "awesome", awesome_lib, awesome_lib); luaA_openlib(L, "awesome", awesome_lib, awesome_lib);
/* Export root lib */ /* Export root */
luaL_register(L, "root", awesome_root_lib); luaA_openlib(L, "root", awesome_root_methods, awesome_root_meta);
lua_pop(L, 1); /* luaL_register() leaves the table on stack */
/* Export hooks lib */ /* Export hooks lib */
luaL_register(L, "hooks", awesome_hooks_lib); luaL_register(L, "hooks", awesome_hooks_lib);

128
root.c
View File

@ -22,7 +22,6 @@
#include <xcb/xtest.h> #include <xcb/xtest.h>
#include "structs.h" #include "structs.h"
#include "button.h"
#include "wibox.h" #include "wibox.h"
#include "common/xcursor.h" #include "common/xcursor.h"
#include "common/tokenize.h" #include "common/tokenize.h"
@ -101,82 +100,6 @@ luaA_root_fake_input(lua_State *L)
return 0; return 0;
} }
/** Get or set global key bindings.
* This binding will be available when you'll press keys on root window.
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lparam An array of key bindings objects, or nothing.
* \lreturn The array of key bindings objects of this client.
*/
static int
luaA_root_keys(lua_State *L)
{
if(lua_gettop(L) == 1)
{
luaA_checktable(L, 1);
foreach(key, globalconf.keys)
key_unref(globalconf.L, *key);
key_array_wipe(&globalconf.keys);
key_array_init(&globalconf.keys);
lua_pushnil(L);
while(lua_next(L, 1))
key_array_append(&globalconf.keys, key_ref(L, -1));
return 1;
}
lua_createtable(L, globalconf.keys.len, 0);
for(int i = 0; i < globalconf.keys.len; i++)
{
key_push(L, globalconf.keys.tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
/** Get or set global mouse bindings.
* This binding will be available when you'll click on root window.
* \param L The Lua VM state.
* \return The number of element pushed on stack.
* \luastack
* \lparam An array of mouse button bindings objects, or nothing.
* \lreturn The array of mouse button bindings objects.
*/
static int
luaA_root_buttons(lua_State *L)
{
if(lua_gettop(L) == 1)
{
luaA_checktable(L, 1);
foreach(button, globalconf.buttons)
button_unref(globalconf.L, *button);
button_array_wipe(&globalconf.buttons);
button_array_init(&globalconf.buttons);
lua_pushnil(L);
while(lua_next(L, 1))
button_array_append(&globalconf.buttons, button_ref(L, -1));
return 1;
}
lua_createtable(L, globalconf.buttons.len, 0);
for(int i = 0; i < globalconf.buttons.len; i++)
{
button_push(L, globalconf.buttons.tab[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
/** Set the root cursor. /** Set the root cursor.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of element pushed on stack. * \return The number of element pushed on stack.
@ -227,13 +150,58 @@ luaA_root_wiboxes(lua_State *L)
return 1; return 1;
} }
const struct luaL_reg awesome_root_lib[] = static int
luaA_root_index(lua_State *L)
{
size_t len;
const char *attr = luaL_checklstring(L, 2, &len);
switch(a_tokenize(attr, len))
{
case A_TK_KEYS:
return luaA_object_push(L, globalconf.keys);
case A_TK_BUTTONS:
return luaA_object_push(L, globalconf.buttons);
default:
return 0;
}
}
static int
luaA_root_newindex(lua_State *L)
{
size_t len;
const char *attr = luaL_checklstring(L, 2, &len);
switch(a_tokenize(attr, len))
{
case A_TK_KEYS:
luaA_object_unref(L, globalconf.keys);
globalconf.keys = luaA_object_ref(L, 3);
break;
case A_TK_BUTTONS:
luaA_object_unref(L, globalconf.buttons);
globalconf.buttons = luaA_object_ref(L, 3);
break;
default:
break;
}
return 0;
}
const struct luaL_reg awesome_root_methods[] =
{ {
{ "buttons", luaA_root_buttons },
{ "keys", luaA_root_keys },
{ "cursor", luaA_root_cursor }, { "cursor", luaA_root_cursor },
{ "fake_input", luaA_root_fake_input }, { "fake_input", luaA_root_fake_input },
{ "wiboxes", luaA_root_wiboxes }, { "wiboxes", luaA_root_wiboxes },
{ "__index", luaA_root_index },
{ "__newindex", luaA_root_newindex },
{ NULL, NULL }
};
const struct luaL_reg awesome_root_meta[] =
{
{ NULL, NULL } { NULL, NULL }
}; };

View File

@ -68,9 +68,9 @@ struct awesome_t
/** True if xinerama is active */ /** True if xinerama is active */
bool xinerama_is_active; bool xinerama_is_active;
/** Root window key bindings */ /** Root window key bindings */
key_array_t keys; void *keys;
/** Root window mouse bindings */ /** Root window mouse bindings */
button_array_t buttons; void *buttons;
/** Modifiers masks */ /** Modifiers masks */
uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask; uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask;
/** Check for XTest extension */ /** Check for XTest extension */

28
wibox.c
View File

@ -40,7 +40,6 @@ luaA_wibox_gc(lua_State *L)
wibox_t *wibox = luaL_checkudata(L, 1, "wibox"); wibox_t *wibox = luaL_checkudata(L, 1, "wibox");
p_delete(&wibox->cursor); p_delete(&wibox->cursor);
simplewindow_wipe(&wibox->sw); simplewindow_wipe(&wibox->sw);
button_array_wipe(&wibox->buttons);
widget_node_array_wipe(&wibox->widgets); widget_node_array_wipe(&wibox->widgets);
return luaA_object_gc(L); return luaA_object_gc(L);
} }
@ -648,6 +647,8 @@ luaA_wibox_index(lua_State *L)
return luaA_object_push_item(L, 1, wibox->sw.shape.bounding); return luaA_object_push_item(L, 1, wibox->sw.shape.bounding);
case A_TK_SHAPE_CLIP: case A_TK_SHAPE_CLIP:
return luaA_object_push_item(L, 1, wibox->sw.shape.clip); return luaA_object_push_item(L, 1, wibox->sw.shape.clip);
case A_TK_BUTTONS:
return luaA_object_push_item(L, 1, wibox->buttons);
default: default:
return 0; return 0;
} }
@ -867,6 +868,9 @@ luaA_wibox_newindex(lua_State *L)
luaA_object_unref_item(L, 1, wibox->sw.shape.clip); luaA_object_unref_item(L, 1, wibox->sw.shape.clip);
wibox->sw.shape.clip = luaA_object_ref_item(L, 1, 3); wibox->sw.shape.clip = luaA_object_ref_item(L, 1, 3);
wibox->need_shape_update = true; wibox->need_shape_update = true;
case A_TK_BUTTONS:
luaA_object_unref_item(L, 1, wibox->buttons);
wibox->buttons = luaA_object_ref_item(L, 1, 3);
break; break;
default: default:
switch(wibox->type) switch(wibox->type)
@ -881,27 +885,6 @@ luaA_wibox_newindex(lua_State *L)
return 0; return 0;
} }
/** Get or set mouse buttons bindings to a wibox.
* \param L The Lua VM state.
* \luastack
* \lvalue A wibox.
* \lparam An array of mouse button bindings objects, or nothing.
* \return The array of mouse button bindings objects of this wibox.
*/
static int
luaA_wibox_buttons(lua_State *L)
{
wibox_t *wibox = luaL_checkudata(L, 1, "wibox");
if(lua_gettop(L) == 2)
{
luaA_button_array_set(L, 1, 2, &wibox->buttons);
return 1;
}
return luaA_button_array_get(L, 1, &wibox->buttons);
}
const struct luaL_reg awesome_wibox_methods[] = const struct luaL_reg awesome_wibox_methods[] =
{ {
{ "__call", luaA_wibox_new }, { "__call", luaA_wibox_new },
@ -909,7 +892,6 @@ const struct luaL_reg awesome_wibox_methods[] =
}; };
const struct luaL_reg awesome_wibox_meta[] = const struct luaL_reg awesome_wibox_meta[] =
{ {
{ "buttons", luaA_wibox_buttons },
{ "geometry", luaA_wibox_geometry }, { "geometry", luaA_wibox_geometry },
{ "__index", luaA_wibox_index }, { "__index", luaA_wibox_index },
{ "__newindex", luaA_wibox_newindex }, { "__newindex", luaA_wibox_newindex },

View File

@ -68,7 +68,7 @@ struct wibox_t
/* Banned? used for titlebars */ /* Banned? used for titlebars */
bool isbanned; bool isbanned;
/** Button bindings */ /** Button bindings */
button_array_t buttons; void *buttons;
}; };
void wibox_unref_simplified(wibox_t **); void wibox_unref_simplified(wibox_t **);

View File

@ -44,7 +44,6 @@ luaA_widget_gc(lua_State *L)
widget_t *widget = luaL_checkudata(L, 1, "widget"); widget_t *widget = luaL_checkudata(L, 1, "widget");
if(widget->destructor) if(widget->destructor)
widget->destructor(widget); widget->destructor(widget);
button_array_wipe(&widget->buttons);
return luaA_object_gc(L); return luaA_object_gc(L);
} }
@ -451,28 +450,6 @@ luaA_widget_new(lua_State *L)
return 1; return 1;
} }
/** Get or set mouse buttons bindings to a widget.
* \param L The Lua VM state.
*
* \luastack
* \lvalue A widget.
* \lparam An array of mouse button bindings objects, or nothing.
* \return The array of mouse button bindings objects of this widget.
*/
static int
luaA_widget_buttons(lua_State *L)
{
widget_t *widget = luaL_checkudata(L, 1, "widget");
if(lua_gettop(L) == 2)
{
luaA_button_array_set(L, 1, 2, &widget->buttons);
return 1;
}
return luaA_button_array_get(L, 1, &widget->buttons);
}
/** Generic widget. /** Generic widget.
* \param L The Lua VM state. * \param L The Lua VM state.
* \return The number of elements pushed on stack. * \return The number of elements pushed on stack.
@ -501,6 +478,8 @@ luaA_widget_index(lua_State *L)
return luaA_object_push_item(L, 1, widget->mouse_enter); return luaA_object_push_item(L, 1, widget->mouse_enter);
case A_TK_MOUSE_LEAVE: case A_TK_MOUSE_LEAVE:
return luaA_object_push_item(L, 1, widget->mouse_leave); return luaA_object_push_item(L, 1, widget->mouse_leave);
case A_TK_BUTTONS:
return luaA_object_push_item(L, 1, widget->buttons);
default: default:
break; break;
} }
@ -535,6 +514,10 @@ luaA_widget_newindex(lua_State *L)
luaA_object_unref_item(L, 1, widget->mouse_leave); luaA_object_unref_item(L, 1, widget->mouse_leave);
widget->mouse_leave = luaA_object_ref_item(L, 1, 3); widget->mouse_leave = luaA_object_ref_item(L, 1, 3);
return 0; return 0;
case A_TK_BUTTONS:
luaA_object_unref_item(L, 1, widget->buttons);
widget->buttons = luaA_object_ref_item(L, 1, 3);
break;
default: default:
return widget->newindex ? widget->newindex(L, token) : 0; return widget->newindex ? widget->newindex(L, token) : 0;
} }
@ -574,7 +557,6 @@ const struct luaL_reg awesome_widget_methods[] =
}; };
const struct luaL_reg awesome_widget_meta[] = const struct luaL_reg awesome_widget_meta[] =
{ {
{ "buttons", luaA_widget_buttons },
{ "extents", luaA_widget_extents }, { "extents", luaA_widget_extents },
{ "__index", luaA_widget_index }, { "__index", luaA_widget_index },
{ "__newindex", luaA_widget_newindex }, { "__newindex", luaA_widget_newindex },

View File

@ -51,7 +51,7 @@ struct widget_t
/** Misc private data */ /** Misc private data */
void *data; void *data;
/** Button bindings */ /** Button bindings */
button_array_t buttons; void *buttons;
/** True if the widget is visible */ /** True if the widget is visible */
bool isvisible; bool isvisible;
}; };