{ config, lib, pkgs, ... }: let cfg = config.features.swayDesktop; # Catppuccin Mocha (shared with the Sway desktop, see home/sway.nix). ctp = import ../lib/catppuccin-mocha.nix; in { # The features.swayDesktop.enable option is declared in # system/modules/features.nix (so headless hosts can read/set it without # importing this module). This module only provides its implementation. config = lib.mkIf cfg.enable { programs.sway = { enable = true; wrapperFeatures.gtk = true; extraSessionCommands = '' # QT export QT_QPA_PLATFORM="wayland;xcb" export QT_QPA_PLATFORMTHEME=qt5ct # SDL export SDL_VIDEODRIVER=wayland # Java export _JAVA_AWT_WM_NONREPARENTING=1 # Misc export CLUTTER_BACKEND=wayland export WINIT_UNIX_BACKEND=wayland export MOZ_ENABLE_WAYLAND=1 ''; # Core Wayland utilities. The lock screen, idle daemon, status bar and # notification daemon are configured per-user in home/sway.nix. extraPackages = with pkgs; [ brightnessctl foot grim slurp # region selection for screenshots swappy # screenshot annotation/save jq # used by the focused-window screenshot bind playerctl # MPRIS media keys sway-launcher-desktop pavucontrol ]; }; fonts.packages = with pkgs; [ noto-fonts noto-fonts-color-emoji font-awesome ]; # Wayland login screen (replaces console/getty login on every Sway host). # greetd runs ReGreet inside the cage kiosk compositor; the Sway session is # offered automatically because programs.sway registers itself via # services.displayManager.sessionPackages. Hosts that turn off # features.swayDesktop (e.g. EDaaS) keep plain TTY login. programs.regreet.enable = true; # Theme the greeter to match the Sway desktop (Catppuccin Mocha). ReGreet is # GTK; recolour via CSS (covering both libadwaita named colours and plain # GTK node selectors) and use the same Noto Sans as the bar/notifications. programs.regreet.font = { name = "Noto Sans"; package = pkgs.noto-fonts; size = 16; }; programs.regreet.extraCss = '' /* GTK4 Adwaita legacy names (what plain GTK4 actually references). */ @define-color theme_bg_color #${ctp.base}; @define-color theme_fg_color #${ctp.text}; @define-color theme_base_color #${ctp.mantle}; @define-color theme_text_color #${ctp.text}; @define-color theme_selected_bg_color #${ctp.blue}; @define-color theme_selected_fg_color #${ctp.base}; @define-color insensitive_bg_color #${ctp.mantle}; @define-color insensitive_fg_color #${ctp.overlay0}; @define-color borders #${ctp.surface1}; @define-color warning_color #${ctp.peach}; @define-color error_color #${ctp.red}; @define-color success_color #${ctp.green}; /* libadwaita names (inert on plain GTK4, kept for forward-compat). */ @define-color window_bg_color #${ctp.base}; @define-color window_fg_color #${ctp.text}; @define-color view_bg_color #${ctp.mantle}; @define-color view_fg_color #${ctp.text}; @define-color card_bg_color #${ctp.surface0}; @define-color card_fg_color #${ctp.text}; @define-color accent_bg_color #${ctp.blue}; @define-color accent_fg_color #${ctp.base}; @define-color accent_color #${ctp.blue}; @define-color destructive_bg_color #${ctp.red}; @define-color destructive_fg_color #${ctp.base}; window { background-color: #${ctp.base}; color: #${ctp.text}; } label { color: #${ctp.text}; } entry { background-color: #${ctp.surface0}; color: #${ctp.text}; border: 1px solid #${ctp.surface1}; } entry:focus-within { border-color: #${ctp.blue}; } button, combobox button { background-color: #${ctp.surface0}; color: #${ctp.text}; border: 1px solid #${ctp.surface1}; } button:hover { background-color: #${ctp.surface1}; } button:active, button:checked { background-color: #${ctp.blue}; color: #${ctp.base}; } ''; # cage reads the XKB_* environment at startup, so force the greeter onto the # same Dvorak layout as the Sway session (home/sway.nix) -- otherwise the # password field would be QWERTY. Dvorak is the "us" layout's variant, NOT a # layout of its own: "dvorak" alone has no symbols/ file, so the keymap # fails to compile and the greeter ends up with no keyboard at all (the # greeter has no fallback, unlike a running Sway session). This overrides the # greetd command regreet sets with mkDefault. services.greetd.settings.default_session.command = let greeter = pkgs.writeShellScript "regreet-cage" '' export XKB_DEFAULT_LAYOUT=us export XKB_DEFAULT_VARIANT=dvorak # ReGreet is plain GTK4 (no libadwaita); force the dark Adwaita variant # so the extraCss accents sit on a dark base instead of light Adwaita. export GTK_THEME=Adwaita:dark exec ${pkgs.dbus}/bin/dbus-run-session ${lib.getExe pkgs.cage} -s -- ${lib.getExe config.programs.regreet.package} ''; in "${greeter}"; # Desktop portals: enables screen sharing (wlroots) and native file pickers # for Wayland apps such as Element and Firefox. xdg.portal = { enable = true; wlr.enable = true; extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; config.common.default = "*"; }; }; }