require 'helpers' -- ========================== -- Media -- ========================== -- Only display the OSD on the currently focused monitor local osdclient = 'swayosd-client --monitor "$(hyprctl monitors -j | jq -r \'.[] | select(.focused == true).name\')"' -- Laptop multimedia keys for volume and LCD brightness (with OSD) bindlr( 'XF86AudioRaiseVolume', dispatch_exec(osdclient .. ' --output-volume raise'), 'Volume up' ) bindlr( 'XF86AudioRaiseVolume', dispatch_exec(osdclient .. ' --output-volume raise'), 'Volume up' ) bindlr( 'XF86AudioLowerVolume', dispatch_exec(osdclient .. ' --output-volume lower'), 'Volume down' ) bindlr( 'XF86AudioMute', dispatch_exec(osdclient .. ' --output-volume mute-toggle'), 'Mute' ) bindlr( 'XF86AudioMicMute', dispatch_exec(osdclient .. ' --input-volume mute-toggle'), 'Mute microphone' ) bindlr( 'XF86MonBrightnessUp', dispatch_exec 'station-brightness-display +5%', 'Brightness up' ) bindlr( 'XF86MonBrightnessDown', dispatch_exec 'station-brightness-display 5%-', 'Brightness down' ) bindlr( 'XF86KbdBrightnessUp', dispatch_exec 'station-brightness-keyboard up', 'Keyboard brightness up' ) bindlr( 'XF86KbdBrightnessDown', dispatch_exec 'station-brightness-keyboard down', 'Keyboard brightness down' ) bindl( 'XF86KbdLightOnOff', dispatch_exec 'station-brightness-keyboard cycle', 'Keyboard backlight cycle' ) -- Precise 1% multimedia adjustments with Alt modifier bindlr( 'ALT + XF86AudioRaiseVolume', dispatch_exec '$osdclient --output-volume +1', 'Volume up precise' ) bindlr( 'ALT + XF86AudioLowerVolume', dispatch_exec '$osdclient --output-volume -1', 'Volume down precise' ) bindlr( 'ALT + XF86MonBrightnessUp', dispatch_exec 'station-brightness-display +1%', 'Brightness up precise' ) bindlr( 'ALT + XF86MonBrightnessDown', dispatch_exec 'station-brightness-display 1%-', 'Brightness down precise' ) -- Requires playerctl bindl( 'XF86AudioNext', dispatch_exec(osdclient .. ' --playerctl next'), 'Next track' ) bindl( 'XF86AudioPause', dispatch_exec(osdclient .. ' --playerctl play-pause'), 'Pause' ) bindl( 'XF86AudioPlay', dispatch_exec(osdclient .. ' --playerctl play-pause'), 'Play' ) bindl( 'XF86AudioPrev', dispatch_exec(osdclient .. ' --playerctl previous'), 'Previous track' ) -- Switch audio output with Super + Mute bindl( 'SUPER + XF86AudioMute', dispatch_exec 'station-cmd-audio-switch', 'Switch audio output' ) -- ========================== -- Copy & Paste -- ========================== bind('SUPER + C', shortcut { mods = 'CTRL', key = 'Insert' }, 'Universal copy') bind( 'SUPER + V', shortcut { mods = 'SHIFT', key = 'Insert' }, 'Universal paste' ) bind('SUPER + X', shortcut { mods = 'CRTL', key = 'X' }, 'Universal cut') bind('SUPER + A', shortcut { mods = 'CTRL', key = 'A' }, 'Universal cut') bind( 'SUPER + CTRL + V', dispatch_exec 'station-launch-walker -m clipboard', 'Clipboard manager' ) -- Close windows bind('SUPER + Q', hl.dsp.window.close(), 'Close window') -- ========================== -- Tiling -- ========================== bind('SUPER + P', hl.dsp.window.pseudo()--[[# dwindle]], 'Pseudo window') bind('SUPER + F', hl.dsp.window.fullscreen(0), 'Full screen') bind('SUPER + CTRL + F', hl.dsp.window.fullscreen(1), 'Full width') bind('SUPER + T', function() local width = 1300 local height = 900 local pinned = hl.get_active_window().pinned if pinned then hl.dispatch(hl.dsp.window.pin()) hl.dispatch(hl.dsp.window.float { action = 'toggle' }) hl.dispatch(hl.dsp.window.tag { tag = '-pop' }) else hl.dispatch(hl.dsp.window.float { action = 'toggle' }) hl.dispatch(hl.dsp.window.resize { x = width, y = height }) hl.dispatch(hl.dsp.window.center()) hl.dispatch(hl.dsp.window.pin()) hl.dispatch(hl.dsp.window.alter_zorder { mode = 'top' }) hl.dispatch(hl.dsp.window.tag { tag = '+pop' }) end end, 'Pop window out (float & pin)') bind('SUPER + CTRL + L', function() local layouts = { 'dwindle', 'scrolling', 'monocle', 'master' } local workspace = hl.get_active_workspace() if hl.get_active_special_workspace() then workspace = hl.get_active_special_workspace() end local next_layout = 'dwindle' if not workspace then return end for i = 1, #layouts do if layouts[i] == workspace.tiled_layout then local next_layout_idx = (i % #layouts) + 1 next_layout = layouts[next_layout_idx] break end end hl.workspace_rule { workspace = 'name:' .. tostring(workspace.name), layout = next_layout, } notify('󱂬 Workspace layout set to ' .. next_layout) end, 'Toggle workspace layout') -- Move focus with SUPER + arrow keys bind('SUPER + H', function() if get_current_layout() == 'monocle' then hl.dispatch(hl.dsp.window.cycle_next { tiled = true, next = false }) else hl.dispatch(hl.dsp.focus { direction = 'left' }) end end, 'Move window focus left') bind('SUPER + L', function() if get_current_layout() == 'monocle' then hl.dispatch(hl.dsp.window.cycle_next { tiled = true, next = true }) else hl.dispatch(hl.dsp.focus { direction = 'right' }) end end, 'Move window focus right') bind('SUPER + K', function() if get_current_layout() == 'monocle' then hl.dispatch(hl.dsp.window.cycle_next { tiled = true, next = false }) else hl.dispatch(hl.dsp.focus { direction = 'up' }) end end, 'Move window focus up') bind('SUPER + J', function() if get_current_layout() == 'monocle' then hl.dispatch(hl.dsp.window.cycle_next { tiled = true, next = true }) else hl.dispatch(hl.dsp.focus { direction = 'down' }) end end, 'Move window focus down') bind( 'SUPER + SHIFT + H', hl.dsp.window.move { direction = 'left' }, 'Move window left' ) bind( 'SUPER + SHIFT + L', hl.dsp.window.move { direction = 'right' }, 'Move window right' ) bind( 'SUPER + SHIFT + K', hl.dsp.window.move { direction = 'up' }, 'Move window up' ) bind( 'SUPER + SHIFT + J', hl.dsp.window.move { direction = 'down' }, 'Move window down' ) -- Control scratchpad bind( 'SUPER + S', hl.dsp.workspace.toggle_special 'scratchpad', 'Toggle scratchpad' ) bind( 'SUPER + ALT + S', hl.dsp.window.move { workspace = 'special:scratchpad' }, 'Move window to scratchpad' ) bind('SUPER + N', function() hl.dispatch(hl.dsp.workspace.toggle_special 'prod') local windows = hl.get_windows { workspace = 'special:prod' } if #windows == 0 then exec 'station-launch-or-focus ^superProductivity$ "uwsm-app -- super-productivity"' exec 'uwsm-app -- xdg-terminal-exec --app-id=org.station.notes nvim ~/Notes' end end, 'Toggle productivity workspace') bind('SUPER + M', function() hl.dispatch(hl.dsp.workspace.toggle_special 'music') local windows = hl.get_windows { workspace = 'special:music' } if #windows == 0 then exec 'station-launch-or-focus spotify' exec 'station-launch-or-focus psysonic' end end, 'Toggle music workspace') bind('SUPER + D', function() hl.dispatch(hl.dsp.workspace.toggle_special 'comms') local windows = hl.get_windows { workspace = 'special:comms' } if #windows == 0 then exec 'station-launch-or-focus ^signal$ "uwsm-app -- signal-desktop"' exec 'station-launch-or-focus ^chrome-web.whatsapp.com__-Default$ "station-launch-webapp https://web.whatsapp.com"' exec 'station-launch-or-focus ^chrome-discord.com__channels_@me-Default$ "station-launch-webapp https://discord.com/channels/@me"' end end, 'Toggle comms workspace') -- Cycle through applications on active workspace bind( 'SUPER + TAB', hl.dsp.window.cycle_next { tiled = true, next = true }, 'Cycle to next window' ) bind( 'SUPER + SHIFT + TAB', hl.dsp.window.cycle_next { tiled = true, next = false }, 'Cycle to prev window' ) -- bind("SUPER + TAB", /*bringactivetotop*/, "Reveal active window on top") -- bind("SUPER SHIFT + TAB", /*bringactivetotop*/, "Reveal active window on top") -- Resize active window bind( 'SUPER + code:20', hl.dsp.window.resize { x = -100, y = 0 }, 'Expand window left' ) bind( 'SUPER + code:21', hl.dsp.window.resize { x = 100, y = 0 }, 'Shrink window left' ) bind( 'SUPER + SHIFT + code:20', hl.dsp.window.resize { x = 0, y = -100 }, 'Shrink window up' ) bind( 'SUPER + SHIFT + code:21', hl.dsp.window.resize { x = 0, y = 100 }, 'Expand window down' ) -- Move/resize windows with mainMod + LMB/RMB and dragging bind('SUPER + mouse:272', hl.dsp.window.drag(), 'Move window', { mouse = true }) bind( 'SUPER + mouse:273', hl.dsp.window.resize(), 'Resize window', { mouse = true } ) -- Toggle current window to be a group or stack in other window manager lingo bind('SUPER + G', hl.dsp.group.toggle(), 'Toggle window to a group') -- Move to the next tab group window bind( 'SUPER + bracketleft', hl.dsp.group.prev(), 'Move to previous window in the group' ) bind( 'SUPER + bracketright', hl.dsp.group.next(), 'Move to next window in the group' ) -- Move current window in the tab group bind( 'SUPER + SHIFT + bracketleft', hl.dsp.group.move_window { direction = 'left' }, 'Move window left in group' ) bind( 'SUPER + SHIFT + bracketright', hl.dsp.group.move_window { direction = 'right' }, 'Move window right in group' ) -- Move current window out of the tab group bind( 'SUPER + CTRL + bracketleft', hl.dsp.window.move { out_of_group = 'left' }, 'Move window out of group left' ) bind( 'SUPER + CTRL + bracketright', hl.dsp.window.move { out_of_group = 'right' }, 'Move window out of group right' ) -- Move current window into an existing tab group or create a new one bind( 'SUPER + SHIFT + CTRL + bracketleft', hl.dsp.window.move { into_or_create_group = 'left' }, 'Move window into group left' ) bind( 'SUPER + SHIFT + CTRL + bracketright', hl.dsp.window.move { into_or_create_group = 'right' }, 'Move window into group right' ) -- ========================== -- Utilities -- ========================== -- Menus bind('SUPER + SPACE', dispatch_exec 'station-launch-walker', 'Launch apps') bind( 'SUPER + CTRL + E', dispatch_exec 'station-launch-walker -m symbols', 'Emoji picker' ) bind('SUPER + CTRL + C', dispatch_exec 'station-menu capture', 'Capture menu') bind('SUPER + CTRL + O', dispatch_exec 'station-menu toggle', 'Toggle menu') bind('SUPER + ALT + SPACE', dispatch_exec 'station-menu', 'Station menu') bind('SUPER + ESCAPE', dispatch_exec 'station-menu system', 'System menu') bindl('XF86PowerOff', dispatch_exec 'station-menu system', 'Power menu') bind('SUPER + K', dispatch_exec 'station-menu-keybindings', 'Show key bindings') bind('XF86Calculator', dispatch_exec 'gnome-calculator', 'Calculator') -- Aesthetics bind( 'SUPER + SHIFT + SPACE', dispatch_exec 'station-toggle-waybar', 'Toggle top bar' ) bind( 'SUPER + CTRL + SPACE', dispatch_exec 'station-menu background', 'Theme background menu' ) -- bind("SUPER SHIFT CTRL + SPACE", dispatch_exec("station-menu theme"), "Theme menu") bind( 'SUPER + BACKSPACE', dispatch_exec 'hyprctl dispatch setprop "address:$(hyprctl activewindow -j | jq -r \'.address\')" opaque toggle', 'Toggle window transparency' ) bind('SUPER + SHIFT + BACKSPACE', function() local gaps = hl.get_config 'general.gaps_out' if gaps.top == 0 then hl.config { general = { gaps_out = 10, gaps_in = 5, border_size = 2, }, } else hl.config { general = { gaps_out = 0, gaps_in = 0, border_size = 0, }, } end end, 'Toggle window gaps') -- Notifications bind( 'SUPER + COMMA', dispatch_exec 'makoctl dismiss', 'Dismiss last notification' ) bind( 'SUPER + SHIFT + COMMA', dispatch_exec 'makoctl dismiss --all', 'Dismiss all notifications' ) bind( 'SUPER + CTRL + COMMA', dispatch_exec 'station-toggle-notification-silencing', 'Toggle silencing notifications' ) bind( 'SUPER + ALT + COMMA', dispatch_exec 'makoctl invoke', 'Invoke last notification' ) bind( 'SUPER + SHIFT + ALT + COMMA', dispatch_exec 'makoctl restore', 'Restore last notification' ) -- Toggles bind( 'SUPER + CTRL + I', dispatch_exec 'station-toggle-idle', 'Toggle locking on idle' ) bind( 'SUPER + CTRL + N', dispatch_exec 'station-toggle-nightlight', 'Toggle nightlight' ) -- Captures bind('PRINT', dispatch_exec 'station-cmd-screenshot', 'Screenshot') bind( 'ALT + PRINT', dispatch_exec 'station-menu screenrecord', 'Screenrecording' ) bind( 'SUPER + PRINT', dispatch_exec 'pkill hyprpicker || hyprpicker -a', 'Color picker' ) -- File sharing -- bind("SUPER CTRL + S", dispatch_exec("station-menu share"), "Share") -- Waybar-less information bind( 'SUPER + CTRL + ALT + T', dispatch_exec 'notify " $(date +"%A %H:%M — %d %B W%V %Y")"', 'Show time' ) bind( 'SUPER + CTRL + ALT + B', dispatch_exec 'notify-send "󰁹 Battery is at $(station-battery-remaining)%"', 'Show battery remaining' ) bind('SUPER + CTRL + ALT + W', function() local window = hl.get_active_window() notify('Window: ' .. window.title .. '\nClass: ' .. window.class) end, 'Show active window name and class') -- Control panels bind('SUPER + CTRL + A', dispatch_exec 'station-launch-audio', 'Audio controls') bind( 'SUPER + CTRL + B', dispatch_exec 'station-launch-bluetooth', 'Bluetooth controls' ) bind('SUPER + CTRL + W', dispatch_exec 'station-launch-wifi', 'Wifi controls') bind('SUPER + CTRL + T', dispatch_exec 'station-launch-tui btop', 'Activity') -- Dictation -- bind("SUPER CTRL + X", dispatch_exec("voxtype record toggle"), "Toggle dictation") -- Zoom bind( 'SUPER + CTRL + Z', dispatch_exec "hyprctl keyword cursor:zoom_factor $(hyprctl getoption cursor:zoom_factor -j | jq '.float + 1')", 'Zoom in' ) bind( 'SUPER + CTRL + ALT + Z', dispatch_exec 'hyprctl keyword cursor:zoom_factor 1', 'Reset zoom' ) -- Lock system -- bind("SUPER CTRL + L", dispatch_exec("station-lock-screen"), "Lock system") -- ========================== -- Applications -- ========================== bind( 'SUPER + RETURN', dispatch_exec 'uwsm-app -- xdg-terminal-exec', 'Terminal' ) bind( 'SUPER + ALT + RETURN', dispatch_exec 'uwsm-app -- xdg-terminal-exec --dir="$(station-cmd-terminal-cwd)" tmux new', 'Tmux' ) bind( 'SUPER + SHIFT + F', dispatch_exec 'uwsm-app -- nautilus --new-window', 'File manager' ) bind( 'SUPER + ALT + SHIFT + F', dispatch_exec 'uwsm-app -- nautilus --new-window "$(station-cmd-terminal-cwd)"', 'File manager (cwd)' ) bind('SUPER + SHIFT + B', dispatch_exec 'station-launch-browser', 'Browser') bind( 'SUPER + SHIFT + ALT + B', dispatch_exec 'station-launch-browser --private', 'Browser (private)' ) bind( 'SUPER + SHIFT + S', dispatch_exec 'station-launch-or-focus spotify', 'Spotify' ) bind( 'SUPER + SHIFT + M', dispatch_exec 'station-launch-or-focus psysonic', 'Music' ) -- bind("SUPER SHIFT + D", dispatch_exec("station-launch-tui lazydocker"), "Docker") bind( 'SUPER + SHIFT + G', dispatch_exec 'station-launch-or-focus ^signal$ "uwsm-app -- signal-desktop"', 'Signal' ) bind( 'SUPER + SHIFT + D', dispatch_exec 'station-launch-or-focus ^chrome-discord.com__channels_@me-Default$ "uwsm-app -- discord"', 'Discord' ) bind( 'SUPER + SHIFT + W', dispatch_exec 'station-launch-or-focus ^chrome-web.whatsapp.com__-Default$ "uwsm-app -- whatsapp"', 'Whatsapp' ) bind( 'SUPER + SHIFT + P', dispatch_exec 'station-launch-or-focus ^superProductivity$ "uwsm-app -- super-productivity"', 'Super Productivity' ) bind( 'SUPER + SHIFT + N', dispatch_exec 'uwsm-app -- xdg-terminal-exec --app-id=org.station.notes nvim ~/Tower/Documents/Notes', 'Editor' ) -- bind("SUPER SHIFT + W", dispatch_exec("uwsm-app -- typora --enable-wayland-ime"), "Typora") bind('SUPER + SHIFT + SLASH', dispatch_exec 'Enpass showassistant', 'Passwords') bind( 'SUPER + SHIFT + E', dispatch_exec 'station-launch-or-focus mailspring', 'Email' ) bind( 'SUPER + SHIFT + A', dispatch_exec 'station-launch-webapp "https://gemini.google.com/app"', 'ChatGPT' ) bind( 'SUPER + SHIFT + C', dispatch_exec 'station-launch-webapp "https://tower.scarif.space/apps/calendar"', 'Calendar' ) bind( 'SUPER + SHIFT + Y', dispatch_exec 'station-launch-or-focus-webapp "YouTube" "https://youtube.com/"', 'YouTube' ) bind( 'SUPER + SHIFT + ALT + G', dispatch_exec 'station-launch-or-focus-webapp WhatsApp "https://web.whatsapp.com/"', 'WhatsApp' ) bind( 'SUPER + SHIFT + CTRL + G', dispatch_exec 'station-launch-or-focus-webapp "Google Maps" "https://maps.google.com"', 'Google Maps' ) -- bind("SUPER SHIFT + P", dispatch_exec("station-launch-or-focus-webapp "Google Photos" "https://photos.google.com/""), "Google Photos") -- bind("SUPER SHIFT + X", dispatch_exec("station-launch-webapp "https://x.com/""), "X") -- bind("SUPER SHIFT ALT + X", dispatch_exec("station-launch-webapp "https://x.com/compose/post""), "X Post") -- Add extra bindings bind( 'SUPER + SHIFT + R', dispatch_exec 'ghostty -e ssh scarif', 'SSH to scarif' )