Merge pull request #2509 from Elv13/xmas_2k18_3

Fix some tag.layouts corner cases
This commit is contained in:
Emmanuel Lepage Vallée 2019-01-24 08:50:41 -05:00 committed by GitHub
commit 7f0e2e6bbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 26 deletions

View File

@ -22,6 +22,7 @@ local ascreen = require("awful.screen")
local timer = require("gears.timer") local timer = require("gears.timer")
local gmath = require("gears.math") local gmath = require("gears.math")
local gtable = require("gears.table") local gtable = require("gears.table")
local gdebug = require("gears.debug")
local protected_call = require("gears.protected_call") local protected_call = require("gears.protected_call")
local function get_screen(s) local function get_screen(s)
@ -108,35 +109,42 @@ function layout.inc(i, s, layouts)
if type(i) == "table" then if type(i) == "table" then
-- Older versions of this function had arguments (layouts, i, s), but -- Older versions of this function had arguments (layouts, i, s), but
-- this was changed so that 'layouts' can be an optional parameter -- 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 layouts, i, s = i, s, layouts
end end
s = get_screen(s or ascreen.focused()) s = get_screen(s or ascreen.focused())
local t = s.selected_tag local t = s.selected_tag
layouts = layouts or layout.layouts
if t then if not t then return end
local curlayout = layout.get(s)
local curindex layouts = layouts or t.layouts or {}
for k, v in ipairs(layouts) do
if v == curlayout or curlayout._type == v then if #layouts == 0 then
curindex = k layouts = layout.layouts
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
end 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 end
--- Set the layout function of the current tag. --- Set the layout function of the current tag.

View File

@ -854,12 +854,21 @@ end
function tag.object.set_layouts(self, layouts) function tag.object.set_layouts(self, layouts)
tag.setproperty(self, "_custom_layouts", {}) tag.setproperty(self, "_custom_layouts", {})
tag.setproperty(self, "_layouts", gtable.clone(layouts, false)) 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") self:emit_signal("property::layouts")
end end
function tag.object.get_layout(t) 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 end
--- Set layout. --- Set layout.

View File

@ -100,6 +100,48 @@ function gtable.hasitem(t, item)
end end
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. --- Get a sorted table with all integer keys from a table.
-- @class function -- @class function
-- @name keys -- @name keys