From 5ad0856fee6596f2b50a24e6a047aa7068f12268 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Mon, 11 Nov 2019 01:55:54 -0500 Subject: [PATCH] layout: Add a `request::default_layouts` to fill the list of layouts. This will allow the default client layout list to be manipulated by modules without the risk of overwriting each other. The commit also add a new `--{{{ Tag --}}}` section to `rc.lua`. It will be expanded once the tag rules get merged. --- awesomerc.lua | 46 ++++++------ lib/awful/layout/init.lua | 143 ++++++++++++++++++++++++++++++++------ objects/tag.c | 14 ++++ 3 files changed, 161 insertions(+), 42 deletions(-) diff --git a/awesomerc.lua b/awesomerc.lua index 13959fb10..733bc1840 100644 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -49,27 +49,6 @@ editor_cmd = terminal .. " -e " .. editor -- I suggest you to remap Mod4 to another key using xmodmap or other tools. -- However, you can use another modifier like Mod1, but it may interact with others. modkey = "Mod4" - --- @DOC_LAYOUT@ --- Table of layouts to cover with awful.layout.inc, order matters. -awful.layout.layouts = { - awful.layout.suit.floating, - awful.layout.suit.tile, - awful.layout.suit.tile.left, - awful.layout.suit.tile.bottom, - awful.layout.suit.tile.top, - awful.layout.suit.fair, - awful.layout.suit.fair.horizontal, - awful.layout.suit.spiral, - awful.layout.suit.spiral.dwindle, - awful.layout.suit.max, - awful.layout.suit.max.fullscreen, - awful.layout.suit.magnifier, - awful.layout.suit.corner.nw, - -- awful.layout.suit.corner.ne, - -- awful.layout.suit.corner.sw, - -- awful.layout.suit.corner.se, -} -- }}} -- {{{ Menu @@ -95,10 +74,33 @@ mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon, menubar.utils.terminal = terminal -- Set the terminal for applications that require it -- }}} +-- {{{ Tag +-- @DOC_LAYOUT@ +-- Table of layouts to cover with awful.layout.inc, order matters. +tag.connect_signal("request::default_layouts", function() + awful.layout.append_default_layouts({ + awful.layout.suit.floating, + awful.layout.suit.tile, + awful.layout.suit.tile.left, + awful.layout.suit.tile.bottom, + awful.layout.suit.tile.top, + awful.layout.suit.fair, + awful.layout.suit.fair.horizontal, + awful.layout.suit.spiral, + awful.layout.suit.spiral.dwindle, + awful.layout.suit.max, + awful.layout.suit.max.fullscreen, + awful.layout.suit.magnifier, + awful.layout.suit.corner.nw, + }) +end) +-- }}} + +-- {{{ Wibar + -- Keyboard map indicator and switcher mykeyboardlayout = awful.widget.keyboardlayout() --- {{{ Wibar -- Create a textclock widget mytextclock = wibox.widget.textclock() diff --git a/lib/awful/layout/init.lua b/lib/awful/layout/init.lua index e9aeb0097..47bbcbf2b 100644 --- a/lib/awful/layout/init.lua +++ b/lib/awful/layout/init.lua @@ -31,26 +31,17 @@ end local layout = {} -layout.suit = require("awful.layout.suit") +-- Support `table.insert()` to avoid breaking old code. +local default_layouts = setmetatable({}, { + __newindex = function(self, key, value) + assert(key <= #self+1 and key > 0) -layout.layouts = { - layout.suit.floating, - layout.suit.tile, - layout.suit.tile.left, - layout.suit.tile.bottom, - layout.suit.tile.top, - layout.suit.fair, - layout.suit.fair.horizontal, - layout.suit.spiral, - layout.suit.spiral.dwindle, - layout.suit.max, - layout.suit.max.fullscreen, - layout.suit.magnifier, - layout.suit.corner.nw, - layout.suit.corner.ne, - layout.suit.corner.sw, - layout.suit.corner.se, -} + layout.append_default_layout(value) + end +}) + + +layout.suit = require("awful.layout.suit") --- The default list of layouts. -- @@ -256,6 +247,51 @@ function layout.arrange(screen) end) end +--- Append a layout to the list of default tag layouts. +-- +-- @staticfct awful.layout.append_default_layout +-- @tparam layout to_add A valid tag layout. +-- @see awful.layout.layouts +function layout.append_default_layout(to_add) + rawset(default_layouts, #default_layouts+1, to_add) + capi.tag.emit_signal("property::layouts") +end + +--- Remove a layout from the list of default layouts. +-- +-- @staticfct awful.layout.remove_default_layout +-- @tparam layout to_remove A valid tag layout. +-- @treturn boolean True if the layout was found and removed. +-- @see awful.layout.layouts +function layout.remove_default_layout(to_remove) + local ret, found = false, true + + -- Remove all instances, just in case. + while found do + found = false + for k, l in ipairs(default_layouts) do + if l == to_remove then + table.remove(default_layouts, k) + ret, found = true, true + break + end + end + end + + return ret +end + +--- Append many layouts to the list of default tag layouts. +-- +-- @staticfct awful.layout.append_default_layouts +-- @tparam table layouts A table of valid tag layout. +-- @see awful.layout.layouts +function layout.append_default_layouts(layouts) + for _, l in ipairs(layouts) do + rawset(default_layouts, #default_layouts+1, l) + end +end + --- Get the current layout name. -- @param _layout The layout. -- @return The layout name. @@ -365,6 +401,73 @@ capi.screen.connect_signal("property::geometry", function(s, old_geom) end end) -return layout +local init_layouts +init_layouts = function() + capi.tag.emit_signal("request::default_layouts") + capi.tag.disconnect_signal("new", init_layouts) + + -- Fallback. + if #default_layouts == 0 then + layout.append_default_layouts({ + layout.suit.floating, + layout.suit.tile, + layout.suit.tile.left, + layout.suit.tile.bottom, + layout.suit.tile.top, + layout.suit.fair, + layout.suit.fair.horizontal, + layout.suit.spiral, + layout.suit.spiral.dwindle, + layout.suit.max, + layout.suit.max.fullscreen, + layout.suit.magnifier, + layout.suit.corner.nw, + layout.suit.corner.ne, + layout.suit.corner.sw, + layout.suit.corner.se, + }) + end + + init_layouts = nil +end + +-- "new" is emited before "activate", do it should be the very last opportunity +-- generate the list of default layout. With dynamic tag, this can happen later +-- than the first event loop iteration. +capi.tag.connect_signal("new", init_layouts) + +-- Intercept the calls to `layouts` to both lazyload then and emit the proper +-- signals. +local mt = { + __index = function(_, key) + if key == "layouts" then + -- Lazy initialization to *at least* attempt to give modules a + -- chance to load before calling `request::default_layouts`. Note + -- that the old `rc.lua` called `awful.layout.layouts` in the global + -- context. If there was some module `require()` later in the code, + -- they will not get the signal. + if init_layouts then + init_layouts() + end + + return default_layouts + end + end, + __newindex = function(_, key, value) + if key == "layouts" then + gdebug.print_warning( + "`awful.layout.layouts` was set before `request::default_layouts` could ".. + "be called. Please use `awful.layout.append_default_layouts` to ".. + " avoid this problem" + ) + capi.tag.disconnect_signal("new", init_layouts) + init_layouts = nil + else + rawset(layout, key, value) + end + end +} + +return setmetatable(layout, mt) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/objects/tag.c b/objects/tag.c index 729cfe299..de8e7a8e9 100644 --- a/objects/tag.c +++ b/objects/tag.c @@ -207,6 +207,20 @@ * @signal request::select */ +/** + * This signal is emitted to fill the list of default layouts. + * + * It is emitted on the global `tag` class rather than individual tag objects. + * The default handler is part of `rc.lua`. New modules can also use this signal + * to dynamically add new layouts to the list of default layouts. + * + * @signal request::default_layouts + * @see awful.layout.layouts + * @see awful.layout.append_default_layout + * @see awful.layout.remove_default_layout + */ + + /** When a client gets tagged with this tag. * @signal tagged * @client c The tagged client.