Mastering Layouts in AwesomeWM: Create Your Own Tabless mstab
The AwesomeWM bling
library offers a world of layout possibilities, but sometimes it feels like you're drowning in options. If you love the mstab
layout but want to ditch the tab bar and trim down the bloat, you're in the right place. Let's roll up our sleeves and craft our own custom layout that puts you in control!
Crafting Your Layout
Let's start by importing the necessary functionality. In the AwesomeWM world, it's always best to work smartly.
local math = math
local screen = screen
local stack = {}
AwesomeWM layouts are specific to the tag they are called from. We'll begin by getting variables assigned to our present tag.
local function arrange(p, dir)
local t = p.tag or screen[p.screen].selected_tag
local wa = p.workarea
local cls = p.clients
if #cls == 0 then
return
}
Unfortunately, AwesomeWM insists on using the master-slave
naming convention, which might not be your cup of tea. However, it's best to stick with conventions to keep everything consistent.
Let's assign variables related to the two sides of the screen - one for the master window and one for the slave window that stacking will occur on.
local mstrWidthFact = t.master_width_factor
local mstrWidth = math.floor(wa.width * mstrWidthFact)
local mstrHeight = math.floor(wa.height)
local slavesNumber = #cls - 1
local slavesWidth = math.floor(wa.width - mstrWidth)
local slavesHeight = math.floor(wa.height)
if slavesNumber == 0 then
mstrWidth = wa.width
end
Now, it's time to assign positions for the master and slave. The direction ("right" or "left") will determine where the stacking occurs.
-- Places master
local c, g = cls[1], {}
g.height = math.max(mstrHeight, 1)
g.width = math.max(mstrWidth, 1)
g.y = wa.y
g.x = (dir == "right") and (wa.x) or (wa.x + slavesWidth)
if slavesNumber == 0 then
g.x = wa.x
end
p.geometries[c] = g
Now, to limit the screen to showing the two windows and ensuring the stacking happens on the right side.
if #cls == 1 then
return
end
-- Places slaves
for i = 2, #cls do
local c, g = cls[i], {}
g.height = math.max(slavesHeight, 1)
g.width = math.max(slavesWidth, 1)
g.y = wa.y
g.x = (dir == "right") and (wa.x + mstrWidth) or (wa.x)
p.geometries[c] = g
end
end
Lastly, let's define the name of each layout variant and add the return statement at the end. This way, we can require this layout in the file where we append layouts to the default list. You're free to organize custom layouts as you see fit; I prefer to keep them in their directory.
stack.name = "stack"
function stack.arrange(p)
return arrange(p, "right")
end
stack.left = {}
stack.left.name = "stackLeft"
function stack.left.arrange(p)
return arrange(p, "left")
end
Conclusion
With the comment bars included, your final source code should look like this. You'll need to add this file to wherever you append layouts to your configuration. I often keep custom layouts in their own directory, but you can organize it your way.
local math = math
local screen = screen
local stack = {}
local function arrange(p, dir)
local t = p.tag or screen[p.screen].selected_tag
local wa = p.workarea
local cls = p.clients
if #cls == 0 then
return
end
local mstrWidthFact = t.master_width_factor
local mstrWidth = math.floor(wa.width * mstrWidthFact)
local mstrHeight = math.floor(wa.height)
local slavesNumber = #cls - 1
local slavesWidth = math.floor(wa.width - mstrWidth)
local slavesHeight = math.floor(wa.height)
if slavesNumber == 0 then
mstrWidth = wa.width
end
-- Places master
local c, g = cls[1], {}
g.height = math.max(mstrHeight, 1)
g.width = math.max(mstrWidth, 1)
g.y = wa.y
g.x = (dir == "right") and (wa.x) or (wa.x + slavesWidth)
if slavesNumber == 0 then
g.x = wa.x
end
p.geometries[c] = g
if #cls == 1 then
return
end
-- Places slaves
for i = 2, #cls do
local c, g = cls[i], {}
g.height = math.max(slavesHeight, 1)
g.width = math.max(slavesWidth, 1)
g.y = wa.y
g.x = (dir == "right") and (wa.x + mstrWidth) or (wa.x)
p.geometries[c] = g
end
end
stack.name = "stack"
function stack.arrange(p)
return arrange(p, "right")
end
stack.left = {}
stack.left.name = "stackLeft"
function stack.left.arrange(p)
return arrange(p, "left")
end
return stack
There you have it! You've mastered a custom layout in AwesomeWM, taking control of your workspace without the extra fluff. Happy customizing!