Merge pull request #2360 from Elv13/add_awful_tag_layouts

awful.tag: Add awful tag layouts
This commit is contained in:
Emmanuel Lepage Vallée 2018-10-22 14:40:16 -04:00 committed by GitHub
commit 2458f127f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 192 additions and 1 deletions

View File

@ -21,6 +21,7 @@ local client = require("awful.client")
local ascreen = require("awful.screen") 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 protected_call = require("gears.protected_call") local protected_call = require("gears.protected_call")
local function get_screen(s) local function get_screen(s)
@ -73,6 +74,16 @@ layout.layouts = {
-- --
-- @field layout.layouts -- @field layout.layouts
--- Return the tag layout index (from `awful.layout.layouts`).
--
-- If the layout isn't part of `awful.layout.layouts`, this function returns
-- nil.
--
-- @tparam tag t The tag.
-- @treturn nil|number The layout index.
function layout.get_tag_layout_index(t)
return gtable.hasitem(layout.layouts, t.layout)
end
-- This is a special lock used by the arrange function. -- This is a special lock used by the arrange function.
-- This avoids recurring call by emitted signals. -- This avoids recurring call by emitted signals.

View File

@ -14,6 +14,7 @@ local gmath = require("gears.math")
local object = require("gears.object") local object = require("gears.object")
local timer = require("gears.timer") local timer = require("gears.timer")
local gtable = require("gears.table") local gtable = require("gears.table")
local alayout = nil
local pairs = pairs local pairs = pairs
local ipairs = ipairs local ipairs = ipairs
local table = table local table = table
@ -74,6 +75,68 @@ local function raw_tags(scr)
return tmp_tags return tmp_tags
end 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. --- The number of elements kept in the history.
-- @tfield integer awful.tag.history.limit -- @tfield integer awful.tag.history.limit
-- @tparam[opt=20] integer limit -- @tparam[opt=20] integer limit
@ -718,7 +781,26 @@ end
-- @tparam layout|function layout A layout table or a constructor function -- @tparam layout|function layout A layout table or a constructor function
-- @return The layout -- @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) function tag.object.set_layout(t, layout)
local template = nil
-- Check if the signature match a stateful layout -- Check if the signature match a stateful layout
if type(layout) == "function" or ( if type(layout) == "function" or (
type(layout) == "table" type(layout) == "table"
@ -741,14 +823,41 @@ function tag.object.set_layout(t, layout)
t.dynamic_layout_cache[layout] = instance t.dynamic_layout_cache[layout] = instance
end end
template = layout
layout = instance layout = instance
end end
tag.setproperty(t, "layout", layout) tag.setproperty(t, "layout", layout)
update_layouts(t, template or layout, layout)
return layout return layout
end 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) function tag.object.get_layout(t)
return tag.getproperty(t, "layout") or require("awful.layout.suit.floating") return tag.getproperty(t, "layout") or require("awful.layout.suit.floating")
end end

View File

@ -1,4 +1,5 @@
local awful = require("awful") local awful = require("awful")
local gtable = require("gears.table")
local beautiful = require("beautiful") local beautiful = require("beautiful")
local function check_order() local function check_order()
@ -124,7 +125,77 @@ local steps = {
return true return true
end end
end,
-- Test the custom layout list
function()
local t = mouse.screen.tags[9]
assert(t)
-- Test that the global_layouts is the default
local global_layouts = awful.layout.layouts
local t_layouts = t.layouts
local count = #t_layouts
local original = gtable.clone(t_layouts, false)
assert(t_layouts and global_layouts)
assert(#global_layouts == #t_layouts)
for idx, l in ipairs(global_layouts) do
assert(t_layouts[idx] == l)
end end
-- Make sure the list isn't forked
t.layout = global_layouts[3]
assert(t_layouts == t.layouts)
-- Add a dummy layout
t.layout = {name = "fake1", arrange=function() end}
assert(#t.layouts == #global_layouts+1)
-- Make sure adding global layouts still work
table.insert(global_layouts, {name = "fake2", arrange=function() end})
assert(#t.layouts == count+2)
-- Test that the global list is forked when there is no other
-- options.
table.insert(global_layouts, function()
return {name = "fake2", arrange=function() end}
end)
assert(#t.layouts == count+3)
assert(#original == #global_layouts-2)
assert(not t._layouts)
t.layout = global_layouts[#global_layouts]
assert(t._layouts)
assert(#t._custom_layouts+#global_layouts == #t.layouts)
assert(#t.layouts == count+3, "Expected "..(count+3).." got "..#t.layouts)
-- Create a custom list of layouts
t.layouts = {
awful.layout.suit.fair,
awful.layout.suit.fair.horizontal,
}
-- 3 because the current layout was added
assert(#t.layouts == 3)
t.layout = {name = "fake3", arrange=function() end}
assert(#t.layouts == 4)
-- Test the layout template and stateful layouts
t.layouts = {
t.layout,
function() return {name = "fake4", arrange=function() end} end
}
assert(#t.layouts == 2)
t.layout = t.layouts[2]
assert(#t.layouts == 2)
return true
end,
} }
local multi_screen_steps = {} local multi_screen_steps = {}