{ config, pkgs, lib, ... }: let lightdmConf = builtins.readFile ../../assets/conf/core/lightdm.conf; lockPng = ../../assets/lock.png; greeterConfPath = ../../assets/conf/core/lightdm-gtk-greeter.conf; greeterRaw = builtins.readFile greeterConfPath; # Extract "key = value" from the greeter conf. # Returns null if not found. getIniValue = key: let lines = lib.splitString "\n" greeterRaw; # Captures the value part (group 0) from a single line. # We match line-by-line because Nix regex does NOT support PCRE flags like (?s). m = let ms = builtins.filter (x: x != null) (map (line: builtins.match ("^[[:space:]]*" + key + "[[:space:]]*=[[:space:]]*([^#;]+).*$") line ) lines); in if ms == [] then null else builtins.elemAt ms 0; in if m == null then null else lib.strings.trim (builtins.elemAt m 0); # In your greeter.conf these are *package keys*, not theme names. themePkgKey = getIniValue "theme-name"; iconPkgKey = getIniValue "icon-theme-name"; cursorPkgKey = getIniValue "cursor-theme-name"; cursorSizeStr = getIniValue "cursor-theme-size"; cursorSize = if cursorSizeStr == null then null else lib.toInt (lib.strings.trim cursorSizeStr); # Map package-keys (from greeter.conf) -> { package, name } # # IMPORTANT: # - "name" must be the real theme/icon/cursor NAME as seen under share/themes or share/icons. # - "package" is the Nixpkgs derivation providing it. pkgMap = { catppuccinThemePkg = { package = pkgs.catppuccin-gtk.override { accents = [ "blue" ]; variant = "mocha"; size = "standard"; tweaks = [ ]; }; name = "Catppuccin-Mocha-Standard-Blue-Dark"; }; papirus-icon-theme = { package = pkgs.papirus-icon-theme; name = "Papirus-Dark"; }; bibata-cursors = { package = pkgs.bibata-cursors; name = "Bibata-Modern-Ice"; }; }; pick = key: if key == null then throw "lightdm: missing required key in ${toString greeterConfPath}" else if !(pkgMap ? "${key}") then throw "lightdm: unknown package key '${key}' in ${toString greeterConfPath}. Known keys: ${lib.concatStringsSep ", " (builtins.attrNames pkgMap)}" else pkgMap."${key}"; themeSel = pick themePkgKey; iconSel = pick iconPkgKey; cursorSel = pick cursorPkgKey; # Rewrite greeter.conf so LightDM sees REAL names, not package keys. # Also force background to lockPng. greeterFixed = '' [greeter] theme-name = ${themeSel.name} icon-theme-name = ${iconSel.name} cursor-theme-name = ${cursorSel.name} ${lib.optionalString (cursorSize != null) "cursor-theme-size = ${toString cursorSize}"} '' + "\n" + greeterRaw; in { services.greetd.enable = false; services.xserver = { enable = true; desktopManager.xterm.enable = false; displayManager.lightdm = { enable = true; background = lockPng; greeters.gtk = { enable = true; theme = { name = themeSel.name; package = themeSel.package; }; iconTheme = { name = iconSel.name; package = iconSel.package; }; cursorTheme = { name = cursorSel.name; package = cursorSel.package; } // lib.optionalAttrs (cursorSize != null) { size = cursorSize; }; # This includes your (rewritten) greeter config. extraConfig = greeterFixed; }; extraConfig = lightdmConf; }; }; programs.hyprland.enable = true; # Optional: make them available system-wide as well environment.systemPackages = [ themeSel.package iconSel.package cursorSel.package ]; }