| 1 | --------------------- |
| 2 | ---- KEYBINDINGS ---- |
| 3 | --------------------- |
| 4 | -- See https://wiki.hypr.land/Configuring/Basics/Binds/ for more |
| 5 | |
| 6 | hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal)) |
| 7 | hl.bind(mainMod .. " + SHIFT + X", hl.dsp.window.close()) |
| 8 | hl.bind(mainMod .. " + SHIFT + Q", hl.dsp.exit()) |
| 9 | hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen({ mode = "fullscreen", action = "toggle" })) |
| 10 | hl.bind(mainMod .. " + SHIFT + F", hl.dsp.window.fullscreen({ mode = "maximized", action = "toggle" })) |
| 11 | |
| 12 | -- bind = $mainMod SHIFT, R, togglefloating, |
| 13 | -- Smart Float: Toggle float -> Resize to 90% -> Center |
| 14 | hl.bind( |
| 15 | mainMod .. "+ SHIFT + R", |
| 16 | hl.dsp.exec_cmd([[ |
| 17 | if hyprctl activewindow | grep -q 'floating: 0'; then |
| 18 | W=$(hyprctl monitors -j | jq '.[] | select(.focused) | ((.width / .scale) * 0.9) | floor') |
| 19 | H=$(hyprctl monitors -j | jq '.[] | select(.focused) | ((.height / .scale) * 0.9) | floor') |
| 20 | hyprctl --batch "dispatch hl.dsp.window.float({action='set'}); dispatch hl.dsp.window.resize({x=${W}, y=${H}, relative=false})" |
| 21 | hyprctl dispatch "hl.dsp.window.center()" |
| 22 | else |
| 23 | hyprctl dispatch "hl.dsp.window.float({action='unset'})" |
| 24 | fi |
| 25 | ]]), |
| 26 | { description = "Smart Float" } |
| 27 | ) |
| 28 | |
| 29 | ------------------ |
| 30 | -- Aurora Shell |
| 31 | ----------------- |
| 32 | hl.bind(mainMod .. " + c", hl.dsp.exec_cmd("qs -c aurora ipc call shell toggle")) |
| 33 | hl.bind(mainMod .. " + b", hl.dsp.exec_cmd("qs -c aurora ipc call shell bar")) |
| 34 | hl.bind(mainMod .. " + SHIFT + b", hl.dsp.exec_cmd("systemctl --user restart aurora-shell")) |
| 35 | |
| 36 | hl.bind(mainMod .. " + R", hl.dsp.exec_cmd(menu)) |
| 37 | -- bind = $mainMod SHIFT, P, pseudo, # dwindle |
| 38 | hl.bind(mainMod .. " + Tab", hl.dsp.window.cycle_next({ next = false }), { repeating = true }) |
| 39 | hl.bind(mainMod .. " + SHIFT + Tab", hl.dsp.exec_cmd("qs -c aurora ipc call shell overview"), { description = "workspace overview" }) |
| 40 | hl.bind(mainMod .. " + grave", hl.dsp.exec_cmd("qs -c aurora ipc call shell chars"), { description = "glyph picker" }) |
| 41 | hl.bind(mainMod .. " + escape", hl.dsp.exec_cmd("qs -c aurora ipc call shell power")) |
| 42 | hl.bind(mainMod .. " + I", hl.dsp.exec_cmd("qs -c aurora ipc call shell settings ''"), { description = "aurora settings" }) |
| 43 | |
| 44 | -- Applications |
| 45 | hl.bind(mainMod .. " + W", hl.dsp.exec_cmd(browser)) |
| 46 | hl.bind("PRINT", hl.dsp.exec_cmd("qs -c aurora ipc call shell shot region"), { description = "screenshot" }) |
| 47 | hl.bind(mainMod .. " + SHIFT + P", hl.dsp.exec_cmd("qs -c aurora ipc call shell shot region"), { description = "screenshot" }) |
| 48 | hl.bind("SHIFT + PRINT", hl.dsp.exec_cmd("ocr"), { description = "ocr a region" }) |
| 49 | hl.bind(mainMod .. " + SHIFT + O", hl.dsp.exec_cmd("ocr"), { description = "ocr a region" }) |
| 50 | |
| 51 | -- Music Controls |
| 52 | hl.bind(mainMod .. " + m", hl.dsp.exec_cmd(terminal .. " -e zsh -i -c \"rmptui\"")) |
| 53 | hl.bind(mainMod .. " + SHIFT + m", hl.dsp.exec_cmd("madd </dev/null")) -- stdin is tty1 otherwise: madd would pick fzf |
| 54 | hl.bind(mainMod .. " + p", hl.dsp.exec_cmd("mpc toggle")) |
| 55 | hl.bind(mainMod .. " + period", hl.dsp.exec_cmd("mpc seek +10"), { repeating = true }) |
| 56 | hl.bind(mainMod .. " + comma", hl.dsp.exec_cmd("mpc seek -10"), { repeating = true }) |
| 57 | hl.bind(mainMod .. " + SHIFT + period", hl.dsp.exec_cmd("mpc next")) |
| 58 | hl.bind(mainMod .. " + SHIFT + comma", hl.dsp.exec_cmd("mpc prev")) |
| 59 | |
| 60 | -- Swap current focused window with master |
| 61 | hl.bind(mainMod .. " + space", hl.dsp.layout("swapwithmaster")) |
| 62 | |
| 63 | -- Resize windows with h/j/k/l |
| 64 | hl.bind(mainMod .. " + h", hl.dsp.window.resize({ x = -30, y = 0, relative = true}), { repeating = true }) |
| 65 | hl.bind(mainMod .. " + l", hl.dsp.window.resize({ x = 30, y = 0, relative = true}), { repeating = true }) |
| 66 | hl.bind(mainMod .. " + k", hl.dsp.window.resize({ x = 0, y = -30, relative = true }), { repeating = true }) |
| 67 | hl.bind(mainMod .. " + j", hl.dsp.window.resize({ x = 0, y = 30, relative = true }), { repeating = true }) |
| 68 | |
| 69 | -- Clipboard menu (cliphist) |
| 70 | hl.bind(mainMod .. " + v", hl.dsp.exec_cmd("qs -c aurora ipc call shell clip")) |
| 71 | |
| 72 | -- ----------------------------------------------------- |
| 73 | -- Workspace switching |
| 74 | -- ----------------------------------------------------- |
| 75 | |
| 76 | local mainMod = "SUPER" |
| 77 | for i = 1, smw.get_amount_of_workspaces() do |
| 78 | local n = tostring(i) |
| 79 | if n == "10" then n = "0" end -- Optional if you configured 10 workspaces: bind workspace 10 to SUPER + 0 |
| 80 | -- Switch to the Nth workspace on the currently focused monitor. |
| 81 | hl.bind(mainMod .. " +" .. n, smw.workspace(n)) |
| 82 | -- Move the active window to the Nth workspace on the currently focused monitor silently (no focus change). |
| 83 | hl.bind(mainMod .. " + SHIFT +" .. n, smw.move_to_workspace_silent(n)) |
| 84 | end |
| 85 | |
| 86 | -- dwm focusmon/tagmon: focus the previous/next monitor, or send the window to its visible workspace (focus stays) |
| 87 | local function tagmon(dir) |
| 88 | return function() |
| 89 | local mons = hl.get_monitors() |
| 90 | local cur = hl.get_active_monitor() |
| 91 | if #mons < 2 or not cur then return end |
| 92 | table.sort(mons, function(a, b) return a.id < b.id end) |
| 93 | for i, m in ipairs(mons) do |
| 94 | if m.id == cur.id then |
| 95 | local target = mons[(i - 1 + dir) % #mons + 1] |
| 96 | if target.active_workspace then |
| 97 | hl.dispatch(hl.dsp.window.move({ workspace = tostring(target.active_workspace.id), follow = false })) |
| 98 | end |
| 99 | return |
| 100 | end |
| 101 | end |
| 102 | end |
| 103 | end |
| 104 | hl.bind(mainMod .. " + Left", hl.dsp.focus({ monitor = "-1" })) |
| 105 | hl.bind(mainMod .. " + Right", hl.dsp.focus({ monitor = "+1" })) |
| 106 | hl.bind(mainMod .. " + SHIFT + Left", tagmon(-1)) |
| 107 | hl.bind(mainMod .. " + SHIFT + Right", tagmon(1)) |
| 108 | |
| 109 | -- Example special workspace (scratchpad) |
| 110 | hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic")) |
| 111 | hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" })) |
| 112 | |
| 113 | -- Scratchpad like DWM |
| 114 | hl.workspace_rule({ workspace = "special:h", on_created_empty = terminal }) |
| 115 | hl.bind(mainMod .. " + SHIFT + Return", hl.dsp.workspace.toggle_special("h")) |
| 116 | |
| 117 | -- --- Accessibility: Zoom --- |
| 118 | hl.config({ cursor = { zoom_disable_aa = true } }) |
| 119 | |
| 120 | hl.bind( |
| 121 | "SUPER + equal", |
| 122 | function() |
| 123 | local z = hl.get_config("cursor.zoom_factor") |
| 124 | hl.config({ cursor = { zoom_factor = z * 1.25 } }) |
| 125 | end, |
| 126 | { description = "Zoom In", repeating = true } |
| 127 | ) |
| 128 | |
| 129 | hl.bind( |
| 130 | "SUPER + minus", |
| 131 | function() |
| 132 | local z = hl.get_config("cursor.zoom_factor") |
| 133 | local nz = z / 1.25 |
| 134 | if nz < 1.0 then nz = 1.0 end |
| 135 | hl.config({ cursor = { zoom_factor = nz } }) |
| 136 | end, |
| 137 | { description = "Zoom Out", repeating = true } |
| 138 | ) |
| 139 | |
| 140 | hl.bind( |
| 141 | "SUPER + BACKSPACE", |
| 142 | function() |
| 143 | hl.config({ cursor = { zoom_factor = 1.0 } }) |
| 144 | end, |
| 145 | { description = "Reset Zoom", locked = true } |
| 146 | ) |
| 147 | |
| 148 | -- Screen Rotate |
| 149 | hl.bind(mainMod .. " + CTRL + comma", hl.dsp.exec_cmd("hypr_screen_rotate.py +90"), |
| 150 | { locked = true, desc = "Rotate Screen Anti-Clockwise" }) |
| 151 | hl.bind(mainMod .. " + CTRL + period", hl.dsp.exec_cmd("hypr_screen_rotate.py -90"), |
| 152 | { locked = true, desc = "Rotate Screen Clockwise" }) |
| 153 | |
| 154 | -- Scroll through existing workspaces with mainMod + scroll |
| 155 | hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) |
| 156 | hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) |
| 157 | |
| 158 | -- Move/resize windows with mainMod + LMB/RMB and dragging |
| 159 | hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) |
| 160 | hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) |
| 161 | |
| 162 | -- mainMod + MMB drag: float a tiled window and move it, like dwm |
| 163 | -- (follow_mouse = 1, so the active window is the one under the cursor) |
| 164 | hl.bind(mainMod .. " + mouse:274", function() |
| 165 | local w = hl.get_active_window() |
| 166 | if w and not w.floating then hl.dispatch(hl.dsp.window.float({ action = "set" })) end |
| 167 | end, { non_consuming = true }) |
| 168 | hl.bind(mainMod .. " + mouse:274", hl.dsp.window.drag(), { mouse = true }) |
| 169 | |
| 170 | -- Laptop multimedia keys for volume and LCD brightness (brightness goes through aurora for the OSD; it runs ~/.local/bin/brictl) |
| 171 | hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true }) |
| 172 | hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true }) |
| 173 | hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true }) |
| 174 | hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true }) |
| 175 | hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("qs -c aurora ipc call shell bright down"), { locked = true, repeating = true }) |
| 176 | hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("qs -c aurora ipc call shell bright up"), { locked = true, repeating = true }) |
| 177 | |
| 178 | -- Requires playerctl |
| 179 | hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true }) |
| 180 | hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) |
| 181 | hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) |
| 182 | hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) |
| 183 | |