{ pkgs, ... }: { # Notification daemon -- sway has no hyprctl-notify equivalent, mako is # the standard minimal choice in the sway ecosystem (used below and by # battery-monitor.nix via plain notify-send). services.mako.enable = true; wayland.windowManager.sway = { enable = true; wrapperFeatures.gtk = true; # The generated config references a wallpaper under the user's home # directory, which doesn't exist in the Nix build sandbox -- sway's # own build-time config validation fails on that even though the # config is fine at actual runtime. Documented, expected workaround # (straight from the error message this hits without it). checkConfig = false; config = { modifier = "Mod4"; terminal = "kitty"; output = { "eDP-1" = { resolution = "1920x1080@60Hz"; position = "0,0"; }; "HDMI-A-2" = { resolution = "1920x1080@60Hz"; position = "1920,0"; }; "*" = { bg = "/home/builder/wallpapers/white.png fill"; }; }; input = { "type:keyboard" = { xkb_layout = "de"; xkb_options = "ctrl:nocaps"; }; "type:touchpad" = { natural_scroll = "disabled"; }; }; # Only the plain workspace-switching behaviour lukas actually asked # for, plus straightforward ports of the app launchers already in # use. Dropped versus the old hyprland.nix: the clock toggle widget # and light/dark theme-toggle script (both hyprctl-specific, # explicitly out of scope -- "brauche kein Hyprland, Workspaces # reichen"), waybar/tofi autostart (was already commented out for # waybar; tofi itself still works under sway if wanted later). keybindings = let modifier = "Mod4"; in ( { "${modifier}+q" = "kill"; "${modifier}+Shift+e" = "exec swaymsg exit"; "${modifier}+Tab" = "focus next"; "${modifier}+p" = "exec keepassxc"; "${modifier}+a" = "exec kitty"; "${modifier}+n" = "exec kitty -e v"; "${modifier}+m" = "exec alacritty -e aerc"; "${modifier}+b" = "exec kitty -e btop"; "${modifier}+o" = ''exec qutebrowser --target window --set tabs.show never --set statusbar.show in-mode --set scrolling.bar never desk.0ff.space''; "${modifier}+f" = "exec qutebrowser"; "Print" = ''exec grim -g "$(slurp)" - | wl-copy''; "XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"; "XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"; "XF86MonBrightnessDown" = "exec brightnessctl set 5%-"; "XF86MonBrightnessUp" = "exec brightnessctl set 5%+"; "${modifier}+u" = ''exec bash -c 'udiskie-umount -a && rm -f ~/juno && rm -f ~/LukasDisk && notify-send "💿 Laufwerke ausgehängt" || notify-send "⚠️ Aushängen fehlgeschlagen"' ''; "${modifier}+Shift+u" = ''exec bash -c 'udiskie-mount -a && ln -sfn /run/media/builder/juno ~/juno && ln -sfn /run/media/builder/LukasDisk ~/LukasDisk && notify-send "📁 Laufwerke eingehängt" || notify-send "⚠️ Einhängen fehlgeschlagen"' ''; } // ( # Workspace bindings 1-9, same dynamic generation as before builtins.listToAttrs ( builtins.genList ( i: let ws = builtins.toString (i + 1); in { name = "${modifier}+${ws}"; value = "workspace number ${ws}"; } ) 9 ) ) // ( builtins.listToAttrs ( builtins.genList ( i: let ws = builtins.toString (i + 1); in { name = "${modifier}+Shift+${ws}"; value = "move container to workspace number ${ws}"; } ) 9 ) ) ); }; }; }