NixDaemon

NixOS pentest workstation as one flake — IceBreaker's successor
git clone https://git.daemon-sec.xyz/NixDaemon.git
Log | Files | Refs | README

defaults.lua (20897B)


      1 -- defaults.lua — the stock Omarchy binds as they were live on the Arch install
      2 -- (vault shortcuts/keybinds.txt), re-expressed for NixOS + Caelestia with the
      3 -- same keys and descriptions. bindings.lua, lid.lua and caelestia.lua load
      4 -- after this file and unbind-then-rebind the keys they take over.
      5 --
      6 -- Keys whose Omarchy service has no counterpart here (reminders, bar panels,
      7 -- Herdr, OCR, …) keep their place but run `omarchy-not-ported`, which names
      8 -- the gap in a notification instead of failing silently. Apps not in the
      9 -- toolbox closure (spotify, lazydocker, btop, tmux, …) are treated the same.
     10 local o = require("omarchy")
     11 
     12 local function launch(cmd) return "uwsm app -- " .. cmd end
     13 local function web(url) return launch("zen-beta --new-window " .. url) end
     14 local function gone(description, was)
     15   return string.format("omarchy-not-ported %q %q", description, was or "")
     16 end
     17 local function resize(x, y) return hl.dsp.window.resize({ x = x, y = y, relative = true }) end
     18 
     19 local sidebar = "caelestia shell drawers toggle sidebar"
     20 local locked = { locked = true }
     21 local held = { locked = true, repeating = true }
     22 local mouse = { mouse = true }
     23 
     24 -- ── Apps ─────────────────────────────────────────────────────────────────────
     25 o.bind("SUPER + RETURN", "Terminal", launch("kitty"))
     26 o.bind("SUPER + SHIFT + RETURN", "Browser", launch("zen-beta"))
     27 o.bind("SUPER + SHIFT + B", "Browser", launch("zen-beta"))
     28 o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", launch("zen-beta --private-window"))
     29 o.bind("SUPER + SHIFT + F", "File manager", launch("nautilus --new-window"))
     30 o.bind("SUPER + SHIFT + ALT + F", "File manager (cwd)", launch("nautilus --new-window"))
     31 o.bind("SUPER + SHIFT + N", "Editor", launch("kitty -e ${EDITOR:-nano}"))
     32 o.bind("SUPER + SHIFT + O", "Obsidian", launch("obsidian")) -- bindings.lua rebinds (vault-open)
     33 o.bind("SUPER + SHIFT + ALT + M", "Music TUI", launch("kitty --class rmpc -e rmpc"))
     34 o.bind("SUPER + SHIFT + CTRL + A", "Agent", launch("kitty --class agent -e claude"))
     35 o.bind("CTRL + SUPER + Q", "Calculator", launch("kitty --class calculator -e qalc"))
     36 o.bind("XF86Calculator", "Calculator", launch("kitty --class calculator -e qalc"))
     37 o.bind("SUPER + SHIFT + M", "Music", gone("Music", "spotify"))
     38 o.bind("SUPER + SHIFT + D", "Docker", gone("Docker", "lazydocker"))
     39 o.bind("SUPER + SHIFT + G", "Signal", gone("Signal", "signal-desktop"))
     40 o.bind("SUPER + SHIFT + SLASH", "Passwords", gone("Passwords", "1password"))
     41 o.bind("SUPER + SHIFT + W", "Omawrite", gone("Omawrite", "Omarchy writing webapp"))
     42 o.bind("SUPER + SHIFT + E", "Email", gone("Email", "Omarchy mail webapp")) -- bindings.lua rebinds (Omamail)
     43 o.bind("SUPER + SHIFT + ALT + E", "New email", gone("New email", "Omarchy mail webapp"))
     44 o.bind("CTRL + SUPER + T", "Activity", gone("Activity", "btop"))
     45 o.bind("ALT + SUPER + RETURN", "Tmux", gone("Tmux", "tmux is not in the toolbox closure"))
     46 o.bind("CTRL + SUPER + RETURN", "Herdr", gone("Herdr"))
     47 o.bind("CTRL + SUPER + K", "Herdr keybindings", gone("Herdr keybindings"))
     48 
     49 -- ── Web apps (Zen windows) ───────────────────────────────────────────────────
     50 o.bind("SUPER + SHIFT + A", "ChatGPT", web("https://chatgpt.com"))
     51 o.bind("SUPER + SHIFT + ALT + A", "Grok", web("https://grok.com"))
     52 o.bind("SUPER + SHIFT + C", "Calendar", web("https://calendar.google.com"))
     53 o.bind("SUPER + SHIFT + Y", "YouTube", web("https://youtube.com")) -- bindings.lua rebinds (bakx)
     54 o.bind("SUPER + SHIFT + ALT + G", "WhatsApp", web("https://web.whatsapp.com"))
     55 o.bind("SUPER + SHIFT + CTRL + G", "Google Messages", web("https://messages.google.com/web"))
     56 o.bind("SUPER + SHIFT + X", "X", web("https://x.com"))
     57 o.bind("SUPER + SHIFT + ALT + X", "X Post", web("https://x.com/compose/post"))
     58 o.bind("SUPER + SHIFT + P", "Google Photos", web("https://photos.google.com"))
     59 o.bind("SUPER + SHIFT + S", "Google Maps", web("https://maps.google.com"))
     60 
     61 -- ── Shell: menus, panels, notifications ──────────────────────────────────────
     62 o.bind("SUPER + SPACE", "Omarchy menu", hl.dsp.global("caelestia:launcher")) -- caelestia.lua rebinds
     63 o.bind("ALT + SUPER + SPACE", "Apps menu", hl.dsp.global("caelestia:launcher"))
     64 o.bind("SUPER + ESCAPE", "System menu", hl.dsp.global("caelestia:session")) -- caelestia.lua rebinds
     65 o.bind("CTRL + SUPER + P", "Power", hl.dsp.global("caelestia:session"))
     66 o.bind("XF86PowerOff", "Power menu", hl.dsp.global("caelestia:session"), locked)
     67 o.bind("SUPER + K", "Keybindings", "keybinds-menu")
     68 o.bind("SUPER + SHIFT + SPACE", "Toggle top bar", gone("Toggle top bar", "the Caelestia bar has no toggle"))
     69 o.bind("SUPER + SHIFT + CTRL + SPACE", "Theme menu", gone("Theme menu", "the theme is static Rosé Pine here"))
     70 o.bind("CTRL + SUPER + SPACE", "Background switcher", "wallpaper-picker") -- Caelestia launcher in wallpaper mode (home/modules/hyprland.nix)
     71 o.bind("CTRL + SUPER + O", "Toggle menu", gone("Toggle menu"))
     72 o.bind("CTRL + SUPER + D", "Display", gone("Display", "omarchy display menu"))
     73 o.bind("CTRL + SUPER + H", "Hardware menu", gone("Hardware menu"))
     74 o.bind("CTRL + SUPER + S", "Share", gone("Share"))
     75 o.bind("CTRL + SUPER + PERIOD", "Transcode", gone("Transcode"))
     76 o.bind("CTRL + SUPER + W", "Network", sidebar) -- caelestia.lua rebinds
     77 o.bind("CTRL + SUPER + B", "Bluetooth", sidebar) -- caelestia.lua rebinds
     78 o.bind("CTRL + SUPER + A", "Audio", sidebar) -- caelestia.lua rebinds
     79 o.bind("CTRL + SUPER + E", "Emojis", "caelestia emoji")
     80 o.bind("CTRL + SUPER + V", "Clipboard manager", "caelestia clipboard")
     81 o.bind("CTRL + SUPER + C", "Capture menu", "caelestia shell picker openFreeze")
     82 o.bind("CTRL + SUPER + N", "Toggle nightlight", "nightlight-toggle")
     83 o.bind("CTRL + SUPER + I", "Toggle locking on idle", "caelestia shell idleInhibitor toggle")
     84 o.bind("CTRL + SUPER + L", "Lock system", hl.dsp.global("caelestia:lock"))
     85 o.bind("CTRL + SUPER + R", "Set reminder", gone("Set reminder"))
     86 o.bind("CTRL + ALT + SUPER + R", "Show reminders", gone("Show reminders"))
     87 o.bind("SHIFT + CTRL + SUPER + R", "Clear reminders", gone("Clear reminders"))
     88 o.bind("CTRL + ALT + SUPER + B", "Show battery remaining", "nixdaemon-show battery")
     89 o.bind("CTRL + ALT + SUPER + T", "Show time", "nixdaemon-show time")
     90 o.bind("CTRL + ALT + SUPER + D", "Calendar", "nixdaemon-show calendar")
     91 o.bind("CTRL + ALT + SUPER + W", "Toggle weather", "caelestia shell drawers toggle dashboard")
     92 o.bind("SUPER + comma", "Dismiss last notification", hl.dsp.global("caelestia:clearNotifs")) -- caelestia.lua rebinds
     93 o.bind("SUPER + SHIFT + comma", "Dismiss all notifications", hl.dsp.global("caelestia:clearNotifs"))
     94 o.bind("CTRL + SUPER + comma", "Toggle silencing notifications", "caelestia shell notifs toggleDnd") -- caelestia.lua rebinds
     95 o.bind("ALT + SUPER + comma", "Invoke last notification", gone("Invoke last notification"))
     96 o.bind("SHIFT + ALT + SUPER + comma", "Open notification history", sidebar)
     97 for i = 1, 9 do
     98   o.bind("CTRL + SUPER + code:" .. (9 + i), "Bar panel " .. i, gone("Bar panel " .. i, "Omarchy bar panels"))
     99 end
    100 
    101 -- ── Capture ──────────────────────────────────────────────────────────────────
    102 o.bind("PRINT", "Screenshot", hl.dsp.global("caelestia:screenshot"))
    103 o.bind("ALT + PRINT", "Screenrecording", "caelestia record")
    104 o.bind("SUPER + PRINT", "Color picker", "hyprpicker -a")
    105 o.bind("CTRL + SUPER + PRINT", "Extract text (OCR) from screenshot", gone("Extract text (OCR) from screenshot", "tesseract"))
    106 
    107 -- ── Media and hardware keys ──────────────────────────────────────────────────
    108 o.bind("XF86AudioRaiseVolume", "Volume up", "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+", held)
    109 o.bind("XF86AudioLowerVolume", "Volume down", "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-", held)
    110 o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 1%+", held)
    111 o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%-", held)
    112 o.bind("XF86AudioMute", "Mute", "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", locked)
    113 o.bind("XF86AudioMicMute", "Mute microphone", "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle", locked)
    114 o.bind("SHIFT + XF86AudioMute", "Switch audio output", "caelestia shell audio cycleOutput", locked)
    115 o.bind("XF86AudioPlay", "Play", hl.dsp.global("caelestia:mediaToggle"), locked)
    116 o.bind("XF86AudioPause", "Pause", hl.dsp.global("caelestia:mediaToggle"), locked)
    117 o.bind("XF86AudioNext", "Next track", hl.dsp.global("caelestia:mediaNext"), locked)
    118 o.bind("XF86AudioPrev", "Previous track", hl.dsp.global("caelestia:mediaPrev"), locked)
    119 o.bind("ALT + XF86AudioPlay", "Next track", hl.dsp.global("caelestia:mediaNext"), locked)
    120 o.bind("SHIFT + ALT + XF86AudioPlay", "Previous track", hl.dsp.global("caelestia:mediaPrev"), locked)
    121 o.bind("SHIFT + XF86AudioPlay", "Switch media source", gone("Switch media source", "playerctld shift"), locked)
    122 o.bind("SHIFT + XF86AudioPause", "Switch media source", gone("Switch media source", "playerctld shift"), locked)
    123 o.bind("XF86MonBrightnessUp", "Brightness up", "caelestia shell brightness set +5%", held)
    124 o.bind("XF86MonBrightnessDown", "Brightness down", "caelestia shell brightness set 5%-", held)
    125 o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "caelestia shell brightness set +1%", held)
    126 o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "caelestia shell brightness set 1%-", held)
    127 o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "caelestia shell brightness set 100%", held)
    128 o.bind("SHIFT + XF86MonBrightnessDown", "Brightness minimum", "caelestia shell brightness set 1%", held)
    129 o.bind("XF86KbdBrightnessUp", "Keyboard brightness up", "brightnessctl -q -d '*kbd_backlight' set 1+", held)
    130 o.bind("XF86KbdBrightnessDown", "Keyboard brightness down", "brightnessctl -q -d '*kbd_backlight' set 1-", held)
    131 o.bind("XF86KbdLightOnOff", "Keyboard backlight cycle", "nixdaemon-show kbd-backlight-cycle", locked)
    132 o.bind("XF86Eject", "Eject media", gone("Eject media"), locked)
    133 o.bind("XF86TouchpadToggle", "Toggle touchpad", o.bin .. "/padx toggle --notify", locked)
    134 o.bind("XF86TouchpadOn", "Enable touchpad", o.bin .. "/padx on --notify", locked)
    135 o.bind("XF86TouchpadOff", "Disable touchpad", o.bin .. "/padx off --notify", locked)
    136 o.bind("switch:on:Lid Switch", "Laptop lid closed", o.bin .. "/lid-control close", locked) -- lid.lua rebinds
    137 o.bind("switch:off:Lid Switch", "Laptop lid opened", o.bin .. "/lid-control wake", locked) -- lid.lua rebinds
    138 
    139 -- ── Windows ──────────────────────────────────────────────────────────────────
    140 o.bind("SUPER + W", "Close window", hl.dsp.window.close())
    141 o.bind("CTRL + ALT + DELETE", "Close all windows", function()
    142   for _, w in ipairs(hl.get_windows()) do
    143     hl.dispatch(hl.dsp.window.close({ window = w }))
    144   end
    145 end)
    146 o.bind("SUPER + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
    147 o.bind("CTRL + SUPER + F", "Tiled full screen", hl.dsp.window.fullscreen_state({ internal = 0, client = 2 }))
    148 o.bind("ALT + SUPER + F", "Full width", hl.dsp.window.fullscreen({ mode = "maximized" }))
    149 o.bind("SUPER + T", "Toggle window floating/tiling", hl.dsp.window.float({ action = "toggle" }))
    150 o.bind("SUPER + O", "Pop window out (float & pin)", function()
    151   hl.dispatch(hl.dsp.window.float({ action = "enable" }))
    152   hl.dispatch(hl.dsp.window.pin({ action = "enable" }))
    153 end)
    154 o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo())
    155 o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit"))
    156 o.bind("SUPER + BACKSPACE", "Toggle window transparency", hl.dsp.window.set_prop({ prop = "opaque", value = "toggle" }))
    157 o.bind("CTRL + SUPER + BACKSPACE", "Toggle single-window square aspect", gone("Toggle single-window square aspect"))
    158 
    159 local gaps_on = true
    160 o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", function()
    161   gaps_on = not gaps_on
    162   if gaps_on then
    163     hl.config({ general = { gaps_in = 5, gaps_out = 20 } })
    164   else
    165     hl.config({ general = { gaps_in = 0, gaps_out = 0 } })
    166   end
    167 end)
    168 
    169 local layout = "dwindle"
    170 o.bind("SUPER + L", "Toggle workspace layout", function()
    171   layout = layout == "dwindle" and "master" or "dwindle"
    172   hl.config({ general = { layout = layout } })
    173 end)
    174 
    175 -- Focus, swap, move
    176 o.bind("SUPER + LEFT", "Focus on left window", hl.dsp.focus({ direction = "left" }))
    177 o.bind("SUPER + RIGHT", "Focus on right window", hl.dsp.focus({ direction = "right" }))
    178 o.bind("SUPER + UP", "Focus on above window", hl.dsp.focus({ direction = "up" }))
    179 o.bind("SUPER + DOWN", "Focus on below window", hl.dsp.focus({ direction = "down" }))
    180 o.bind("SUPER + SHIFT + LEFT", "Swap window to the left", hl.dsp.window.swap({ direction = "left" })) -- bindings.lua rebinds
    181 o.bind("SUPER + SHIFT + RIGHT", "Swap window to the right", hl.dsp.window.swap({ direction = "right" }))
    182 o.bind("SUPER + SHIFT + UP", "Swap window up", hl.dsp.window.swap({ direction = "up" }))
    183 o.bind("SUPER + SHIFT + DOWN", "Swap window down", hl.dsp.window.swap({ direction = "down" }))
    184 o.bind("ALT + TAB", "Focus on next window", hl.dsp.window.cycle_next())
    185 o.bind("ALT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top())
    186 o.bind("SHIFT + ALT + TAB", "Focus on previous window", hl.dsp.window.cycle_next({ next = false }))
    187 o.bind("SHIFT + ALT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top())
    188 
    189 -- Resize (keycodes 20/21 = the -/= keys, layout independent, as Omarchy)
    190 o.bind("SUPER + code:20", "Expand window left", resize(-100, 0))
    191 o.bind("SUPER + code:21", "Shrink window left", resize(100, 0))
    192 o.bind("SUPER + SHIFT + code:20", "Shrink window up", resize(0, -100))
    193 o.bind("SUPER + SHIFT + code:21", "Expand window down", resize(0, 100))
    194 o.bind("ALT + SUPER + code:20", "Expand window left a little", resize(-50, 0))
    195 o.bind("ALT + SUPER + code:21", "Shrink window left a little", resize(50, 0))
    196 o.bind("SHIFT + ALT + SUPER + code:20", "Shrink window up a little", resize(0, -50))
    197 o.bind("SHIFT + ALT + SUPER + code:21", "Expand window down a little", resize(0, 50))
    198 o.bind("CTRL + SUPER + code:20", "Expand window left a lot", resize(-200, 0))
    199 o.bind("CTRL + SUPER + code:21", "Shrink window left a lot", resize(200, 0))
    200 o.bind("SHIFT + CTRL + SUPER + code:20", "Shrink window up a lot", resize(0, -200))
    201 o.bind("SHIFT + CTRL + SUPER + code:21", "Expand window down a lot", resize(0, 200))
    202 o.bind("SUPER + Home", "Restore window width", gone("Restore window width", "omarchy window width memory"))
    203 o.bind("ALT + SUPER + Home", "Save window width", gone("Save window width", "omarchy window width memory"))
    204 -- "Make webcam overlay smaller/larger" (ALT+SUPER, keycodes unknown): not carried; Omarchy webcam overlay.
    205 
    206 -- Mouse
    207 o.bind("SUPER + mouse:272", "Move window", hl.dsp.window.drag(), mouse)
    208 o.bind("SUPER + mouse:273", "Resize window", hl.dsp.window.resize(), mouse)
    209 o.bind("SUPER + mouse_down", "Scroll active workspace forward", hl.dsp.focus({ workspace = "e+1" }))
    210 o.bind("SUPER + mouse_up", "Scroll active workspace backward", hl.dsp.focus({ workspace = "e-1" }))
    211 
    212 -- Universal clipboard: terminals get CTRL+SHIFT, everything else CTRL
    213 local terminal_class = "^(kitty|dropterm|Alacritty|foot|org%.codeberg%.dnkl%.foot|com%.mitchellh%.ghostty)$"
    214 local function universal(key)
    215   return function()
    216     local w = hl.get_active_window()
    217     local mods = (w and (w.class or ""):match(terminal_class)) and "CTRL SHIFT" or "CTRL"
    218     hl.dispatch(hl.dsp.send_shortcut({ mods = mods, key = key }))
    219   end
    220 end
    221 o.bind("SUPER + C", "Universal copy", universal("C"))
    222 o.bind("SUPER + V", "Universal paste", universal("V"))
    223 o.bind("SUPER + X", "Universal cut", universal("X"))
    224 
    225 -- ── Workspaces ───────────────────────────────────────────────────────────────
    226 for i = 1, 10 do
    227   local code = "code:" .. (9 + i) -- keycodes 10..19 = keys 1..9,0 (layout independent, as Omarchy)
    228   o.bind("SUPER + " .. code, "Switch to workspace " .. i, hl.dsp.focus({ workspace = i }))
    229   o.bind("SUPER + SHIFT + " .. code, "Move window to workspace " .. i, hl.dsp.window.move({ workspace = i }))
    230   o.bind("SUPER + SHIFT + ALT + " .. code, "Move window silently to workspace " .. i, hl.dsp.window.move({ workspace = i, follow = false }))
    231 end
    232 o.bind("SUPER + TAB", "Next workspace", hl.dsp.focus({ workspace = "e+1" }))
    233 o.bind("SUPER + SHIFT + TAB", "Previous workspace", hl.dsp.focus({ workspace = "e-1" }))
    234 o.bind("CTRL + SUPER + TAB", "Former workspace", hl.dsp.focus({ workspace = "previous" }))
    235 o.bind("SUPER + S", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad"))
    236 o.bind("ALT + SUPER + S", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad" }))
    237 o.bind("CTRL + ALT + TAB", "Focus on next monitor", hl.dsp.focus({ monitor = "+1" }))
    238 o.bind("SHIFT + CTRL + ALT + TAB", "Focus on previous monitor", hl.dsp.focus({ monitor = "-1" }))
    239 o.bind("SHIFT + ALT + SUPER + LEFT", "Move workspace to left monitor", hl.dsp.workspace.move({ monitor = "l" }))
    240 o.bind("SHIFT + ALT + SUPER + RIGHT", "Move workspace to right monitor", hl.dsp.workspace.move({ monitor = "r" }))
    241 o.bind("SHIFT + ALT + SUPER + UP", "Move workspace to up monitor", hl.dsp.workspace.move({ monitor = "u" }))
    242 o.bind("SHIFT + ALT + SUPER + DOWN", "Move workspace to down monitor", hl.dsp.workspace.move({ monitor = "d" }))
    243 
    244 -- ── Groups ───────────────────────────────────────────────────────────────────
    245 o.bind("SUPER + G", "Toggle window grouping", hl.dsp.group.toggle())
    246 o.bind("ALT + SUPER + G", "Move active window out of group", hl.dsp.window.move({ out_of_group = true }))
    247 o.bind("ALT + SUPER + TAB", "Next window in group", hl.dsp.group.next())
    248 o.bind("SHIFT + ALT + SUPER + TAB", "Previous window in group", hl.dsp.group.prev())
    249 o.bind("ALT + SUPER + mouse_down", "Next window in group", hl.dsp.group.next())
    250 o.bind("ALT + SUPER + mouse_up", "Previous window in group", hl.dsp.group.prev())
    251 for i = 1, 5 do
    252   o.bind("ALT + SUPER + code:" .. (9 + i), "Switch to group window " .. i, hl.dsp.group.active({ index = i }))
    253 end
    254 o.bind("CTRL + SUPER + LEFT", "Move grouped window focus left", hl.dsp.group.move_window({ forward = false }))
    255 o.bind("CTRL + SUPER + RIGHT", "Move grouped window focus right", hl.dsp.group.move_window({ forward = true }))
    256 o.bind("ALT + SUPER + LEFT", "Move window to group on left", hl.dsp.window.move({ direction = "left", group_aware = true }))
    257 o.bind("ALT + SUPER + RIGHT", "Move window to group on right", hl.dsp.window.move({ direction = "right", group_aware = true }))
    258 o.bind("ALT + SUPER + UP", "Move window to group on top", hl.dsp.window.move({ direction = "up", group_aware = true }))
    259 o.bind("ALT + SUPER + DOWN", "Move window to group on bottom", hl.dsp.window.move({ direction = "down", group_aware = true }))
    260 
    261 -- ── Monitor scale and zoom ───────────────────────────────────────────────────
    262 local function rescale(delta)
    263   return function()
    264     local m = hl.get_active_monitor()
    265     if not m then return end
    266     local s = math.max(1, (m.scale or 1) + delta)
    267     if m.name == "eDP-1" then
    268       hl.monitor({ output = "eDP-1", mode = "2560x1440@240", position = "0x0", scale = s })
    269     else
    270       hl.monitor({ output = m.name, mode = "preferred", position = "auto", scale = s })
    271     end
    272   end
    273 end
    274 o.bind("SUPER + SLASH", "Monitor scaling up", rescale(0.25))
    275 o.bind("ALT + SUPER + SLASH", "Monitor scaling down", rescale(-0.25))
    276 
    277 local zoom = 1.0
    278 o.bind("CTRL + SUPER + Z", "Zoom in", function()
    279   zoom = zoom + 0.5
    280   hl.config({ cursor = { zoom_factor = zoom } })
    281 end)
    282 o.bind("CTRL + ALT + SUPER + Z", "Reset zoom", function()
    283   zoom = 1.0
    284   hl.config({ cursor = { zoom_factor = 1.0 } })
    285 end)
    286 
    287 -- Laptop display toggles were Omarchy monitor scripts; display recovery is lid.lua's SUPER+CTRL+F12.
    288 o.bind("CTRL + SUPER + Delete", "Toggle laptop display", gone("Toggle laptop display", "omarchy monitor script"))
    289 o.bind("CTRL + ALT + SUPER + Delete", "Toggle laptop display mirroring", gone("Toggle laptop display mirroring", "omarchy monitor script"))