{config, pkgs, outputs, ...}: { wayland.windowManager.sway = { config = let # Set default modifier and variables primeMod = "Mod4"; secMod = "Mod1"; resizeAmount = ''55''; sendNotif = ''notify-send --expire-time=1500''; in { # Hotkeys modifier = "${primeMod}"; keybindings = let # Define scripts specific to Sway pinWindow = pkgs.writeScript "pin-window" '' # Get the current border style of the focused window current_style=$(swaymsg -t get_tree | jq -r '.. | select(.focused?).border') # Toggle between "normal" (default) and "pixel ${outputs.look.border.string}" border styles if [ "$current_style" == "none" ]; then swaymsg "sticky disable, border pixel ${outputs.look.border.string}" else swaymsg "sticky enable, border none" fi ''; # Kill a window or probe it for info swayTools = pkgs.writeScript "swaytools" '' # List the app name and whether or not it uses wayland swayprop() { selected_window=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)"' | slurp -r -c ${outputs.look.colors.prime} -B 00000066 -b 00000000) if [ -n "$selected_window" ]; then app_id=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .app_id') system=$(sed 's/xdg_shell/Wayland/g; s/xwayland/Xorg/g' < <(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .shell')) notify-send "$(echo -e "Window's app_id: $app_id\nWindow System: $system")" fi } # Kill a selected window swaykill() { selected_window=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)"' | slurp -r -c ${outputs.look.colors.prime} -B 00000066 -b 00000000) if [ -n "$selected_window" ]; then pid=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .pid') kill -9 "$pid" fi } # Handle which tool we use if [ "$1" == "--prop" ]; then swayprop elif [ "$1" == "--kill" ]; then swaykill fi ''; in { ## Launcher keys # LibreWolf profiles "${primeMod}+F1" = ''exec librewolf -P Jimbo --name=JimBrowser | ${sendNotif} "Main Browser"''; "${primeMod}+F2" = ''exec librewolf -P Alt --name=AltBrowser | ${sendNotif} "Alternate Browser"''; "${primeMod}+F3" = ''exec librewolf -P Misc --name=MiscBrowser | ${sendNotif} "Miscellaneous Browser"''; # Discord "${primeMod}+F4" = ''exec vesktop --ozone-platform-hint=auto | ${sendNotif} "Discord"''; # Games "${primeMod}+F5" = ''exec steam | ${sendNotif} "Steam"''; "${primeMod}+F6" = ''exec heroic | ${sendNotif} "Heroic Games"''; # Looking glass for VMs "${primeMod}+F7" = ''exec looking-glass-client input:rawMouse=yes | ${sendNotif} "Looking Glass"''; # Virtual Machines "${primeMod}+F10" = ''exec virt-manager | ${sendNotif} "Virtual Machines"''; # BeMenu scripts "${primeMod}+F11" = ''exec rofiscripts --scratchpads | ${sendNotif} "Scratchpads"''; "${primeMod}+${secMod}+Ctrl+r" = ''exec rofiscripts --resolutions''; # Open NixOS configuration files "${primeMod}+F12" = ''exec foot ${outputs.cmd.nixcfg} | ${sendNotif} "Nix Config"''; # Terminal, rofi, clipmenu, media script, power menu, show/hide waybar "${primeMod}+Return" = ''exec foot''; "${primeMod}+s" = ''exec rofi -show run -p Command''; "${primeMod}+c" = ''exec clipman pick -t rofi''; "${primeMod}+x" = ''exec rofiscripts --power''; "${primeMod}+b" = ''exec pkill -USR1 waybar''; "${primeMod}+Escape" = ''exec ${swayTools} --kill''; # PCManFM, Emoji Picker, Rofi Launcher, Bluetooth, Ranger "${primeMod}+Shift+t" = ''exec pcmanfm-qt''; "${primeMod}+Shift+e" = ''exec BEMOJI_PICKER_CMD="rofi -dmenu -i -p Emoji" bemoji -n -P 0''; "${primeMod}+Shift+s" = ''exec rofi -show drun -modi drun -drun-display-format {name} -show-icons -disable-history''; "${primeMod}+Shift+b" = ''exec rofi-bluetooth''; "${primeMod}+Shift+Return" = ''exec foot ranger''; # Swaytools prop, colorpicker, obs-cmd "${primeMod}+Ctrl+x" = ''exec ${swayTools} --prop''; "${primeMod}+Ctrl+c" = ''exec ${pkgs.hyprpicker}/bin/hyprpicker -an && ${sendNotif} "Color copied to clipboard"''; "${primeMod}+Ctrl+Prior" = ''exec ${pkgs.obs-cmd}/bin/obs-cmd scene switch "Main"''; "${primeMod}+Ctrl+Next" = ''exec ${pkgs.obs-cmd}/bin/obs-cmd scene switch "Guest"''; ## Media keys # Volume control "XF86AudioRaiseVolume" = ''exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+''; "XF86AudioLowerVolume" = ''exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-''; # MPV volume control "${secMod}+XF86AudioRaiseVolume" = ''exec mpc volume +3''; "${secMod}+XF86AudioLowerVolume" = ''exec mpc volume -3''; # Mute, Stop "XF86AudioMute" = ''exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle''; "XF86AudioStop" = ''exec mpc stop''; # Play MPD, Firefox, or MPV "XF86AudioPlay" = ''exec mpc toggle''; "${secMod}+XF86AudioPlay" = ''exec playerctl --player=librewolf play-pause''; "Ctrl+XF86AudioPlay" = ''exec playerctl --player=mpv play-pause''; # Next/Previous "XF86AudioNext" = ''exec mpc next''; "XF86AudioPrev" = ''exec mpc prev''; # Seek "${secMod}+Shift+XF86AudioNext" = ''exec mpc seek +5''; "${secMod}+Shift+XF86AudioPrev" = ''exec mpc seek -5''; ## Notification keys # Toggle mako "${primeMod}+n" = ''exec makotoggle''; "${primeMod}+Shift+n" = ''exec makoctl restore''; "${primeMod}+Ctrl+n" = ''exec makoctl dismiss -a''; ## Miscellaneous keys # Screenshots "Print" = ''exec swayshot --swappy''; "${primeMod}+Shift+f" = ''exec swayshot --swappy''; "Shift+Print" = ''exec swayshot --screen''; # Server SSH "${primeMod}+Ctrl+Return" = ''exec foot ssh ${outputs.ips.server} -p 2222''; # Display Brightness and Keyboard Brightness "XF86MonBrightnessUp" = ''exec light -A 5''; "XF86MonBrightnessDown" = ''exec light -U 5''; "Shift+XF86MonBrightnessUp" = ''exec light -A 1''; "Shift+XF86MonBrightnessDown" = ''exec light -U 1''; "XF86KbdBrightnessUp" = ''exec light -s sysfs/leds/smc::kbd_backlight -A 5''; "XF86KbdBrightnessDown" = ''exec light -s sysfs/leds/smc::kbd_backlight -U 5''; ## Window manager keys "${primeMod}+q" = ''kill''; "${primeMod}+Shift+r" = ''reload''; # Switch to workspaces "${primeMod}+grave" = ''workspace ${outputs.ws.w0}''; "${primeMod}+1" = ''workspace ${outputs.ws.w1}''; "${primeMod}+2" = ''workspace ${outputs.ws.w2}''; "${primeMod}+3" = ''workspace ${outputs.ws.w3}''; "${primeMod}+4" = ''workspace ${outputs.ws.w4}''; "${primeMod}+5" = ''workspace ${outputs.ws.w5}''; "${primeMod}+6" = ''workspace ${outputs.ws.w6}''; "${primeMod}+7" = ''workspace ${outputs.ws.w7}''; "${primeMod}+8" = ''workspace ${outputs.ws.w8}''; "${primeMod}+9" = ''workspace ${outputs.ws.w9}''; # Switch to alternate workspaces "${secMod}+F1" = ''workspace ${outputs.ws.w1a}''; "${secMod}+F2" = ''workspace ${outputs.ws.w2a}''; "${secMod}+F3" = ''workspace ${outputs.ws.w3a}''; "${secMod}+F4" = ''workspace ${outputs.ws.w4a}''; "${secMod}+F5" = ''workspace ${outputs.ws.w5a}''; "${secMod}+F6" = ''workspace ${outputs.ws.w6a}''; "${secMod}+F7" = ''workspace ${outputs.ws.w7a}''; "${secMod}+F8" = ''workspace ${outputs.ws.w8a}''; "${secMod}+F9" = ''workspace ${outputs.ws.w9a}''; # Move window to and focus new workspace "${primeMod}+Shift+grave" = ''move container to workspace ${outputs.ws.w0}; workspace ${outputs.ws.w0}''; "${primeMod}+Shift+1" = ''move container to workspace ${outputs.ws.w1}; workspace ${outputs.ws.w1}''; "${primeMod}+Shift+2" = ''move container to workspace ${outputs.ws.w2}; workspace ${outputs.ws.w2}''; "${primeMod}+Shift+3" = ''move container to workspace ${outputs.ws.w3}; workspace ${outputs.ws.w3}''; "${primeMod}+Shift+4" = ''move container to workspace ${outputs.ws.w4}; workspace ${outputs.ws.w4}''; "${primeMod}+Shift+5" = ''move container to workspace ${outputs.ws.w5}; workspace ${outputs.ws.w5}''; "${primeMod}+Shift+6" = ''move container to workspace ${outputs.ws.w6}; workspace ${outputs.ws.w6}''; "${primeMod}+Shift+7" = ''move container to workspace ${outputs.ws.w7}; workspace ${outputs.ws.w7}''; "${primeMod}+Shift+8" = ''move container to workspace ${outputs.ws.w8}; workspace ${outputs.ws.w8}''; "${primeMod}+Shift+9" = ''move container to workspace ${outputs.ws.w9}; workspace ${outputs.ws.w9}''; # Move window to and focus new alternate workspace "${secMod}+Shift+F1" = ''move container to workspace ${outputs.ws.w1a}; workspace ${outputs.ws.w1a}''; "${secMod}+Shift+F2" = ''move container to workspace ${outputs.ws.w2a}; workspace ${outputs.ws.w2a}''; "${secMod}+Shift+F3" = ''move container to workspace ${outputs.ws.w3a}; workspace ${outputs.ws.w3a}''; "${secMod}+Shift+F4" = ''move container to workspace ${outputs.ws.w4a}; workspace ${outputs.ws.w4a}''; "${secMod}+Shift+F5" = ''move container to workspace ${outputs.ws.w5a}; workspace ${outputs.ws.w5a}''; "${secMod}+Shift+F6" = ''move container to workspace ${outputs.ws.w6a}; workspace ${outputs.ws.w6a}''; "${secMod}+Shift+F7" = ''move container to workspace ${outputs.ws.w7a}; workspace ${outputs.ws.w7a}''; "${secMod}+Shift+F8" = ''move container to workspace ${outputs.ws.w8a}; workspace ${outputs.ws.w8a}''; "${secMod}+Shift+F9" = ''move container to workspace ${outputs.ws.w9a}; workspace ${outputs.ws.w9a}''; # Change focus across windows "${primeMod}+Up" = ''focus up''; "${primeMod}+Down" = ''focus down''; "${primeMod}+Left" = ''focus left''; "${primeMod}+Right" = ''focus right''; # Switch focus across outputs "${primeMod}+j" = ''focus output ${outputs.displays.d2}''; "${primeMod}+k" = ''focus output ${outputs.displays.d1}''; "${primeMod}+l" = ''focus output ${outputs.displays.d3}''; # Move focused window "${primeMod}+Shift+Up" = ''move up ${resizeAmount} px''; "${primeMod}+Shift+Down" = ''move down ${resizeAmount} px''; "${primeMod}+Shift+Left" = ''move left ${resizeAmount} px''; "${primeMod}+Shift+Right" = ''move right ${resizeAmount} px''; # Move window across outputs "${primeMod}+Shift+j" = ''move output ${outputs.displays.d2}; focus output ${outputs.displays.d2}''; "${primeMod}+Shift+k" = ''move output ${outputs.displays.d1}; focus output ${outputs.displays.d1}''; "${primeMod}+Shift+l" = ''move output ${outputs.displays.d3}; focus output ${outputs.displays.d3}''; # Change focus between floating/tiled, toggle floating "${primeMod}+space" = ''focus mode_toggle''; "${primeMod}+Shift+space" = ''floating toggle''; # Allow a window to be visible on all workspaces, toggle border "${primeMod}+0" = ''exec ${pinWindow}''; # Toggle fullscreen "${primeMod}+f" = ''fullscreen toggle''; "${primeMod}+${secMod}+Ctrl+f" = ''fullscreen toggle global''; # Change container layout "${primeMod}+w" = ''layout toggle split''; "${primeMod}+e" = ''layout toggle tabbed stacking''; # Change split direction "${primeMod}+h" = ''split h''; "${primeMod}+v" = ''split v''; # Focus parent / child "${primeMod}+a" = ''focus parent''; "${primeMod}+d" = ''focus child''; # Resize windows "${primeMod}+${secMod}+Up" = ''resize grow height ${resizeAmount} px or 5 ppt''; "${primeMod}+${secMod}+Down" = ''resize shrink height ${resizeAmount} px or 5 ppt''; "${primeMod}+${secMod}+Left" = ''resize shrink width ${resizeAmount} px or 5 ppt''; "${primeMod}+${secMod}+Right" = ''resize grow width ${resizeAmount} px or 5 ppt''; # Adjust gap size "${primeMod}+Shift+equal" = ''gaps inner current set 5''; "${primeMod}+equal" = ''gaps inner current plus 5''; "${primeMod}+minus" = ''gaps inner current minus 5''; # Scratchpads "Ctrl+Shift+Escape" = ''[app_id="gotop"] scratchpad show, move position center, resize set 1216 888''; "${primeMod}+Shift+m" = ''[app_id="music"] scratchpad show, move position center, resize set 1006 657''; "${primeMod}+Shift+v" = ''[app_id="sound"] scratchpad show, move position center, resize set 1000 800''; "${primeMod}+Shift+Backslash" = ''[app_id="com.github.wwmm.easyeffects"] scratchpad show, move position center, resize set 1000 800''; }; }; }; }