diff --git a/hyprland/.config/hypr/binds.lua b/hyprland/.config/hypr/binds.lua index 8f3bba3..5b0f7b9 100644 --- a/hyprland/.config/hypr/binds.lua +++ b/hyprland/.config/hypr/binds.lua @@ -44,11 +44,43 @@ hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "r" }), { desc = "Focus ri hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "u" }), { desc = "Focus up" }) hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "d" }), { desc = "Focus down" }) --- Cycle workspaces on the active monitor with mainMod + arrows (m+1/m-1 stay --- on the current monitor; plain +1/-1 would follow the workspace if it moves --- to another monitor). These only visit non-empty workspaces. -hl.bind(mainMod .. " + Left", hl.dsp.focus({ workspace = "m-1" }), { desc = "Previous workspace (active monitor)" }) -hl.bind(mainMod .. " + Right", hl.dsp.focus({ workspace = "m+1" }), { desc = "Next workspace (active monitor)" }) +-- Cycle workspaces on the active monitor with mainMod + arrows. Advancing past +-- the last workspace on the monitor creates a fresh (empty) workspace there; +-- going before the first wraps around to the last one on the monitor. +local function step_workspace(dir) + local mon = hl.get_active_monitor() + if not mon then return end + local current = mon.active_workspace.id + + local mon_ids, all_max = {}, 0 + for _, ws in ipairs(hl.get_workspaces()) do + if ws.id > all_max then all_max = ws.id end + if ws.monitor and ws.monitor.id == mon.id then + table.insert(mon_ids, ws.id) + end + end + table.sort(mon_ids) + + local target + if dir > 0 then + for _, id in ipairs(mon_ids) do + if id > current then target = id break end + end + -- No next workspace on this monitor: create one right here. + if not target then target = all_max + 1 end + else + for i = #mon_ids, 1, -1 do + if mon_ids[i] < current then target = mon_ids[i] break end + end + -- No previous workspace on this monitor: wrap to the last one. + if not target and #mon_ids > 0 then target = mon_ids[#mon_ids] end + end + + if target then hl.dispatch(hl.dsp.focus({ workspace = target })) end +end + +hl.bind(mainMod .. " + Left", function() step_workspace(-1) end, { desc = "Previous workspace (active monitor)" }) +hl.bind(mainMod .. " + Right", function() step_workspace(1) end, { desc = "Next workspace (active monitor); creates one past the end" }) -- Switch workspaces with mainMod + [0-9] for i = 1, 10 do diff --git a/hyprland/.config/hypr/hyprland.lua b/hyprland/.config/hypr/hyprland.lua index 514a2a0..54d94db 100644 --- a/hyprland/.config/hypr/hyprland.lua +++ b/hyprland/.config/hypr/hyprland.lua @@ -41,8 +41,8 @@ hl.config({ hl.config({ binds = { - -- Let SUPER+Left/Right (and scroll) wrap around instead of stopping at the - -- edge when cycling workspaces on the active monitor. + -- Let SUPER+scroll workspace cycling wrap around instead of stopping at + -- the edges. (SUPER+Left/Right wrapping is handled directly in binds.lua.) allow_workspace_cycles = true, }, })