# Greeter — greetd/tuigreet, themed from the same theme-state.json that # drives the desktop (nomarchy.system.stateFile; the Plymouth model: # baked at SYSTEM rebuild, so it follows the theme as of the last # sys-update, not the last instant apply). # # tuigreet draws on the virtual console with the 16 ANSI slots, so the # theming is two-part: # 1. console.colors — the VT palette becomes the theme's ansi[] hexes # (which also themes raw ttys and the LUKS passphrase prompt: the # same JSON reaches every pre-session surface). # 2. --theme — tuigreet components on NAMED slots (its parser is # ratatui Color::from_str; names map to the standard indexes, e.g. # blue=4, gray=7, white=15, so the palette above hands them the # theme's colors). ANSI "black" stays dark even in light themes — # the greeter reads terminal-dark there, the same convention every # terminal applies to ANSI colors. { config, lib, pkgs, ... }: let cfg = config.nomarchy.system; distroName = config.system.nixos.distroName; state = if cfg.stateFile != null then builtins.fromJSON (builtins.readFile cfg.stateFile) else { }; # A sparse/hand-rolled state without a proper ansi block just skips the # theming (stock tuigreet grey) — never an eval error. ansi = state.ansi or [ ]; themed = builtins.isList ansi && builtins.length ansi == 16; tuigreetTheme = lib.concatStringsSep ";" [ "container=black" # ansi[0] — the theme's terminal background "border=blue" # ansi[4] — the accent family in every shipped palette "title=cyan" "greet=cyan" "prompt=green" "input=white" # ansi[15] — bright foreground "action=blue" "button=yellow" "time=cyan" "text=gray" # ansi[7] — muted foreground ]; in { config = { # VT palette from the theme (RRGGBB, no #; lands as vt.default_* kernel # params). mkDefault so a downstream console.colors wins. console.colors = lib.mkIf themed (lib.mkDefault (map (lib.removePrefix "#") ansi)); services.greetd = lib.mkIf cfg.greeter.enable { enable = lib.mkDefault true; settings = { default_session = { # start-hyprland is Hyprland 0.55's watchdog launcher; running # the bare binary makes every session print a warning. command = lib.mkDefault ("${pkgs.tuigreet}/bin/tuigreet --time --remember --greeting 'Welcome to ${distroName}'" + lib.optionalString themed " --theme '${tuigreetTheme}'" + " --cmd start-hyprland"); user = "greeter"; }; # Boot straight into the session once; logout → normal greeter. initial_session = lib.mkIf (cfg.greeter.autoLogin != null) { command = "start-hyprland"; user = cfg.greeter.autoLogin; }; }; }; }; }