feat: regreet and swaylock from nixpkgs, autologin after LUKS

greetd.nix configures services.displayManager.regreet and keeps niri as
the greeter compositor, so niri-greeter.kdl stays the shared file that
carries the German keyboard layout. The moongreet input, its package and
pkgs/moongreet.nix are gone.

extraCss goes through builtins.readFile: the module only recognises a
direct /nix/store child as a path, so passing the file path as a string
wrote the path itself into /etc/greetd/regreet.css.

desktop.nix installs swaylock, seeds ~/.config/swaylock/config with the
wallpaper rewritten to the store path, and now owns the moonlock PAM
stack. The Colloid overrides moved to flake.nix so the greeter and the
desktop share one derivation.

initial_session is set per host because the accounts differ. greetd's
restart option flips itself off, verified.

flake.lock still pins moonarch at the pushed revision; it needs
`nix flake update moonarch` once the moonarch commit is pushed.
This commit is contained in:
nevaforget committed 2026-08-14 14:32:43 +02:00
1 parent 16ee94f647
commit 630faf5390
9 files changed
+189 -131

No files matched your search

+26 -12
View File
@@ -1,7 +1,7 @@
# ABOUTME: Deploys the XDG configs from the moonarch repo and the package set.
# ABOUTME: Niri, Quickshell, terminal, theming, portals.
{ pkgs, lib, moonarchSrc, moonarchPkgs, ... }:
{ pkgs, lib, moonarchSrc, moonarchPkgs, moonarchThemes, ... }:
let
xdg = "${moonarchSrc}/defaults/xdg";
@@ -23,6 +23,15 @@ let
substitute ${xdg}/waypaper/config.ini "$out" \
--replace-fail /usr/share/moonarch/wallpaper.jpg ${wallpaper}
'';
# Same treatment for swaylock's wallpaper path. swaylock searches
# ~/.swaylock/config, $XDG_CONFIG_HOME/swaylock/config and
# SYSCONFDIR/swaylock/config — and its sysconfdir is inside the store here,
# so the home copy seeded below is the only one it ever reads.
swaylockConfig = pkgs.runCommand "swaylock-config" { } ''
substitute ${xdg}/swaylock/config "$out" \
--replace-fail /usr/share/moonarch/wallpaper.jpg ${wallpaper}
'';
in
{
# --- XDG configs -> /etc/xdg/ ---
@@ -148,11 +157,16 @@ in
environment.systemPackages = with pkgs; [
# Own programs
moonarchPkgs.moonlock
moonarchPkgs.moonset
moonarchPkgs.sweet-cursors
moonarchPkgs.stasis
moonarchPkgs.moonarch-scripts
# Only still installed because moonset's Lock action invokes moonlock by
# name and has no lock_command option. Idle and lid-close use swaylock.
moonarchPkgs.moonlock
# Session lock
swaylock
# Compositor extras
xwayland-satellite
@@ -191,16 +205,9 @@ in
udisks2
ntfs3g
# Theming
(colloid-gtk-theme.override {
themeVariants = [ "grey" ];
colorVariants = [ "dark" ];
tweaks = [ "catppuccin" ];
})
(colloid-icon-theme.override {
schemeVariants = [ "catppuccin" ];
colorVariants = [ "grey" ];
})
# Theming. Same derivations the greeter uses, see flake.nix.
moonarchThemes.gtk
moonarchThemes.icons
libsForQt5.qtstyleplugin-kvantum
qt6Packages.qtstyleplugin-kvantum
qt6Packages.qt6ct
@@ -235,5 +242,12 @@ in
# edits survive. This is what post-install.sh does imperatively on Arch.
systemd.user.tmpfiles.rules = [
"C %h/.config/waypaper/config.ini 0644 - - - ${waypaperConfig}"
"C %h/.config/swaylock/config 0644 - - - ${swaylockConfig}"
];
# PAM stack for moonlock, shipped by the package but owned by the system.
# swaylock needs none of this: programs.niri.enable brings
# security.pam.services.swaylock with it. Goes away with moonlock.
security.pam.services.moonlock.text =
builtins.readFile "${moonarchPkgs.moonlock}/share/moonlock/moonlock-pam";
}
+59 -43
View File
@@ -1,61 +1,77 @@
# ABOUTME: Sets up greetd with moongreet as the login greeter.
# ABOUTME: Sets up greetd with regreet as the login greeter.
# ABOUTME: Counterpart to defaults/etc/greetd/ in the moonarch repo.
{ pkgs, lib, moonarchSrc, moonarchPkgs, ... }:
{ pkgs, lib, moonarchSrc, moonarchPkgs, moonarchThemes, ... }:
let
wallpaper = "${moonarchSrc}/defaults/backgrounds/wallpaper.jpg";
# moongreet.toml cannot be copied verbatim: the upstream file points at
# /usr/share/moonarch/wallpaper.jpg, which does not exist under Nix.
# Everything else matches defaults/etc/moongreet/moongreet.toml.
moongreetConfig = pkgs.writeText "moongreet.toml" ''
[appearance]
background = "${wallpaper}"
cursor-theme = "Sweet-cursors"
cursor-size = 24
'';
greeterNiriConfig = "${moonarchSrc}/defaults/etc/greetd/niri-greeter.kdl";
in
{
environment.etc = {
"greetd/niri-greeter.kdl".source = greeterNiriConfig;
"moongreet/moongreet.toml".source = moongreetConfig;
};
environment.etc."greetd/niri-greeter.kdl".source = greeterNiriConfig;
# moongreet caches the last user and session under /var/cache/moongreet.
# Without the directory it logs a permission error on every start.
systemd.tmpfiles.rules = [
"d /var/cache/moongreet 0755 greeter greeter -"
"d /var/cache/moongreet/last-session 0755 greeter greeter -"
];
# /etc/greetd/regreet.toml and regreet.css are written by the module, so
# defaults/etc/greetd/regreet.toml is not deployed verbatim: its wallpaper
# path points at /usr/share/moonarch/, which does not exist here. Every other
# value matches that file. Declaring those two paths in environment.etc would
# collide with the module.
services.displayManager.regreet = {
enable = true;
settings = {
background = {
path = wallpaper;
fit = "Cover";
};
GTK.application_prefer_dark_theme = true;
commands = {
reboot = [ "systemctl" "reboot" ];
poweroff = [ "systemctl" "poweroff" ];
};
};
# The rest of the GTK table is generated from these options.
theme = {
package = moonarchThemes.gtk;
name = "Colloid-Grey-Dark-Catppuccin";
};
iconTheme = {
package = moonarchThemes.icons;
name = "Colloid-Grey-Catppuccin-Dark";
};
cursorTheme = {
package = moonarchPkgs.sweet-cursors;
name = "Sweet-cursors";
};
font = {
package = pkgs.nerd-fonts.ubuntu-sans;
name = "UbuntuSans Nerd Font";
size = 12;
};
# readFile, not the path: the module only treats a direct /nix/store child
# as a path (lib.isStorePath), so passing this file's path as a string would
# write the path itself into /etc/greetd/regreet.css.
extraCss = builtins.readFile "${moonarchSrc}/defaults/etc/greetd/regreet.css";
};
services.greetd = {
enable = true;
settings = {
terminal.vt = 1;
default_session = {
# moongreet needs a Wayland compositor; niri provides it.
command = "${lib.getExe pkgs.niri} -c /etc/greetd/niri-greeter.kdl";
user = "greeter";
};
settings.default_session = {
# regreet needs a Wayland compositor. niri instead of the module's cage
# default: niri-greeter.kdl carries the German keyboard layout, numlock
# and the cursor theme, and cage would come up with none of them.
command = "${lib.getExe pkgs.niri} -c /etc/greetd/niri-greeter.kdl";
user = "greeter";
};
};
# greetd is WantedBy=graphical.target. An installation without a desktop
# boots into multi-user.target, where the unit never starts.
systemd.defaultUnit = "graphical.target";
# moongreet walks XDG_DATA_DIRS for wayland-sessions/ and xsessions/.
# NixOS does not link those directories into the system profile by default.
# regreet walks XDG_DATA_DIRS for wayland-sessions/ and xsessions/.
environment.pathsToLink = [ "/share/wayland-sessions" "/share/xsessions" ];
# The greeter session spawns `moongreet` by name from niri-greeter.kdl,
# so it has to resolve in PATH.
environment.systemPackages = [ moonarchPkgs.moongreet ];
# PAM stack for moonlock, shipped by the package but owned by the system.
security.pam.services.moonlock.text =
builtins.readFile "${moonarchPkgs.moonlock}/share/moonlock/moonlock-pam";
}