awful.tag: Add a "tag centric" way to manage a layout list.

Previously, the layout list was global. However it wasn't covering all
possible use cases and make using `awful.widget.layoutlist` hard since
a layout could be excluded from the `awful.layout.layouts` but still
used for a tag (by setting it explicitly).
This commit is contained in:
Emmanuel Lepage Vallee 2018-08-18 17:58:06 -04:00
parent ae5fc042ae
commit 990b1ddb9d
1 changed files with 109 additions and 0 deletions

View File

@ -14,6 +14,7 @@ local gmath = require("gears.math")
local object = require("gears.object")
local timer = require("gears.timer")
local gtable = require("gears.table")
local alayout = nil
local pairs = pairs
local ipairs = ipairs
local table = table
@ -74,6 +75,68 @@ local function raw_tags(scr)
return tmp_tags
end
local function custom_layouts(self)
local cls = tag.getproperty(self, "_custom_layouts")
if not cls then
cls = {}
tag.setproperty(self, "_custom_layouts", cls)
end
return cls
end
-- Update the "user visible" list of layouts. If `from` and `to` are not the
-- same, then `from` will be replaced. This is necessary for either the layouts
-- defined as a function (called "template" below) and object oriented, stateful
-- layouts where the original entry is only a constructor.
local function update_layouts(self, from, to)
if not to then return end
alayout = alayout or require("awful.layout")
local override = tag.getproperty(self, "_layouts")
local pos = from and gtable.hasitem(override or {}, from) or nil
-- There is an override and the layout template is part of it, replace by
-- the instance.
if override and pos and from ~= to then
assert(type(pos) == 'number')
override[pos] = to
self:emit_signal("property::layouts")
return
end
-- Only add to the custom_layouts and preserve the ability to globally
-- set the layouts.
if override and not pos then
table.insert(override, to)
self:emit_signal("property::layouts")
return
end
pos = from and gtable.hasitem(alayout.layouts, from) or nil
local cls = custom_layouts(self)
-- The new layout is part of the global layouts. Fork the list.
if pos and from ~= to then
local cloned = gtable.clone(alayout.layouts, false)
cloned[pos] = to
gtable.merge(cloned, cls)
self.layouts = cloned
return
end
if pos then return end
if gtable.hasitem(cls, to) then return end
-- This layout is unknown, add it to the custom list
table.insert(cls, to)
self:emit_signal("property::layouts")
end
--- The number of elements kept in the history.
-- @tfield integer awful.tag.history.limit
-- @tparam[opt=20] integer limit
@ -718,7 +781,26 @@ end
-- @tparam layout|function layout A layout table or a constructor function
-- @return The layout
--- The (proposed) list of available layouts for this tag.
--
-- This property allows to define a subset (or superset) of layouts available
-- in the "rotation table". In the default configuration file, `Mod4+Space`
-- and `Mod4+Shift+Space` are used to switch between tags. The
-- `awful.widget.layoutlist` also uses this as its default layout filter.
--
-- By default, it will be the same as `awful.layout.layouts` unless there the
-- a layout not present is used. If that's the case they will be added at the
-- front of the list.
--
-- @property layouts
-- @param table
-- @see awful.layout.layouts
-- @see layout
function tag.object.set_layout(t, layout)
local template = nil
-- Check if the signature match a stateful layout
if type(layout) == "function" or (
type(layout) == "table"
@ -741,14 +823,41 @@ function tag.object.set_layout(t, layout)
t.dynamic_layout_cache[layout] = instance
end
template = layout
layout = instance
end
tag.setproperty(t, "layout", layout)
update_layouts(t, template or layout, layout)
return layout
end
function tag.object.get_layouts(self)
local override = tag.getproperty(self, "_layouts")
if override then
return override
end
-- Required to get the default/fallback list of layouts
alayout = alayout or require("awful.layout")
local cls = custom_layouts(self)
-- Without the clone, the custom_layouts would grow
return #cls > 0 and gtable.merge(gtable.clone(cls, false), alayout.layouts) or
alayout.layouts
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)
self:emit_signal("property::layouts")
end
function tag.object.get_layout(t)
return tag.getproperty(t, "layout") or require("awful.layout.suit.floating")
end