diff options
| author | Sam Nystrom <sam@samnystrom.dev> | 2025-11-27 17:35:48 -0500 |
|---|---|---|
| committer | Sam Nystrom <sam@samnystrom.dev> | 2025-11-27 17:35:48 -0500 |
| commit | 747b8a465a501211ebe41d5892eb9262f26743dc (patch) | |
| tree | 170ef89197a6648a378cec1ce45201442c3e163e /modes.lua | |
Squashed '.config/waywall/waywork/' content from commit f0b8424
git-subtree-dir: .config/waywall/waywork
git-subtree-split: f0b84240c63f4a13d6a8cb54a037424d5d64329a
Diffstat (limited to 'modes.lua')
| -rw-r--r-- | modes.lua | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/modes.lua b/modes.lua new file mode 100644 index 0000000..3bf0047 --- /dev/null +++ b/modes.lua @@ -0,0 +1,103 @@ +local modes = {} + +--- ModeManager orchestrates resolution toggles and on_enter/on_exit hooks. +local ModeManager = {} +ModeManager.__index = ModeManager + +function ModeManager.new(waywall) + return setmetatable({ ww = waywall, active = nil, defs = {} }, ModeManager) +end + +--- def: { width, height, on_enter=function(), on_exit=function(), toggle_guard=function()->bool } +function ModeManager:define(name, def) + self.defs[name] = def +end + +local function active_res(ww) + local w, h = ww.active_res() + return tonumber(w), tonumber(h) +end + +--- Get the mode definition by name, erroring if not found. +--- @param name string +function ModeManager:_get_def(name) + assert(self.defs[name], "No such mode: " .. tostring(name)) + return self.defs[name] +end + +--- Transition to a mode by name, turning off any previously active mode. +--- If name is nil, turn off any active mode. +--- This does not check toggle_guard. +--- @param name string? +function ModeManager:_transition_to(name) + local function exit_active() + if self.active then + local prev = self:_get_def(self.active) + self.ww.set_resolution(0, 0) + if prev.on_exit then + prev.on_exit() + end + self.active = nil + end + end + + local function enter_mode(_name) + if _name then + local new = self:_get_def(_name) + self.ww.set_resolution(new.width, new.height) + if new.on_enter then + new.on_enter() + end + self.active = _name + end + end + + if name == nil then + exit_active() + return + end + if name == self.active then + -- already active, do nothing + return + end + exit_active() + enter_mode(name) +end + +--- Toggle a mode by name. If it's active, turn it off. If it's inactive, turn it on. +--- If the mode has a toggle_guard and it returns false, do nothing and return false. +--- @param name string +--- @return boolean|nil +function ModeManager:toggle(name) + local ww, def = self.ww, self.defs[name] + if not def then + return + end + if def.toggle_guard and def.toggle_guard() == false then + return false + end + -- local w, h = active_res(ww) + -- if w == def.width and h == def.height then + -- ww.set_resolution(0, 0) + -- if def.on_exit then + -- def.on_exit() + -- end + -- self.active = nil + -- else + -- ww.set_resolution(def.width, def.height) + -- if def.on_enter then + -- def.on_enter() + -- end + -- -- exit previous if different + -- self.active = name + -- end + + if name == self.active then + self:_transition_to(nil) + else + self:_transition_to(name) + end +end + +modes.ModeManager = ModeManager +return modes |
