In this post I show a nice method to define tags and associated layouts, where the tag names change dynamically when the layout changes.
Note: the following works with AwesomeWM v4.0. I used v4.0-105-gbfb35349.
Current situation
When you look at the example rc.lua
file, you see that tags and layout setup
is spread over several places.
First, you have this long list of available layouts:
-- 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,
}
and then, where the screens get setup, you see:
-- Each screen has its own tag table.
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
I disliked several things here:
- the numbers aren’t telling me much
- when I change the numbers to roles, e.g. “www”, “dev”, “music” I loose flexibility. Maybe I don’t have “music” at the work, but at home …
- as a layout is tightly coupled to a tag, it would probably be better to reflect the layout in the tag name.
- initializing all tags with the same layout seems unflexible
So let’s work toward a setup that will fit more to my taste.
Define tags and layouts in one go
I first define a table that contains which tags I want and their default layout:
local my_tag_list = {
awful.layout.suit.fair,
awful.layout.suit.fair,
awful.layout.suit.fair,
awful.layout.suit.floating,
awful.layout.suit.max,
}
With this example, I would end up with 5 tags.
Automatically set awful.layout.layouts
This is completely optional. If you don’t want this, then setup
awful.layout.layouts
like in the example rc.lua.
Awesome needs awful.layout.layouts
set. It uses when you
increment/decrement the layout, e.g with the mouse or some keybinding.
Instead of manually setting this up, we can use my_tag_list
as a
source for it.
awful.layout.layouts = {}
for _,v in pairs(my_tag_list) do
if not awful.util.table.hasitem(awful.layout.layouts, v) then
table.insert(awful.layout.layouts, v)
end
end
Attach tags and layouts to the screens
We can now attach our tags and layouts to the screens:
-- put this inside the `awful.screen.connect_for_each_screen` function:
for i,l in ipairs(my_tag_list) do
awful.tag.add(i .. ":" .. shorten_layout_name(l.name),
{layout = l,
screen = s,
selected = i==1})
end
An observant reader will have noticed that I used a function
shorten_layout_name()
. That’s just because I want my tag/layout
names to be short, e.g. around 4 characters wide.
function shorten_layout_name(name)
if name == "fullscreen" then name = "full"
elseif name == "floating" then name = "float"
elseif name == "fairv" then name = "fair"
elseif name == "termfair" then name = "term" end
return name
end
Automatically change the tag names when layout changes
The taglist will now look like
4:fair 5:fait 6:fair 7:float 8:max
This will be wrong as soon as I change the layout of a tag. So I need to react to some signals. Define this function:
local function tagbox_update_tagname(t)
t.name = t.index .. ":" .. shorten_layout_name(t.layout.name)
end
And now just assign this function to two signals:
-- put this inside the `awful.screen.connect_for_each_screen` function:
awful.tag.attached_connect_signal(s, "tagged", tagbox_update_tagname)
awful.tag.attached_connect_signal(s, "property::layout", tagbox_update_tagname)