-- https://wiki.hypr.land/Configuring/Basics/Binds/ local mainMod = "SUPER" local terminal = "kitty" local fileManager = "thunar" local editor = "kitty nvim" local menu = "vicinae toggle" local winswitch = "" -- TODO: define your window switcher command -- Screen-absolute focus/move wrapper. In the scrolling/columns layouts, Hyprland -- resolves a direction perpendicular to the tape onto "scroll the tape", so the same -- key means different things depending on scrolling:direction. hypr-nav keeps every -- key literal to its on-screen direction (and is a pass-through for dwindle/master). local nav = "~/.config/scripts/hypr-nav" -------------------- ---- LID SWITCH ---- -------------------- hl.bind("switch:on:Lid Switch", hl.dsp.exec_cmd("hyprlock"), { locked = true }) hl.bind("switch:off:Lid Switch", hl.dsp.exec_cmd("hyprctl dispatch dpms on"), { locked = true }) -------------------- ---- GESTURES ------ -------------------- hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" }) hl.gesture({ fingers = 3, direction = "up", action = function() hl.dispatch(hl.dsp.window.move({ workspace = "special:magic", silent = true })) end }) hl.gesture({ fingers = 3, direction = "down", action = "special", workspace_name = "magic" }) hl.gesture({ fingers = 3, direction = "pinchin", action = function() hl.dispatch(hl.dsp.exec_cmd(menu)) end }) hl.gesture({ fingers = 3, direction = "pinchout", action = "float" }) hl.gesture({ fingers = 4, direction = "pinchout", action = "close" }) hl.gesture({ fingers = 4, direction = "pinchin", action = function() hl.dispatch(hl.dsp.exec_cmd(terminal)) end }) hl.gesture({ fingers = 4, direction = "down", action = function() hl.dispatch(hl.dsp.window.move({ workspace = "special:magic" })) end }) hl.gesture({ fingers = 4, direction = "up", action = function() hl.dispatch(hl.dsp.window.move({ workspace = "r+0" })) end }) hl.gesture({ fingers = 4, direction = "left", action = function() hl.dispatch(hl.dsp.window.move({ workspace = "r+1" })) end }) hl.gesture({ fingers = 4, direction = "right", action = function() hl.dispatch(hl.dsp.window.move({ workspace = "r-1" })) end }) -------------------- ---- APPS ---------- -------------------- hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(terminal)) hl.bind(mainMod .. " + SHIFT + T", hl.dsp.exec_cmd("cool-retro-term -p ~/Dotfiles/desktopenvs/hyprlua/CRT")) hl.bind(mainMod .. " + M", hl.dsp.exec_cmd(editor)) hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(fileManager)) hl.bind(mainMod .. " + ALT + E", hl.dsp.exec_cmd("pcmanfm-qt")) hl.bind(mainMod .. " + X", hl.dsp.exec_cmd("wofi --show=run")) hl.bind(mainMod .. " + N", hl.dsp.exec_cmd("nextcloud")) hl.bind(mainMod .. " + I", hl.dsp.exec_cmd("iwmenu --launcher walker")) hl.bind(mainMod .. " + ALT + I", hl.dsp.exec_cmd("bzmenu --launcher walker")) hl.bind(mainMod .. " + SHIFT + I", hl.dsp.exec_cmd("[tag +mixer] nm-connection-editor")) hl.bind(mainMod .. " + R", hl.dsp.exec_cmd(menu)) hl.bind(mainMod .. " + RETURN", hl.dsp.exec_cmd(menu)) hl.bind(mainMod .. " + SHIFT + RETURN", hl.dsp.exec_cmd(winswitch)) hl.bind(mainMod .. " + SHIFT + R", hl.dsp.exec_cmd("wofi --show drun")) hl.bind("CTRL + SHIFT + R", hl.dsp.exec_cmd(menu)) -- File picker dialog -> clipboard (path / contents) hl.bind(mainMod .. " + F", hl.dsp.exec_cmd("[tag +filepicker] ~/.config/scripts/filepicker-clipboard.sh path")) hl.bind(mainMod .. " + SHIFT + F", hl.dsp.exec_cmd("[tag +filepicker] ~/.config/scripts/filepicker-clipboard.sh content")) -- old: -- hl.bind(mainMod .. " + F", hl.dsp.exec_cmd("~/.config/scripts/wofi-file-search.sh")) -- hl.bind(mainMod .. " + SHIFT + F", hl.dsp.exec_cmd("~/.config/scripts/foldersearch.sh")) hl.bind(mainMod .. " + ALT + F", hl.dsp.exec_cmd("wofi-calc")) hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("[tag +mixer] pavucontrol")) hl.bind(mainMod .. " + U", hl.dsp.exec_cmd("[tag +centered-L] kitty btop")) hl.bind(mainMod .. " + W", hl.dsp.exec_cmd("[tag +centered-L] kitty -e ~/.config/scripts/wallpaper-picker ~/Pictures")) hl.bind(mainMod .. " + SHIFT + M", hl.dsp.exec_cmd("[tag +centered-L] kitty -e ~/.config/scripts/monitor-manager")) hl.bind(mainMod .. " + CTRL + R", hl.dsp.exec_cmd("[tag +centered-L] kitty -e ~/.config/scripts/amssh")) hl.bind(mainMod .. " + F1", hl.dsp.exec_cmd("[tag +centered] kitty ~/.config/scripts/helpmenu.sh")) hl.bind(mainMod .. " + CTRL + T", hl.dsp.exec_cmd("[tag +centered-S] kitty bash ~/.config/scripts/timer-pick")) hl.bind(mainMod .. " + SHIFT + F1", hl.dsp.exec_cmd("[tag +centered-L] kitty nvim ~/.config/hypr/usr/binds.lua")) hl.bind(mainMod .. " + CTRL + P", hl.dsp.exec_cmd("~/.config/scripts/screenrec.sh")) -------------------- ---- WINDOW MGMT --- -------------------- hl.bind(mainMod .. " + Q", hl.dsp.window.close()) hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" })) hl.bind(mainMod .. " + C", hl.dsp.window.pseudo()) hl.bind(mainMod .. " + SHIFT + V", hl.dsp.window.tag({ tag = "+centered" })) hl.bind(mainMod .. " + SHIFT + Q", hl.dsp.exec_cmd("hyprctl kill")) hl.bind(mainMod .. " + CTRL + M", hl.dsp.exec_cmd("~/.config/scripts/toggle-layout.sh")) -- lock/exit — hyprshutdown gracefully closes every app (with a UI) before it exits -- Hyprland and runs its --post-cmd, instead of yanking the session out from under them. -- orbit-menu wraps hyprshutdown behind the radial menu: Shift+O opens straight into -- the Power ring (sleep/reboot/poweroff/soft-reboot); Ctrl+O opens the full 5-category -- menu (Power/Tools/Scripts/Management/Windows). Re-press to close. hl.bind(mainMod .. " + O", hl.dsp.exec_cmd("hyprlock")) hl.bind(mainMod .. " + SHIFT + O", hl.dsp.exec_cmd("~/.config/scripts/orbit-menu.sh power")) hl.bind(mainMod .. " + CTRL + O", hl.dsp.exec_cmd("~/.config/scripts/orbit-menu.sh menu")) hl.bind(mainMod .. " + CTRL + SHIFT + O",hl.dsp.exec_cmd('hyprshutdown -p "systemctl reboot"')) -- graceful reboot hl.bind(mainMod .. " + ALT + O", hl.dsp.exec_cmd("~/.config/scripts/pwr-dmenu.sh")) hl.bind(mainMod .. " + ALT + CTRL + SHIFT + END", hl.dsp.exit()) -- bar / ui hl.bind(mainMod .. " + Z", hl.dsp.exec_cmd("~/.config/scripts/togglebar.sh")) hl.bind(mainMod .. " + CTRL + B", hl.dsp.exec_cmd("eww reload")) -------------------- ---- FOCUS --------- -------------------- hl.bind(mainMod .. " + h", hl.dsp.exec_cmd(nav .. " focus l")) hl.bind(mainMod .. " + l", hl.dsp.exec_cmd(nav .. " focus r")) hl.bind(mainMod .. " + k", hl.dsp.exec_cmd(nav .. " focus u")) hl.bind(mainMod .. " + j", hl.dsp.exec_cmd(nav .. " focus d")) hl.bind(mainMod .. " + left", hl.dsp.exec_cmd(nav .. " focus l")) hl.bind(mainMod .. " + right", hl.dsp.exec_cmd(nav .. " focus r")) hl.bind(mainMod .. " + up", hl.dsp.exec_cmd(nav .. " focus u")) hl.bind(mainMod .. " + down", hl.dsp.exec_cmd(nav .. " focus d")) hl.bind(mainMod .. " + TAB", hl.dsp.window.cycle_next()) hl.bind(mainMod .. " + SHIFT + TAB", hl.dsp.exec_cmd(winswitch)) -------------------- ---- MOVE WINDOW --- -------------------- hl.bind(mainMod .. " + SHIFT + left", hl.dsp.exec_cmd(nav .. " move l")) hl.bind(mainMod .. " + SHIFT + right", hl.dsp.exec_cmd(nav .. " move r")) hl.bind(mainMod .. " + SHIFT + up", hl.dsp.exec_cmd(nav .. " move u")) hl.bind(mainMod .. " + SHIFT + down", hl.dsp.exec_cmd(nav .. " move d")) hl.bind(mainMod .. " + SHIFT + h", hl.dsp.exec_cmd(nav .. " move l")) hl.bind(mainMod .. " + SHIFT + l", hl.dsp.exec_cmd(nav .. " move r")) hl.bind(mainMod .. " + SHIFT + k", hl.dsp.exec_cmd(nav .. " move u")) hl.bind(mainMod .. " + SHIFT + j", hl.dsp.exec_cmd(nav .. " move d")) -- Columns layout: manage how many columns / windows-per-view (no-op in other layouts). -- Horizontal ws: H/L = fewer/more columns, K/J = fewer/more windows-per-view. -- Vertical ws: K/J = fewer/more columns, H/L = fewer/more windows-per-view. hl.bind(mainMod .. " + CTRL + ALT + h", hl.dsp.exec_cmd(nav .. " count h")) hl.bind(mainMod .. " + CTRL + ALT + l", hl.dsp.exec_cmd(nav .. " count l")) hl.bind(mainMod .. " + CTRL + ALT + k", hl.dsp.exec_cmd(nav .. " count k")) hl.bind(mainMod .. " + CTRL + ALT + j", hl.dsp.exec_cmd(nav .. " count j")) -- cross-monitor: focus / move the active window to the previous/next monitor. -- Works in every layout (including scrolling, where the directional keys deliberately -- do NOT jump monitors — see hypr-nav). +1/-1 cycle through the monitors. hl.bind(mainMod .. " + comma", hl.dsp.focus({ monitor = "-1" })) hl.bind(mainMod .. " + period", hl.dsp.focus({ monitor = "+1" })) hl.bind(mainMod .. " + SHIFT + comma", hl.dsp.window.move({ monitor = "-1" })) hl.bind(mainMod .. " + SHIFT + period", hl.dsp.window.move({ monitor = "+1" })) -- mouse drag / resize hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) -- Super+rightclick resize. The custom Columns layout gives no mouse-resize hook, so ONLY -- there the window is floated first (enable is a no-op if already floating) so it can be -- mouse-dragged; re-tile afterwards with Super+V. In every other layout it's a plain -- interactive resize, untouched. (Keyboard resize that stays tiled: Super+Alt + hjkl.) local function active_ws_is_columns() local ok, aw = pcall(hl.get_active_window) if not ok or not aw then return false end local wid pcall(function() wid = aw.workspace.id end) if not wid then return false end local f = io.open((os.getenv("HOME") or "") .. "/.cache/astal-menu/layouts-state.json", "r") if not f then return false end local data = f:read("*a") or ""; f:close() return data:match('"' .. tostring(wid) .. '"%s*:%s*"([^"]+)"') == "columns" end hl.bind(mainMod .. " + mouse:273", function() if active_ws_is_columns() then hl.dispatch(hl.dsp.window.float({ action = "enable" })) end hl.dispatch(hl.dsp.window.resize()) end, { mouse = true }) hl.bind(mainMod .. " + SHIFT + mouse:272", hl.dsp.window.resize(), { mouse = true }) -------------------- ---- RESIZE -------- -------------------- -- Routed through hypr-nav: in the Columns layout ALT-resize retunes the focused -- column's width / window's height (weights); everywhere else it's a plain screen- -- relative resize, exactly as before. l/h narrower, r/l wider, k/up shorter, j/down taller. hl.bind(mainMod .. " + ALT + right", hl.dsp.exec_cmd(nav .. " resize r"), { repeating = true }) hl.bind(mainMod .. " + ALT + left", hl.dsp.exec_cmd(nav .. " resize l"), { repeating = true }) hl.bind(mainMod .. " + ALT + up", hl.dsp.exec_cmd(nav .. " resize u"), { repeating = true }) hl.bind(mainMod .. " + ALT + down", hl.dsp.exec_cmd(nav .. " resize d"), { repeating = true }) hl.bind(mainMod .. " + ALT + l", hl.dsp.exec_cmd(nav .. " resize r"), { repeating = true }) hl.bind(mainMod .. " + ALT + h", hl.dsp.exec_cmd(nav .. " resize l"), { repeating = true }) hl.bind(mainMod .. " + ALT + k", hl.dsp.exec_cmd(nav .. " resize u"), { repeating = true }) hl.bind(mainMod .. " + ALT + j", hl.dsp.exec_cmd(nav .. " resize d"), { repeating = true }) -------------------- ---- WORKSPACES ---- -------------------- for i = 1, 9 do hl.bind(mainMod .. " + " .. i, hl.dsp.focus({ workspace = i })) hl.bind(mainMod .. " + SHIFT + " .. i, hl.dsp.window.move({ workspace = i })) end hl.bind(mainMod .. " + 0", hl.dsp.focus({ workspace = 10 })) hl.bind(mainMod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = 10 })) -- relative workspace nav — arrows hl.bind(mainMod .. " + CTRL + right", hl.dsp.focus({ workspace = "r+1" })) hl.bind(mainMod .. " + CTRL + left", hl.dsp.focus({ workspace = "r-1" })) hl.bind(mainMod .. " + CTRL + SHIFT + right", hl.dsp.window.move({ workspace = "r+1" })) hl.bind(mainMod .. " + CTRL + SHIFT + left", hl.dsp.window.move({ workspace = "r-1" })) -- relative workspace nav — vim hl.bind(mainMod .. " + CTRL + l", hl.dsp.focus({ workspace = "r+1" })) hl.bind(mainMod .. " + CTRL + h", hl.dsp.focus({ workspace = "r-1" })) hl.bind(mainMod .. " + CTRL + SHIFT + l", hl.dsp.window.move({ workspace = "r+1" })) hl.bind(mainMod .. " + CTRL + SHIFT + h", hl.dsp.window.move({ workspace = "r-1" })) -- Super + wheel: travel along the focused strip in the scrolling/columns layouts -- (next/prev window in the tape or focused column); falls back to switching workspaces -- in every other layout — see hypr-nav. hl.bind(mainMod .. " + mouse_down", hl.dsp.exec_cmd(nav .. " scroll d")) hl.bind(mainMod .. " + mouse_up", hl.dsp.exec_cmd(nav .. " scroll u")) -- volume keys as workspace nav (when mainMod held) hl.bind(mainMod .. " + XF86AudioRaiseVolume", hl.dsp.focus({ workspace = "r+1" }), { repeating = true }) hl.bind(mainMod .. " + XF86AudioLowerVolume", hl.dsp.focus({ workspace = "r-1" }), { repeating = true }) hl.bind(mainMod .. " + SHIFT + XF86AudioRaiseVolume", hl.dsp.window.move({ workspace = "r+1" })) hl.bind(mainMod .. " + SHIFT + XF86AudioLowerVolume", hl.dsp.window.move({ workspace = "r-1" })) -------------------- ---- SCRATCHPAD ---- -------------------- hl.bind(mainMod .. " + SPACE", hl.dsp.workspace.toggle_special("magic")) hl.bind(mainMod .. " + SHIFT + SPACE", hl.dsp.window.move({ workspace = "special:magic" })) hl.bind(mainMod .. " + CTRL + up", hl.dsp.workspace.toggle_special("magic")) hl.bind(mainMod .. " + CTRL + SHIFT + up", hl.dsp.window.move({ workspace = "special:magic" })) hl.bind(mainMod .. " + CTRL + SHIFT + down", hl.dsp.window.move({ workspace = "empty" })) hl.bind(mainMod .. " + CTRL + down", hl.dsp.window.move({ workspace = "special:magic", silent = true })) hl.bind(mainMod .. " + CTRL + k", hl.dsp.workspace.toggle_special("magic")) hl.bind(mainMod .. " + CTRL + j", hl.dsp.window.move({ workspace = "special:magic", silent = true })) hl.bind(mainMod .. " + CTRL + SHIFT + j", hl.dsp.window.move({ workspace = "r+0" })) hl.bind(mainMod .. " + CTRL + SHIFT + k", hl.dsp.window.move({ workspace = "special:magic" })) hl.bind(mainMod .. " + XF86AudioMute", hl.dsp.workspace.toggle_special("magic"), { repeating = true }) hl.bind(mainMod .. " + SHIFT + XF86AudioMute", hl.dsp.window.move({ workspace = "special:magic" }), { repeating = true }) -------------------- ---- GROUPS -------- -------------------- hl.bind(mainMod .. " + ALT + C", hl.dsp.group.toggle()) -- TODO: verify hl.dsp.group API hl.bind(mainMod .. " + CTRL + SHIFT + C", hl.dsp.group.lock_active("toggle")) hl.bind(mainMod .. " + A", hl.dsp.exec_cmd("hyprctl dispatch changegroupactive f")) hl.bind(mainMod .. " + Y", hl.dsp.exec_cmd("hyprctl dispatch changegroupactive b")) hl.bind(mainMod .. " + SHIFT + ALT + left", hl.dsp.group.move_window("l")) hl.bind(mainMod .. " + SHIFT + ALT + right", hl.dsp.group.move_window("r")) hl.bind(mainMod .. " + SHIFT + ALT + up", hl.dsp.group.move_window("u")) hl.bind(mainMod .. " + SHIFT + ALT + down", hl.dsp.group.move_window("d")) hl.bind(mainMod .. " + SHIFT + ALT + h", hl.dsp.group.move_window("l")) hl.bind(mainMod .. " + SHIFT + ALT + l", hl.dsp.group.move_window("r")) hl.bind(mainMod .. " + SHIFT + ALT + k", hl.dsp.group.move_window("u")) hl.bind(mainMod .. " + SHIFT + ALT + j", hl.dsp.group.move_window("d")) -------------------- ---- ASTAL-MENU ---- -------------------- hl.bind(mainMod .. " + D", hl.dsp.exec_cmd("~/.config/scripts/menu-toggle.sh toggle top"), { release = true }) hl.bind(mainMod .. " + SHIFT + A", hl.dsp.exec_cmd("~/.config/scripts/menu-toggle.sh appdrawer")) -------------------- ---- SCREENSHOT ---- -------------------- hl.bind("Print", hl.dsp.exec_cmd("~/.config/scripts/screenshot.sh")) hl.bind(mainMod .. " + P", hl.dsp.exec_cmd("~/.config/scripts/screenshot.sh")) hl.bind(mainMod .. " + SHIFT + P", hl.dsp.exec_cmd("hyprpicker | wl-copy")) hl.bind(mainMod .. " + CTRL + P", hl.dsp.exec_cmd("~/.config/scripts/screenrec.sh")) -------------------- ---- AUDIO --------- -------------------- hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%+"), { repeating = true }) hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1.4 @DEFAULT_AUDIO_SINK@ 5%-"), { repeating = true }) hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle")) hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle")) hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause -p spotify,vlc"), { locked = true }) -------------------- ---- BRIGHTNESS ---- -------------------- hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("bri --up"), { locked = true, repeating = true }) hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("bri --down"), { locked = true, repeating = true }) -------------------- ---- HYPRSUNSET ---- -------------------- hl.bind(mainMod .. " + CTRL + W", hl.dsp.exec_cmd("hyprctl hyprsunset gamma +10")) hl.bind(mainMod .. " + CTRL + S", hl.dsp.exec_cmd("hyprctl hyprsunset gamma -10")) hl.bind(mainMod .. " + CTRL + A", hl.dsp.exec_cmd("hyprctl hyprsunset temperature +450")) hl.bind(mainMod .. " + CTRL + Q", hl.dsp.exec_cmd("hyprctl hyprsunset temperature -450")) hl.bind(mainMod .. " + CTRL + X", hl.dsp.exec_cmd("hyprctl hyprsunset identity")) -------------------- ---- MISC ---------- -------------------- hl.bind(mainMod .. " + CTRL + I", hl.dsp.exec_cmd("chamel toggle")) hl.bind(mainMod .. " + CTRL + U", hl.dsp.exec_cmd("chamel clear")) hl.bind(mainMod .. " + CTRL + Z", hl.dsp.exec_cmd("chamel clear-and-deactivate")) hl.bind(mainMod .. " + CTRL + C", hl.dsp.exec_cmd("dunstctl close-all")) hl.bind(mainMod .. " + CTRL + G", hl.dsp.exec_cmd("~/.config/scripts/onscreenkb.sh")) hl.bind(mainMod .. " + SHIFT + C", hl.dsp.exec_cmd("~/.config/scripts/caffeine.sh")) hl.bind(mainMod .. " + SHIFT + B", hl.dsp.exec_cmd("[tag +centered-S] kitty bash ~/.config/scripts/enroll-biometrics.sh")) hl.bind(mainMod .. " + SHIFT + X", hl.dsp.exec_cmd("~/.config/scripts/hyprland-toggle-touchpad.sh")) hl.bind(mainMod .. " + CTRL + E", hl.dsp.exec_cmd("~/.config/scripts/screenrotationwcw.sh")) hl.bind(mainMod .. " + CTRL + D", hl.dsp.exec_cmd("~/.config/scripts/screenrotationacw.sh"))