diff --git a/lib/awful/layout/init.lua b/lib/awful/layout/init.lua index 7ef4d5f5e..6dcfaa412 100644 --- a/lib/awful/layout/init.lua +++ b/lib/awful/layout/init.lua @@ -22,6 +22,7 @@ local ascreen = require("awful.screen") local timer = require("gears.timer") local gmath = require("gears.math") local gtable = require("gears.table") +local gdebug = require("gears.debug") local protected_call = require("gears.protected_call") local function get_screen(s) @@ -108,35 +109,42 @@ function layout.inc(i, s, layouts) if type(i) == "table" then -- Older versions of this function had arguments (layouts, i, s), but -- this was changed so that 'layouts' can be an optional parameter + gdebug.deprecate("Use awful.layout.inc(increment, screen, layouts) instead".. + " of awful.layout.inc(layouts, increment, screen)", {deprecated_in=5}) + layouts, i, s = i, s, layouts end s = get_screen(s or ascreen.focused()) local t = s.selected_tag - layouts = layouts or layout.layouts - if t then - local curlayout = layout.get(s) - local curindex - for k, v in ipairs(layouts) do - if v == curlayout or curlayout._type == v then - curindex = k - break - end - end - if not curindex then - -- Safety net: handle cases where another reference of the layout - -- might be given (e.g. when (accidentally) cloning it). - for k, v in ipairs(layouts) do - if v.name == curlayout.name then - curindex = k - break - end - end - end - if curindex then - local newindex = gmath.cycle(#layouts, curindex + i) - layout.set(layouts[newindex], t) - end + + if not t then return end + + layouts = layouts or t.layouts or {} + + if #layouts == 0 then + layouts = layout.layouts end + + local cur_l = layout.get(s) + + -- First try to match the object + local cur_idx = gtable.find_first_key( + layouts, function(_, v) return v == cur_l or cur_l._type == v end, true + ) + + -- Safety net: handle cases where another reference of the layout + -- might be given (e.g. when (accidentally) cloning it). + cur_idx = cur_idx or gtable.find_first_key( + layouts, function(_, v) return v.name == cur_l.name end, true + ) + + -- Trying to come up with some kind of fallback layouts to iterate would + -- never produce a result the user expect, so if there is nothing to + -- iterate over, do not iterate. + if not cur_idx then return end + + local newindex = gmath.cycle(#layouts, cur_idx + i) + layout.set(layouts[newindex], t) end --- Set the layout function of the current tag. diff --git a/lib/awful/tag.lua b/lib/awful/tag.lua index 200d9c6a4..631914d50 100644 --- a/lib/awful/tag.lua +++ b/lib/awful/tag.lua @@ -854,12 +854,21 @@ end function tag.object.set_layouts(self, layouts) tag.setproperty(self, "_custom_layouts", {}) tag.setproperty(self, "_layouts", gtable.clone(layouts, false)) - update_layouts(self, self.layout, self.layout) + + local cur = tag.getproperty(self, "layout") + update_layouts(self, cur, cur) + self:emit_signal("property::layouts") end function tag.object.get_layout(t) - return tag.getproperty(t, "layout") or require("awful.layout.suit.floating") + local l = tag.getproperty(t, "layout") + if l then return l end + + local layouts = tag.getproperty(t, "_layouts") + + return layouts and layouts[1] + or require("awful.layout.suit.floating") end --- Set layout. diff --git a/lib/gears/table.lua b/lib/gears/table.lua index be0a9a9e6..d5f525743 100644 --- a/lib/gears/table.lua +++ b/lib/gears/table.lua @@ -100,6 +100,48 @@ function gtable.hasitem(t, item) end end +--- Get all matching table keys for a `matcher` function. +-- +-- @tparam table t The table. +-- @tparam function matcher A function taking the key and value as arguments and +-- returning a boolean. +-- @tparam[opt=false] boolean ordered If true, only look for continuous +-- numeric keys. +-- @tparam[opt=nil] number max The maximum number of entries to find. +-- @treturn table|nil An ordered table with all the keys or `nil` if none were +-- found. +function gtable.find_keys(t, matcher, ordered, max) + if max == 0 then return nil end + + ordered, max = ordered or false, 0 + local ret, it = {}, ordered and ipairs or pairs + + for k, v in it(t) do + if matcher(k,v) then + table.insert(ret, k) + + if #ret == max then break end + end + end + + return #ret > 0 and ret or nil +end + +--- Find the first key that matches a function. +-- +-- @tparam table t The table. +-- @tparam function matcher A function taking the key and value as arguments and +-- returning a boolean. +-- @tparam[opt=false] boolean ordered If true, only look for continuous +-- numeric keys. +-- @return The table key or nil +function gtable.find_first_key(t, matcher, ordered) + local ret = gtable.find_keys(t, matcher, ordered, 1) + + return ret and ret[1] or nil +end + + --- Get a sorted table with all integer keys from a table. -- @class function -- @name keys