From f37421038293c47430741e48f0c4834c65041827 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 22 Sep 2008 17:54:48 +0200 Subject: [PATCH] client: add property hook Signed-off-by: Julien Danjou --- awesomerc.lua.in | 2 +- client.c | 19 ++++++++++++++++++ event.c | 2 +- ewmh.c | 3 ++- lib/awful.lua.in | 38 +++++++++++++++++++++++------------ luaa.c | 52 +++++++++++++++++++++++++----------------------- luaa.h | 7 +++++++ property.c | 9 +++++---- structs.h | 10 ++++------ 9 files changed, 91 insertions(+), 51 deletions(-) diff --git a/awesomerc.lua.in b/awesomerc.lua.in index 4868331b..1b5377c3 100644 --- a/awesomerc.lua.in +++ b/awesomerc.lua.in @@ -357,7 +357,7 @@ awful.hooks.unmarked.register(function (c) end) -- Hook function to execute when the mouse is over a client. -awful.hooks.mouse_over.register(function (c) +awful.hooks.mouse_enter.register(function (c) -- Sloppy focus, but disabled for magnifier layout if awful.layout.get(c.screen) ~= "magnifier" and awful.client.focus.filter(c) then diff --git a/client.c b/client.c index 6d0cca0e..35382249 100644 --- a/client.c +++ b/client.c @@ -577,6 +577,9 @@ client_resize(client_t *c, area_t geometry, bool hints) values); window_configure(c->win, geometry, c->border); + /* execute hook */ + hooks_property(c, "geometry"); + if(c->screen != new_screen) screen_client_moveto(c, new_screen, true, false); } @@ -613,6 +616,8 @@ client_setfloating(client_t *c, bool floating) XCB_PROP_MODE_REPLACE, c->win, _AWESOME_FLOATING, CARDINAL, 8, 1, &c->isfloating); + /* execute hook */ + hooks_property(c, "floating"); } } @@ -629,6 +634,8 @@ client_setminimized(client_t *c, bool s) c->isminimized = s; client_need_arrange(c); ewmh_client_update_hints(c); + /* execute hook */ + hooks_property(c, "minimized"); } } @@ -645,6 +652,7 @@ client_setsticky(client_t *c, bool s) c->issticky = s; client_need_arrange(c); ewmh_client_update_hints(c); + hooks_property(c, "sticky"); } } @@ -681,6 +689,7 @@ client_setfullscreen(client_t *c, bool s) c->win, _AWESOME_FULLSCREEN, CARDINAL, 8, 1, &c->isfullscreen); ewmh_client_update_hints(c); + hooks_property(c, "fullscreen"); } } @@ -696,6 +705,8 @@ client_setabove(client_t *c, bool s) c->isabove = s; client_stack(); ewmh_client_update_hints(c); + /* execute hook */ + hooks_property(c, "above"); } } @@ -711,6 +722,8 @@ client_setbelow(client_t *c, bool s) c->isbelow = s; client_stack(); ewmh_client_update_hints(c); + /* execute hook */ + hooks_property(c, "below"); } } @@ -726,6 +739,8 @@ client_setmodal(client_t *c, bool s) c->ismodal = s; client_stack(); ewmh_client_update_hints(c); + /* execute hook */ + hooks_property(c, "modal"); } } @@ -740,6 +755,8 @@ client_setontop(client_t *c, bool s) { c->isontop = s; client_stack(); + /* execute hook */ + hooks_property(c, "ontop"); } } @@ -978,6 +995,8 @@ client_setborder(client_t *c, int width) else globalconf.screens[c->screen].need_arrange = true; } + + hooks_property(c, "border_width"); } /** Kill a client. diff --git a/event.c b/event.c index e2975f6a..73789da7 100644 --- a/event.c +++ b/event.c @@ -469,7 +469,7 @@ event_handle_enternotify(void *data __attribute__ ((unused)), globalconf.pointer_y = ev->root_y; luaA_client_userdata_new(globalconf.L, c); - luaA_dofunction(globalconf.L, globalconf.hooks.mouse_over, 1, 0); + luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0); } else if((emwin = xembed_getbywin(globalconf.embedded, ev->event))) xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY, diff --git a/ewmh.c b/ewmh.c index 2f62c30b..ddb46a3c 100644 --- a/ewmh.c +++ b/ewmh.c @@ -332,7 +332,8 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) /* execute hook */ luaA_client_userdata_new(globalconf.L, c); - luaA_dofunction(globalconf.L, globalconf.hooks.urgent, 1, 0); + lua_pushliteral(globalconf.L, "urgent"); + luaA_dofunction(globalconf.L, globalconf.hooks.property, 2, 0); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } } diff --git a/lib/awful.lua.in b/lib/awful.lua.in index 2ab0806e..0136c268 100644 --- a/lib/awful.lua.in +++ b/lib/awful.lua.in @@ -134,13 +134,16 @@ function client.urgent.jumpto() end --- Adds client to urgent stack. --- @param The client object. -function client.urgent.stack.add(c) - table.insert(client.urgent.stack.data, c) +-- @param c The client object. +-- @param prop The property which is updated. +function client.urgent.stack.add(c, prop) + if prop == "urgent" then + table.insert(client.urgent.stack.data, c) + end end --- Remove client from urgent stack. --- @param The client object. +-- @param c The client object. function client.urgent.stack.delete(c) for k, cl in ipairs(client.urgent.stack.data) do if c == cl then @@ -1529,6 +1532,7 @@ function titlebar.add(c, args) local tb = capi.wibox(targs) local title = capi.widget({ type = "textbox", name = "title", align = "flex" }) + title.text = " " .. escape(c.name) .. " " local bts = { capi.button({ }, 1, function (t) t.client:mouse_move() end), @@ -1578,18 +1582,26 @@ end --- Update a titlebar. This should be called in some hooks. -- @param c The client to update. -function titlebar.update(c) +-- @param prop The property name which has changed. +function titlebar.update(c, prop) if c.titlebar and titlebar.data[c] then local widgets = c.titlebar:widgets() local title, close, closef for k, v in ipairs(widgets) do - if v.name == "title" then title = v end - if v.name == "close" then close = v end - if v.name == "closef" then closef = v end - if title and close and closef then break end + if v.name == "title" then title = v + elseif v.name == "close" then close = v + elseif v.name == "closef" then closef = v + elseif v.name == "appicon" then appicon = v end + if title and close and closef and appicon then break end end - if title then - title.text = " " .. escape(c.name) .. " " + if prop == "name" then + if title then + title.text = " " .. escape(c.name) .. " " + end + elseif prop == "icon" then + if appicon then + appicon.image = c.icon + end end if capi.client.focus == c then c.titlebar.fg = titlebar.data[c].fg_focus @@ -1813,10 +1825,10 @@ hooks.unmanage.register(client_maximize_clean) hooks.focus.register(titlebar.update) hooks.unfocus.register(titlebar.update) -hooks.titleupdate.register(titlebar.update) +hooks.property.register(titlebar.update) hooks.unmanage.register(titlebar.remove) -hooks.urgent.register(client.urgent.stack.add) +hooks.property.register(client.urgent.stack.add) hooks.focus.register(client.urgent.stack.delete) hooks.unmanage.register(client.urgent.stack.delete) diff --git a/luaa.c b/luaa.c index 6e3c0c02..38037940 100644 --- a/luaa.c +++ b/luaa.c @@ -199,9 +199,23 @@ luaA_hooks_unmanage(lua_State *L) * \lparam A function to call each time a client gets mouse over it. */ static int +luaA_hooks_mouse_enter(lua_State *L) +{ + return luaA_registerfct(L, 1, &globalconf.hooks.mouse_enter); +} + +/** Set the function called each time the mouse enter a new window. This + * function is called with the client object as argument. (DEPRECATED) + * \param L The Lua VM state. + * + * \luastack + * \lparam A function to call each time a client gets mouse over it. + */ +static int luaA_hooks_mouse_over(lua_State *L) { - return luaA_registerfct(L, 1, &globalconf.hooks.mouse_over); + deprecate(); + return luaA_hooks_mouse_enter(L); } /** Set the function called on each screen arrange. This function is called @@ -217,30 +231,18 @@ luaA_hooks_arrange(lua_State *L) return luaA_registerfct(L, 1, &globalconf.hooks.arrange); } -/** Set the function called on each title update. This function is called with - * the client object as argument. +/** Set the function called on each client's property change. + * This function is called with the client object as argument and the + * property name. * \param L The Lua VM state. * * \luastack - * \lparam A function to call on each title update of each client. + * \lparam A function to call on each client property update. */ static int -luaA_hooks_titleupdate(lua_State *L) +luaA_hooks_property(lua_State *L) { - return luaA_registerfct(L, 1, &globalconf.hooks.titleupdate); -} - -/** Set the function called when a client get urgency flag. This function is called with - * the client object as argument. - * \param L The Lua VM state. - * - * \luastack - * \lparam A function to call when a client get the urgent flag. - */ -static int -luaA_hooks_urgent(lua_State *L) -{ - return luaA_registerfct(L, 1, &globalconf.hooks.urgent); + return luaA_registerfct(L, 1, &globalconf.hooks.property); } /** Set the function to be called every N seconds. @@ -600,11 +602,12 @@ luaA_init(void) { "unfocus", luaA_hooks_unfocus }, { "manage", luaA_hooks_manage }, { "unmanage", luaA_hooks_unmanage }, - { "mouse_over", luaA_hooks_mouse_over }, + { "mouse_enter", luaA_hooks_mouse_enter }, + { "property", luaA_hooks_property }, { "arrange", luaA_hooks_arrange }, - { "titleupdate", luaA_hooks_titleupdate }, - { "urgent", luaA_hooks_urgent }, { "timer", luaA_hooks_timer }, + /* deprecated */ + { "mouse_over", luaA_hooks_mouse_over }, { NULL, NULL } }; @@ -675,10 +678,9 @@ luaA_init(void) globalconf.hooks.unmanage = LUA_REFNIL; globalconf.hooks.focus = LUA_REFNIL; globalconf.hooks.unfocus = LUA_REFNIL; - globalconf.hooks.mouse_over = LUA_REFNIL; + globalconf.hooks.mouse_enter = LUA_REFNIL; globalconf.hooks.arrange = LUA_REFNIL; - globalconf.hooks.titleupdate = LUA_REFNIL; - globalconf.hooks.urgent = LUA_REFNIL; + globalconf.hooks.property = LUA_REFNIL; globalconf.hooks.timer = LUA_REFNIL; } diff --git a/luaa.h b/luaa.h index 1e391eb1..0c9e6c15 100644 --- a/luaa.h +++ b/luaa.h @@ -270,5 +270,12 @@ luaA_generic_pairs(lua_State *L) return 3; } +#define hooks_property(c, prop) \ + do { \ + luaA_client_userdata_new(globalconf.L, c); \ + lua_pushliteral(globalconf.L, prop); \ + luaA_dofunction(globalconf.L, globalconf.hooks.property, 2, 0); \ + } while(0); + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/property.c b/property.c index f4e0504e..4b795a5e 100644 --- a/property.c +++ b/property.c @@ -189,8 +189,7 @@ property_update_wm_hints(client_t *c, xcb_get_property_reply_t *reply) c->isurgent = isurgent; /* execute hook */ - luaA_client_userdata_new(globalconf.L, c); - luaA_dofunction(globalconf.L, globalconf.hooks.urgent, 1, 0); + hooks_property(c, "urgent"); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } @@ -239,8 +238,7 @@ property_update_wm_name(client_t *c) c->name = name; /* call hook */ - luaA_client_userdata_new(globalconf.L, c); - luaA_dofunction(globalconf.L, globalconf.hooks.titleupdate, 1, 0); + hooks_property(c, "name"); widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); } @@ -294,6 +292,9 @@ property_handle_net_wm_icon(void *data, widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS); icon = ewmh_window_icon_from_reply(reply); c->icon = icon ? image_ref(&icon) : NULL; + + /* execute hook */ + hooks_property(c, "icon"); } return 0; diff --git a/structs.h b/structs.h index 4fae841f..027437f1 100644 --- a/structs.h +++ b/structs.h @@ -440,14 +440,12 @@ struct awesome_t luaA_ref focus; /** Command to execute when removing focus to a client */ luaA_ref unfocus; - /** Command to run when mouse is over */ - luaA_ref mouse_over; + /** Command to run when mouse enter a client */ + luaA_ref mouse_enter; /** Command to run on arrange */ luaA_ref arrange; - /** Command to run on title change */ - luaA_ref titleupdate; - /** Command to run on urgent flag */ - luaA_ref urgent; + /** Command to run on property change */ + luaA_ref property; /** Command to run on time */ luaA_ref timer; } hooks;