Files
flake/environments/river/layout.lua
T

175 lines
4.4 KiB
Lua

---@diagnostic disable: lowercase-global, undefined-global
local inner_gaps = 10
local outer_gaps = 15
local smart_gaps = true
local outputs = {}
function _get_output(name)
local output = outputs[name]
if output ~= nil then
return output
end
outputs[name] = {
mfact = 0.65,
mcount = 1,
layout = "tiling",
alayout = "monocle"
}
return outputs[name]
end
-- The most important function - the actual layout generator
--
-- The argument is a table with:
-- * Focused tags (`args.tags`)
-- * Window count (`args.count`)
-- * Output width (`args.width`)
-- * Output height (`args.height`)
-- * Output name (`args.output`)
--
-- The return value must be a table with exactly `count` entries. Each entry is a table with four
-- numbers:
-- * X coordinate
-- * Y coordinate
-- * Window width
-- * Window height
--
-- This example is a simplified version of `rivertile`
function handle_layout(args)
local output = _get_output(args.output)
-- Prevent mcount from growing too much. We can't do that in the set function.
output.mcount = math.min(output.mcount, args.count)
local ret = {}
if args.count == 1 or output.layout == "monocle" then
if smart_gaps then
for _ = 0, (args.count - 1) do
table.insert(ret, { 0, 0, args.width, args.height })
end
else
for _ = 0, (args.count - 1) do
table.insert(ret, { outer_gaps, outer_gaps, args.width - outer_gaps * 2, args.height - outer_gaps * 2 })
end
end
return ret
end
local width = args.width - outer_gaps * 2
local height = args.height - outer_gaps * 2
local mcount = math.min(output.mcount, args.count)
local scount = math.max(args.count - mcount, 0)
local old_scount = scount
if output.layout == "deck" and scount > 0 then
scount = 1;
end
local main_w = (width * output.mfact) - (inner_gaps / 2)
local side_w = (width * (1 - output.mfact)) - (inner_gaps / 2)
local main_h = (height - (inner_gaps * (mcount - 1))) / mcount
local side_h = (height - (inner_gaps * (scount - 1))) / scount
scount = old_scount
if args.count <= output.mcount then
main_w = width
end
for i = 0, (mcount - 1) do
table.insert(ret, {
outer_gaps,
outer_gaps + i * (main_h + inner_gaps),
main_w,
main_h,
})
end
for i = 0, (scount - 1) do
local y = outer_gaps + i * (side_h + inner_gaps)
if output.layout == "deck" then
y = outer_gaps
end
table.insert(ret, {
main_w + outer_gaps * 2,
y,
side_w,
side_h,
})
end
return ret
end
-- This optional function returns the metadata for the current layout.
-- Currently only `name` is supported, the name of the layout. It get's passed
-- the same `args` as handle_layout()
function handle_metadata(args)
local output = _get_output(args.output)
if output.layout == "tiling" then
return { name = "[]=" }
elseif output.layout == "monocle" then
return { name = string.format("[%d]", args.count) }
elseif output.layout == "deck" then
return { name = "[D]" }
else
return { name = "><>" }
end
end
-- IMPORTANT: User commands send via `riverctl send-layout-cmd` are treated as lua code.
-- Active tags are stored in `CMD_TAGS` global variable.
-- Output name is stored in `CMD_OUTPUT` global variable.
-- Here is an example of a function that can be mapped to some key
-- Run with `riverctl send-layout-cmd luatile "toggle_gaps()"`
function set_mfact(diff)
local output = _get_output(CMD_OUTPUT)
output.mfact = math.max(0, math.min(output.mfact + diff, 1))
end
function set_mcount(diff)
local output = _get_output(CMD_OUTPUT)
-- we don't have the number of clients so we can't set a max value there.
output.mcount = math.max(0, output.mcount + diff)
end
function set_layout(name)
local output = _get_output(CMD_OUTPUT)
if output.layout == name then
output.layout = output.alayout
output.alayout = name
else
output.alayout = output.layout
output.layout = name
end
end
-- Just an helper function to print tables.
function inspect(tbl)
local result = "{"
for k, v in pairs(tbl) do
-- Check the key type (ignore any numerical keys - assume its an array)
if type(k) == "string" then
result = result .. "[\"" .. k .. "\"]" .. "="
end
-- Check the value type
if type(v) == "table" then
result = result .. inspect(v)
elseif type(v) == "boolean" then
result = result .. tostring(v)
else
result = result .. "\"" .. v .. "\""
end
result = result .. ","
end
-- Remove leading commas from the result
if result ~= "" then
result = result:sub(1, result:len() - 1)
end
return result .. "}"
end