# ABOUTME: The session lock: gtklock, its two modules and the PAM stack it needs. # ABOUTME: Its config is generated because moonarch's copy names FHS paths. { pkgs, lib, moonarchSrc, ... }: let wallpaperBlur = "${moonarchSrc}/defaults/backgrounds/wallpaper-blur.jpg"; # gtklock reads $XDG_CONFIG_HOME/gtklock/config.ini and gtklock/config.ini # under every $XDG_CONFIG_DIRS entry, so /etc/xdg is enough and nothing has # to be seeded into the home directory — the one thing swaylock could not do, # its sysconfdir being inside the store. # # The background stays the pre-blurred image. gtklock cannot blur either: # GTK3 has no `filter` CSS property at all (checked against # libgtk-3.so.0.2420.32 — it knows `background-image` and `box-shadow`, and # neither `filter` nor `backdrop-filter`), and it takes no screenshot of the # session, so there is nothing to blur at lock time in the first place. # # No gtk-theme key: gtklock is GTK3 and reads the session theme out of # /etc/xdg/gtk-3.0/settings.ini, so the theme name keeps living in one place. # # Modules are named by absolute store path. `-m` resolves a bare name against # the directory compiled into gtklock, which under Nix is gtklock's own store # path and contains no module at all. powerbar needs no configuration: its # built-in commands are `systemctl reboot|-i poweroff|suspend`, and systemd # is on the PATH the stasis unit sets in modules/services.nix. gtklockConfig = pkgs.writeText "gtklock-config.ini" '' [main] background=${wallpaperBlur} modules=${moduleList} ''; moduleList = lib.concatStringsSep ";" [ "${pkgs.gtklock-userinfo-module}/lib/gtklock/userinfo-module.so" "${pkgs.gtklock-powerbar-module}/lib/gtklock/powerbar-module.so" ]; in { # moonarch ships defaults/xdg/gtklock/config.ini, but it is not deployed # here: it names /usr/share/moonarch for the background and resolves the # modules by bare name against /usr/lib/gtklock. Both are store paths under # Nix, so the file is generated above rather than copied — the same reason # PipeWire's config takes its own route. environment.etc."xdg/gtklock/config.ini".source = gtklockConfig; # Session lock. The power menu is a Quickshell popout, not a package. # gtklock speaks the same ext-session-lock-v1 as swaylock, through # gtk-session-lock, so a crash still leaves the screen locked. The modules # are the reason for it: avatar and clock, and the power buttons. They are # installed for the sake of `nix-store --query --roots`; gtklock itself # loads them from the store paths named in the config above. playerctl is # deliberately absent — it needs playerctld, which nothing here runs. environment.systemPackages = with pkgs; [ gtklock gtklock-userinfo-module gtklock-powerbar-module ]; # Without this gtklock takes the session lock and then rejects every # password: there would be no /etc/pam.d/gtklock, and /etc/pam.d/other denies # auth outright. The generated stack is `auth sufficient pam_unix.so`, the # same one swaylock had. security.pam.services.gtklock = { }; }