diff --git a/awesomerc.lua b/awesomerc.lua index a3c25be1b..f60186497 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 ffd0dbad0..a1d0c5bd0 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 3a906f563..c9686a040 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 989c0110c..030f86166 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 d720a3043..429b96ee4 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 5647a9651..f3ea73c15 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 c7d49f6b7..a37f9d3c1 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 8cdcc2cba..265a25fb3 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 9f4a6c401..9a659c140 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 8b54b4d89..b01c1c1af 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 57bc3b011..0300c77a8 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 7e8b117c9..9fc153884 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 d2fe7cfee..48e2adf79 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 150bc0bfa..84d1d6740 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 0c8193184..74a23131c 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 c7ac1038f..4b4054ef0 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 f2067131f..c425c5379 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 db89234d6..24c61c7e4 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 ca989b231..12b520e45 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 1a4530701..6e08c2f2d 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 f0558097d..b36a42710 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)