From 067bcaca60ed138f016388be34675e22d0421bc2 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sun, 10 Nov 2019 01:12:43 -0500 Subject: [PATCH] client: Rename the `manage` and `unmanage` signals. They currently fit the general concept of a `request::` in the sense that they are not property related and have "request handlers". The commit also add deprecation for signals. The reason for this fits within the larger standardization project. Non-namespaced signals will eventually be renamed. This has started a long time ago. What is old is new again. Once upon a time, there was a `startup` parameter to the `manage` signal. It is now back in the form of a context. Finally, this commit removes the `manage` section of `rc.lua`. It no longer did anything worthy of being in the config. Each of its important parts have been moved out over the years and the last remaining bit is always required anyway. The code has been moved to `client.lua`. --- awesomerc.lua | 22 +---- docs/05-awesomerc.md.lua | 6 -- docs/config.ld | 11 ++- event.c | 6 +- ewmh.c | 6 +- lib/awful/autofocus.lua | 2 +- lib/awful/client.lua | 37 ++++++-- lib/awful/client/urgent.lua | 2 +- lib/awful/rules.lua | 2 +- lib/awful/spawn.lua | 2 +- lib/awful/titlebar.lua | 6 +- lib/awful/widget/taglist.lua | 2 +- lib/awful/widget/tasklist.lua | 2 +- objects/client.c | 95 ++++++++++++++++--- objects/client.h | 10 +- .../examples/awful/placement/no_offscreen.lua | 3 + tests/examples/shims/client.lua | 4 + tests/test-awful-rules.lua | 2 +- tests/test-leak-client.lua | 2 +- tests/test-spawn-snid.lua | 2 +- tests/test-urgent.lua | 2 +- 21 files changed, 161 insertions(+), 65 deletions(-) diff --git a/awesomerc.lua b/awesomerc.lua index a3c25be1..f6018649 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -435,7 +435,7 @@ end) -- }}} -- {{{ Rules --- Rules to apply to new clients (through the "manage" signal). +-- Rules to apply to new clients. -- @DOC_RULES@ awful.rules.rules = { -- @DOC_GLOBAL_RULE@ @@ -495,22 +495,7 @@ awful.rules.rules = { } -- }}} --- {{{ Signals --- Signal function to execute when a new client appears. --- @DOC_MANAGE_HOOK@ -client.connect_signal("manage", function (c) - -- Set the windows at the slave, - -- i.e. put it at the end of others instead of setting it master. - -- if not awesome.startup then awful.client.setslave(c) end - - if awesome.startup - and not c.size_hints.user_position - and not c.size_hints.program_position then - -- Prevent clients from being unreachable after screen count changes. - awful.placement.no_offscreen(c) - end -end) - +-- {{{ Titlebars -- @DOC_TITLEBARS@ -- Add a titlebar if titlebars_enabled is set to true in the rules. client.connect_signal("request::titlebars", function(c) @@ -549,6 +534,7 @@ client.connect_signal("request::titlebars", function(c) layout = wibox.layout.align.horizontal } end) +-- }}} -- Enable sloppy focus, so that focus follows mouse. client.connect_signal("mouse::enter", function(c) @@ -558,4 +544,4 @@ end) -- @DOC_BORDER@ client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) --- }}} + diff --git a/docs/05-awesomerc.md.lua b/docs/05-awesomerc.md.lua index ffd0dbad..a1d0c5bd 100644 --- a/docs/05-awesomerc.md.lua +++ b/docs/05-awesomerc.md.lua @@ -208,12 +208,6 @@ sections.DOC_DIALOG_RULE = [[   ]] - -sections.DOC_MANAGE_HOOK = [[ -   -]] - - sections.DOC_TITLEBARS = [[   ]] diff --git a/docs/config.ld b/docs/config.ld index 3a906f56..c9686a04 100644 --- a/docs/config.ld +++ b/docs/config.ld @@ -70,6 +70,8 @@ new_type("deprecatedproperty", "Deprecated object properties", false, "Type cons new_type("method", "Object methods ", false, "Parameters") -- New type for signals new_type("signal", "Signals", false, "Arguments") +-- Deprecated signals. +new_type("deprecatedsignal", "Deprecated signals", false, "Arguments") -- New type for signals connections new_type("signalhandler", "Request handlers", false, "Arguments") -- Allow objects to define a set of beautiful properties affecting them @@ -736,6 +738,13 @@ local show_return = { deprecated = true, } +-- The different type of deprecation. +local is_deprecated = { + deprecated = true, + deprecatedproperty = true, + deprecatedsignal = true, +} + custom_display_name_handler = function(item, default_handler) init_custom_types(item) @@ -776,7 +785,7 @@ custom_display_name_handler = function(item, default_handler) end end - if item.type == "deprecated" or item.type == "deprecatedproperty" then + if is_deprecated[item.type] then return ret .. " [deprecated]" end diff --git a/event.c b/event.c index 989c0110..030f8616 100644 --- a/event.c +++ b/event.c @@ -478,7 +478,7 @@ event_handle_destroynotify(xcb_destroy_notify_event_t *ev) client_t *c; if((c = client_getbywin(ev->window))) - client_unmanage(c, false); + client_unmanage(c, CLIENT_UNMANAGE_DESTROYED); else for(int i = 0; i < globalconf.embedded.len; i++) if(globalconf.embedded.tab[i].win == ev->window) @@ -856,7 +856,7 @@ event_handle_unmapnotify(xcb_unmap_notify_event_t *ev) client_t *c; if((c = client_getbywin(ev->window))) - client_unmanage(c, true); + client_unmanage(c, CLIENT_UNMANAGE_UNMAP); } /** The randr screen change notify event handler. @@ -993,7 +993,7 @@ event_handle_reparentnotify(xcb_reparent_notify_event_t *ev) /* Ignore reparents to the root window, they *might* be caused by * ourselves if a client quickly unmaps and maps itself again. */ if (ev->parent != globalconf.screen->root) - client_unmanage(c, true); + client_unmanage(c, CLIENT_UNMANAGE_REPARENT); } else if (ev->parent != globalconf.systray.window) { /* Embedded window moved elsewhere, end of embedding */ diff --git a/ewmh.c b/ewmh.c index d720a304..429b96ee 100644 --- a/ewmh.c +++ b/ewmh.c @@ -238,8 +238,8 @@ ewmh_init_lua(void) luaA_class_connect_signal(L, &client_class, "focus", ewmh_update_net_active_window); luaA_class_connect_signal(L, &client_class, "unfocus", ewmh_update_net_active_window); - luaA_class_connect_signal(L, &client_class, "manage", ewmh_update_net_client_list); - luaA_class_connect_signal(L, &client_class, "unmanage", ewmh_update_net_client_list); + luaA_class_connect_signal(L, &client_class, "request::manage", ewmh_update_net_client_list); + luaA_class_connect_signal(L, &client_class, "request::unmanage", ewmh_update_net_client_list); luaA_class_connect_signal(L, &client_class, "property::modal" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::fullscreen" , ewmh_client_update_hints); luaA_class_connect_signal(L, &client_class, "property::maximized_horizontal" , ewmh_client_update_hints); @@ -256,7 +256,7 @@ ewmh_init_lua(void) luaA_class_connect_signal(L, &client_class, "property::titlebar_right" , ewmh_client_update_frame_extents); luaA_class_connect_signal(L, &client_class, "property::titlebar_left" , ewmh_client_update_frame_extents); luaA_class_connect_signal(L, &client_class, "property::border_width" , ewmh_client_update_frame_extents); - luaA_class_connect_signal(L, &client_class, "manage", ewmh_client_update_frame_extents); + luaA_class_connect_signal(L, &client_class, "request::manage", ewmh_client_update_frame_extents); /* NET_CURRENT_DESKTOP handling */ luaA_class_connect_signal(L, &client_class, "focus", ewmh_update_net_current_desktop); luaA_class_connect_signal(L, &client_class, "unfocus", ewmh_update_net_current_desktop); diff --git a/lib/awful/autofocus.lua b/lib/awful/autofocus.lua index 5647a965..f3ea73c1 100644 --- a/lib/awful/autofocus.lua +++ b/lib/awful/autofocus.lua @@ -64,7 +64,7 @@ end tag.connect_signal("property::selected", function (t) timer.delayed_call(check_focus_tag, t) end) -client.connect_signal("unmanage", check_focus_delayed) +client.connect_signal("request::unmanage", check_focus_delayed) client.connect_signal("tagged", check_focus_delayed) client.connect_signal("untagged", check_focus_delayed) client.connect_signal("property::hidden", check_focus_delayed) diff --git a/lib/awful/client.lua b/lib/awful/client.lua index c7d49f6b..a37f9d3c 100644 --- a/lib/awful/client.lua +++ b/lib/awful/client.lua @@ -843,7 +843,7 @@ capi.client.connect_signal("property::maximized_vertical", update_implicitly_flo capi.client.connect_signal("property::maximized_horizontal", update_implicitly_floating) capi.client.connect_signal("property::maximized", update_implicitly_floating) capi.client.connect_signal("property::size_hints", update_implicitly_floating) -capi.client.connect_signal("manage", update_implicitly_floating) +capi.client.connect_signal("request::manage", update_implicitly_floating) --- Toggle the floating state of a client between 'auto' and 'true'. -- Use `c.floating = not c.floating` @@ -1464,23 +1464,44 @@ end -- @tparam[opt=nil] string content The context (like "rules") -- @tparam[opt=nil] table hints Some hints. ---- The client marked signal (deprecated). --- @signal marked +--- The client marked signal. +-- @deprecatedsignal marked ---- The client unmarked signal (deprecated). --- @signal unmarked +--- The client unmarked signal. +-- @deprecatedsignal unmarked -- Add clients during startup to focus history. -- This used to happen through ewmh.activate, but that only handles visible -- clients now. -capi.client.connect_signal("manage", function (c) +capi.client.connect_signal("request::manage", function (c) + if capi.awesome.startup + and not c.size_hints.user_position + and not c.size_hints.program_position then + -- Prevent clients from being unreachable after screen count changes. + require("awful.placement").no_offscreen(c) + end + if awesome.startup then client.focus.history.add(c) end end) -capi.client.connect_signal("unmanage", client.focus.history.delete) +capi.client.connect_signal("request::unmanage", client.focus.history.delete) -capi.client.connect_signal("unmanage", client.floating.delete) +capi.client.connect_signal("request::unmanage", client.floating.delete) + +-- Print a warning when the old `manage` signal is used. +capi.client.connect_signal("manage::connected", function() + gdebug.deprecate( + "Use `request::manage` rather than `manage`", + {deprecated_in=5} + ) +end) +capi.client.connect_signal("unmanage::connected", function() + gdebug.deprecate( + "Use `request::unmanage` rather than `unmanage`", + {deprecated_in=5} + ) +end) -- Connect to "focus" signal, and allow to disable tracking. do diff --git a/lib/awful/client/urgent.lua b/lib/awful/client/urgent.lua index 8cdcc2cb..265a25fb 100644 --- a/lib/awful/client/urgent.lua +++ b/lib/awful/client/urgent.lua @@ -83,7 +83,7 @@ end capi.client.connect_signal("property::urgent", urgent.add) capi.client.connect_signal("focus", urgent.delete) -capi.client.connect_signal("unmanage", urgent.delete) +capi.client.connect_signal("request::unmanage", urgent.delete) return urgent diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index 9f4a6c40..9a659c14 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -657,7 +657,7 @@ function rules.completed_with_payload_callback(c, props, callbacks) rules.execute(c, props, callbacks) end -client.connect_signal("manage", rules.apply) +client.connect_signal("request::manage", rules.apply) --@DOC_rule_COMMON@ diff --git a/lib/awful/spawn.lua b/lib/awful/spawn.lua index 8b54b4d8..b01c1c1a 100644 --- a/lib/awful/spawn.lua +++ b/lib/awful/spawn.lua @@ -736,7 +736,7 @@ end capi.awesome.connect_signal("spawn::canceled" , spawn.on_snid_cancel ) capi.awesome.connect_signal("spawn::timeout" , spawn.on_snid_cancel ) -capi.client.connect_signal ("manage" , spawn.on_snid_callback ) +capi.client.connect_signal ("request::manage" , spawn.on_snid_callback ) return setmetatable(spawn, { __call = function(_, ...) return spawn.spawn(...) end }) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/awful/titlebar.lua b/lib/awful/titlebar.lua index 57bc3b01..0300c77a 100644 --- a/lib/awful/titlebar.lua +++ b/lib/awful/titlebar.lua @@ -557,7 +557,9 @@ local function new(c, args) c:connect_signal("unfocus", update_colors) -- Inform the drawable when it becomes invisible - c:connect_signal("unmanage", function() ret:_inform_visible(false) end) + c:connect_signal("request::unmanage", function() + ret:_inform_visible(false) + end) else bars[position].args = args ret = bars[position].drawable @@ -832,7 +834,7 @@ function titlebar.widget.stickybutton(c) return widget end -client.connect_signal("unmanage", function(c) +client.connect_signal("request::unmanage", function(c) all_titlebars[c] = nil end) diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index 7e8b117c..9fc15388 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -555,7 +555,7 @@ function taglist.new(args, filter, buttons, style, update_function, base_widget) end) capi.client.connect_signal("tagged", uc) capi.client.connect_signal("untagged", uc) - capi.client.connect_signal("unmanage", uc) + capi.client.connect_signal("request::unmanage", uc) capi.screen.connect_signal("removed", function(s) instances[get_screen(s)] = nil end) diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index d2fe7cfe..48e2adf7 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -621,7 +621,7 @@ function tasklist.new(args, filter, buttons, style, update_function, base_widget capi.client.connect_signal("property::hidden", u) capi.client.connect_signal("tagged", u) capi.client.connect_signal("untagged", u) - capi.client.connect_signal("unmanage", function(c) + capi.client.connect_signal("request::unmanage", function(c) u(c) for _, i in pairs(instances) do for _, tlist in pairs(i) do diff --git a/objects/client.c b/objects/client.c index 150bc0bf..84d1d674 100644 --- a/objects/client.c +++ b/objects/client.c @@ -63,7 +63,7 @@ * * To execute a callback when a new client is added, use the `manage` signal: * - * client.connect_signal("manage", function(c) + * client.connect_signal("request::manage", function(c) * -- do something * end) * @@ -164,7 +164,46 @@ */ /** When a new client appears and gets managed by Awesome. - * @signal manage + * + * This request should be implemented by code which track the client. It isn't + * recommended to use this to initialize the client content. This use case is + * a better fit for `ruled.client`, which has built-in dependency management. + * Using this request to mutate the client state will likely conflict with + * `ruled.client`. + * + * @signal request::manage + * @tparam client c The client. + * @tparam string context What created the client. It is currently either "new" + * or "startup". + * @tparam table hints More metadata (currently empty, it exists for compliance + * with the other `request::` signals). + */ + +/** When a client is going away. + * + * Each places which store `client` objects in non-weak table or whose state + * depend on the current client should answer this request. + * + * The contexts are: + * + * * **user**: `c:unmanage()` was called. + * * **reparented**: The window was reparented to another window. It is no + * longer a stand alone client. + * * **destroyed**: The window was closed. + * + * @signal request::unmanage + * @tparam client c The client. + * @tparam string context Why was the client unmanaged. + * @tparam table hints More metadata (currently empty, it exists for compliance + * with the other `request::` signals). + */ + +/** Use `request::manage`. + * @deprecatedsignal manage + */ + +/** Use `request::unmanage`. + * @deprecatedsignal unmanage */ /** @@ -275,10 +314,6 @@ * @signal unfocus */ -/** - * @signal unmanage - */ - /** When a client gets untagged. * @signal untagged * @tag t The tag object. @@ -1735,7 +1770,19 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at luaA_class_emit_signal(L, &client_class, "list", 0); + /* Add the context */ + if (globalconf.loop == NULL) + lua_pushstring(L, "startup"); + else + lua_pushstring(L, "new"); + + /* Hints */ + lua_newtable(L); + /* client is still on top of the stack; emit signal */ + luaA_object_emit_signal(L, -3, "request::manage", 2); + + /*TODO v6: remove this*/ luaA_object_emit_signal(L, -1, "manage", 0); xcb_generic_error_t *error = xcb_request_check(globalconf.connection, reparent_cookie); @@ -1744,7 +1791,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at NONULL(c->name), NONULL(c->class), NONULL(c->instance)); event_handle((xcb_generic_event_t *) error); p_delete(&error); - client_unmanage(c, true); + client_unmanage(c, CLIENT_UNMANAGE_FAILED); } /* pop client */ @@ -2354,10 +2401,10 @@ client_unban(client_t *c) /** Unmanage a client. * \param c The client. - * \param window_valid Is the client's window still valid? + * \param reason Why was the unmanage done. */ void -client_unmanage(client_t *c, bool window_valid) +client_unmanage(client_t *c, client_unmanage_t reason) { lua_State *L = globalconf_get_lua_State(); @@ -2384,6 +2431,28 @@ client_unmanage(client_t *c, bool window_valid) untag_client(c, globalconf.tags.tab[i]); luaA_object_push(L, c); + + /* Give the context to Lua */ + switch (reason) + { + break; + case CLIENT_UNMANAGE_USER: + lua_pushstring(L, "user"); + break; + case CLIENT_UNMANAGE_REPARENT: + lua_pushstring(L, "reparented"); + break; + case CLIENT_UNMANAGE_UNMAP: + case CLIENT_UNMANAGE_FAILED: + case CLIENT_UNMANAGE_DESTROYED: + lua_pushstring(L, "destroyed"); + break; + } + + /* Hints */ + lua_newtable(L); + + luaA_object_emit_signal(L, -3, "request::unmanage", 2); luaA_object_emit_signal(L, -1, "unmanage", 0); lua_pop(L, 1); @@ -2413,7 +2482,7 @@ client_unmanage(client_t *c, bool window_valid) /* Clear our event mask so that we don't receive any events from now on, * especially not for the following requests. */ - if(window_valid) + if(reason != CLIENT_UNMANAGE_DESTROYED) xcb_change_window_attributes(globalconf.connection, c->window, XCB_CW_EVENT_MASK, @@ -2423,7 +2492,7 @@ client_unmanage(client_t *c, bool window_valid) XCB_CW_EVENT_MASK, (const uint32_t []) { 0 }); - if(window_valid) + if(reason != CLIENT_UNMANAGE_DESTROYED) { xcb_unmap_window(globalconf.connection, c->window); xcb_reparent_window(globalconf.connection, c->window, globalconf.screen->root, @@ -2434,7 +2503,7 @@ client_unmanage(client_t *c, bool window_valid) window_array_append(&globalconf.destroy_later_windows, c->nofocus_window); window_array_append(&globalconf.destroy_later_windows, c->frame_window); - if(window_valid) + if(reason != CLIENT_UNMANAGE_DESTROYED) { /* Remove this window from the save set since this shouldn't be made visible * after a restart anymore. */ @@ -2823,7 +2892,7 @@ static int luaA_client_unmanage(lua_State *L) { client_t *c = luaA_checkudata(L, 1, &client_class); - client_unmanage(c, true); + client_unmanage(c, CLIENT_UNMANAGE_USER); return 0; } diff --git a/objects/client.h b/objects/client.h index 0c819318..74a23131 100644 --- a/objects/client.h +++ b/objects/client.h @@ -47,6 +47,14 @@ typedef enum { CLIENT_TITLEBAR_COUNT = 4 } client_titlebar_t; +typedef enum { + CLIENT_UNMANAGE_DESTROYED = 0, + CLIENT_UNMANAGE_USER = 1, + CLIENT_UNMANAGE_REPARENT = 2, + CLIENT_UNMANAGE_UNMAP = 3, + CLIENT_UNMANAGE_FAILED = 4 +} client_unmanage_t; + /* Special bit we invented to "fake" unset hints */ #define MWM_HINTS_AWESOME_SET (1L << 15) @@ -206,7 +214,7 @@ void client_ban_unfocus(client_t *); void client_unban(client_t *); void client_manage(xcb_window_t, xcb_get_geometry_reply_t *, xcb_get_window_attributes_reply_t *); bool client_resize(client_t *, area_t, bool); -void client_unmanage(client_t *, bool); +void client_unmanage(client_t *, client_unmanage_t); void client_kill(client_t *); void client_set_sticky(lua_State *, int, bool); void client_set_above(lua_State *, int, bool); diff --git a/tests/examples/awful/placement/no_offscreen.lua b/tests/examples/awful/placement/no_offscreen.lua index c7ac1038..4b4054ef 100644 --- a/tests/examples/awful/placement/no_offscreen.lua +++ b/tests/examples/awful/placement/no_offscreen.lua @@ -1,6 +1,9 @@ --DOC_GEN_OUTPUT --DOC_GEN_IMAGE --DOC_HIDE local awful = {placement = require("awful.placement")} --DOC_HIDE +--DOC_HIDE no_offscreen is auto-called when startup is true, avoid this. +awesome.startup = false -- luacheck: globals awesome.startup --DOC_HIDE + local c = client.gen_fake {x = -30, y = -30, width= 100, height=100} --DOC_HIDE print("Before:", "x="..c.x..", y="..c.y..", width="..c.width..", height="..c.height) --DOC_HIDE diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index f2067131..c425c537 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -287,7 +287,11 @@ function client.gen_fake(args) end }) + client.emit_signal("request::manage", ret) + + --TODO v6 remove this. client.emit_signal("manage", ret) + assert(not args.screen or (args.screen == ret.screen)) return ret diff --git a/tests/test-awful-rules.lua b/tests/test-awful-rules.lua index db89234d..24c61c7e 100644 --- a/tests/test-awful-rules.lua +++ b/tests/test-awful-rules.lua @@ -13,7 +13,7 @@ local tests = {} local tb_height = gears.math.round(beautiful.get_font_height() * 1.5) -- local border_width = beautiful.border_width --- Detect "manage" race conditions +-- Detect "request::manage" race conditions local real_apply = awful.rules.apply function awful.rules.apply(c) assert(#c:tags() == 0) diff --git a/tests/test-leak-client.lua b/tests/test-leak-client.lua index ca989b23..12b520e4 100644 --- a/tests/test-leak-client.lua +++ b/tests/test-leak-client.lua @@ -52,7 +52,7 @@ local function create_titlebar(c) end -- "Enable" titlebars (so that the titlebar can prevent garbage collection) -client.connect_signal("manage", function (c) +client.connect_signal("request::manage", function (c) create_titlebar(c) end) diff --git a/tests/test-spawn-snid.lua b/tests/test-spawn-snid.lua index 1a453070..6e08c2f2 100644 --- a/tests/test-spawn-snid.lua +++ b/tests/test-spawn-snid.lua @@ -5,7 +5,7 @@ local test_client = require("_client") local manage_called, c_snid -client.connect_signal("manage", function(c) +client.connect_signal("request::manage", function(c) manage_called = true c_snid = c.startup_id assert(c.machine == awesome.hostname, diff --git a/tests/test-urgent.lua b/tests/test-urgent.lua index f0558097..b36a4271 100644 --- a/tests/test-urgent.lua +++ b/tests/test-urgent.lua @@ -16,7 +16,7 @@ client.connect_signal("property::urgent", function (c) end) local manage_cb_done -client.connect_signal("manage", function (c) +client.connect_signal("request::manage", function (c) manage_cb_done = true assert(c.class == "XTerm", "Client should be xterm!") end)