Simplify layout cycling, fix wins not updating on maximize

This commit is contained in:
Ottatop 2023-09-09 04:01:55 -05:00
parent 68c47f15ae
commit a18b9856bb
3 changed files with 114 additions and 47 deletions

View file

@ -112,8 +112,11 @@ require("pinnacle").setup(function(pinnacle)
-- })
end)
---@type Layout[]
local layouts = {
-- Layout cycling
-- Create a layout cycler to cycle your tag layouts. This will store which layout each tag has
-- and change to the next or previous one in the array when the respective function is called.
local layout_cycler = tag.layout_cycler({
"MasterStack",
"Dwindle",
"Spiral",
@ -121,56 +124,17 @@ require("pinnacle").setup(function(pinnacle)
"CornerTopRight",
"CornerBottomLeft",
"CornerBottomRight",
}
local indices = {}
})
-- Layout cycling
-- Yes, this is overly complicated and yes, I'll cook up a way to make it less so.
input.keybind({ mod_key }, keys.space, function()
local tags = output.get_focused():tags()
for _, tg in pairs(tags) do
if tg:active() then
local name = tg:name()
if name == nil then
return
end
tg:set_layout(layouts[indices[name] or 1])
if indices[name] == nil then
indices[name] = 2
else
if indices[name] + 1 > #layouts then
indices[name] = 1
else
indices[name] = indices[name] + 1
end
end
break
end
end
layout_cycler.next()
end)
input.keybind({ mod_key, "Shift" }, keys.space, function()
local tags = output.get_focused():tags()
for _, tg in pairs(tags) do
if tg:active() then
local name = tg:name()
if name == nil then
return
end
tg:set_layout(layouts[indices[name] or #layouts])
if indices[name] == nil then
indices[name] = #layouts - 1
else
if indices[name] - 1 < 1 then
indices[name] = #layouts
else
indices[name] = indices[name] - 1
end
end
break
end
end
layout_cycler.prev()
end)
-- Tag manipulation
input.keybind({ mod_key }, keys.KEY_1, function()
tag.switch_to("1")
end)

View file

@ -472,4 +472,102 @@ function tag_module.output(t)
return require("output").get_for_tag(t)
end
---@class LayoutCycler
---@field next fun(output: (Output|OutputName)?) Change the first active tag on `output` to its next layout. If `output` is empty, the focused output is used.
---@field prev fun(output: (Output|OutputName)?) Change the first active tag on `output` to its previous layout. If `output` is empty, the focused output is used.
---Given an array of layouts, this will create two functions; one will cycle forward the layout
---for the provided tag, and one will cycle backward.
---@param layouts Layout[] The available layouts.
---@return LayoutCycler layout_cycler A table with the functions `next` and `prev`, which will cycle layouts for the given tag.
function tag_module.layout_cycler(layouts)
local indices = {}
-- Return empty functions if layouts is empty
if #layouts == 0 then
return {
next = function(_) end,
prev = function(_) end,
}
end
return {
---@param output (Output|OutputName)?
next = function(output)
if type(output) == "string" then
output = require("output").get_by_name(output)
end
output = output or require("output").get_focused()
if output == nil then
return
end
local tags = output:tags()
for _, tg in pairs(tags) do
if tg:active() then
local id = tg:id()
if id == nil then
return
end
if #layouts == 1 then
indices[id] = 1
elseif indices[id] == nil then
indices[id] = 2
else
if indices[id] + 1 > #layouts then
indices[id] = 1
else
indices[id] = indices[id] + 1
end
end
tg:set_layout(layouts[indices[id]])
break
end
end
end,
---@param output (Output|OutputName)?
prev = function(output)
if type(output) == "string" then
output = require("output").get_by_name(output)
end
output = output or require("output").get_focused()
if output == nil then
return
end
local tags = output:tags()
for _, tg in pairs(tags) do
if tg:active() then
local id = tg:id()
if id == nil then
return
end
if #layouts == 1 then
indices[id] = 1
elseif indices[id] == nil then
indices[id] = #layouts - 1
else
if indices[id] - 1 < 1 then
indices[id] = #layouts
else
indices[id] = indices[id] - 1
end
end
tg:set_layout(layouts[indices[id]])
break
end
end
end,
}
end
return tag_module

View file

@ -333,7 +333,9 @@ impl XdgShellHandler for State {
if !window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
// TODO: might need to update_windows here
let Some(output) = window.output(self) else { return };
self.update_windows(&output);
}
fn unmaximize_request(&mut self, surface: ToplevelSurface) {
@ -344,6 +346,9 @@ impl XdgShellHandler for State {
if window.with_state(|state| state.fullscreen_or_maximized.is_maximized()) {
window.toggle_maximized();
}
let Some(output) = window.output(self) else { return };
self.update_windows(&output);
}
// fn minimize_request(&mut self, surface: ToplevelSurface) {