diff --git a/README.md b/README.md
index 96ed19b..16df672 100644
--- a/README.md
+++ b/README.md
@@ -248,6 +248,7 @@ two tables below are split along exactly that line.
| `nomarchy.dockAudio.enable` | `true` | On a fresh external-monitor plug, PipeWire/WirePlumber are reprobed after hardware settles and the highest-priority available HDMI/DP/USB sink becomes default, with a toast and journal result. A later manual speaker choice sticks until the next physical plug; unplug falls back to built-in. Manual route: System › Audio |
| `nomarchy.firstBootWelcome.enable` | `true` | One dismissible “you're set” toast on the first session (SUPER+M / SUPER+T / SUPER+? + network pointer); marker is `settings.firstBootShown` in the flake checkout |
| `nomarchy.idle.enable` | `true` | hyprlock + hypridle (idle lock 5 min, display off 10, suspend 15 min — battery-only) |
+| `nomarchy.idle.fingerprint` | `false` | Unlock the lock screen with a fingerprint as well as the password, and say so on the input field. Set it alongside `nomarchy.hardware.fingerprint.pam` in system.nix: hyprlock is configured from Home Manager, which cannot read the NixOS option — and hyprlock does **not** take a fingerprint through PAM at all (its PAM stack runs only on submit), so it uses its own fprintd backend that this switch turns on |
| `nomarchy.yazi.enable` | `true` | yazi TUI file manager, themed + curated plugins |
| `nomarchy.osd.enable` | `true` | swayosd on-screen display for volume/brightness/mute |
| `nomarchy.shell.enable` | `true` | zsh + starship prompt + bat/eza/zoxide (zsh is the default login shell) |
diff --git a/modules/home/idle.nix b/modules/home/idle.nix
index acdade1..bdb3226 100644
--- a/modules/home/idle.nix
+++ b/modules/home/idle.nix
@@ -43,7 +43,15 @@ in
check_color = rgb c.warn;
fail_color = rgb c.bad;
rounding = t.ui.rounding;
- placeholder_text = "password…";
+ # $FPRINTPROMPT is the ONLY place hyprlock renders the fingerprint
+ # ready/scanning/failed messages — there is no implicit slot for
+ # them. Enabling the backend without this yields a reader that
+ # silently works while the field still says "password…", i.e. a
+ # feature nobody can find (VISION: fingerprint discoverable without
+ # reading the README). Verified on hardware 2026-07-14: unlock by
+ # finger worked and said nothing at all.
+ placeholder_text =
+ if cfg.idle.fingerprint then "$FPRINTPROMPT" else "password…";
}];
label = [{
@@ -56,6 +64,19 @@ in
halign = "center";
valign = "center";
}];
+ } // lib.optionalAttrs cfg.idle.fingerprint {
+ # hyprlock does NOT take a fingerprint through PAM: its PAM stack runs
+ # only on submit, so a parallel module never gets to poll the reader.
+ # This is a separate backend of its own, talking to fprintd over
+ # D-Bus, and `nomarchy.hardware.fingerprint.pam` does not reach it —
+ # which is why finger-unlock at the lock screen did nothing at all
+ # until this option existed, while sudo took a finger happily.
+ # The wording mirrors sudo's "Enter Password or Place finger" prompt.
+ auth.fingerprint = {
+ enabled = true;
+ ready_message = "password… or scan finger";
+ present_message = "scanning finger…";
+ };
};
};
diff --git a/modules/home/options.nix b/modules/home/options.nix
index f33411a..01ed2e3 100644
--- a/modules/home/options.nix
+++ b/modules/home/options.nix
@@ -367,6 +367,23 @@ in
dockAudio.enable = lib.mkEnableOption "settled PipeWire/WirePlumber reprobe and automatic default-output switch to an available dock/monitor sink (HDMI/DisplayPort/USB) on fresh display hotplug, with a toast and journal result; a later manual choice sticks until the next plug" // { default = true; };
firstBootWelcome.enable = lib.mkEnableOption "one dismissible \"you're set\" toast on the first session (menu/themes/keys + network pointer); marker is settings.firstBootShown in the flake checkout" // { default = true; };
idle.enable = lib.mkEnableOption "hyprlock + hypridle (idle lock, display off, suspend)" // { default = true; };
+ idle.fingerprint = lib.mkEnableOption ''
+ unlocking the lock screen with a fingerprint as well as the password,
+ and saying so on the input field.
+
+ Mirrors `nomarchy.hardware.fingerprint.pam` in system.nix — keep the two
+ matched, the same way `nomarchy.keyboard.layout` matches
+ `services.xserver.xkb.layout`. It cannot be derived: hyprlock is
+ configured here, in standalone Home Manager, which has no `osConfig` to
+ read the NixOS side from.
+
+ Deliberately separate from the PAM flag rather than implied by it:
+ hyprlock does NOT unlock by fingerprint through PAM. Its PAM stack only
+ runs on submit, so a parallel module never gets to poll — hyprlock has
+ its own fprintd-over-D-Bus backend instead, and this is the switch for
+ it. With no reader present it advertises a scan that cannot happen, so
+ it stays opt-in
+ '';
yazi.enable = lib.mkEnableOption "the yazi TUI file manager, themed with a curated plugin set" // { default = true; };
osd.enable = lib.mkEnableOption "swayosd on-screen display for volume/brightness/mute" // { default = true; };
shell.enable = lib.mkEnableOption "the zsh shell experience (starship prompt, bat/eza/zoxide)" // { default = true; };
diff --git a/templates/downstream/home.nix b/templates/downstream/home.nix
index 5b3bc8d..c15434f 100644
--- a/templates/downstream/home.nix
+++ b/templates/downstream/home.nix
@@ -18,6 +18,12 @@
# nomarchy.waybar.enable = false; # bring your own bar
# nomarchy.stylix.enable = false; # opt out of GTK/Qt theming
# nomarchy.dockAudio.enable = false; # keep audio put when docking
+ # nomarchy.idle.fingerprint = true; # unlock the lock screen by finger too, and
+ # # say so on the field. Set it alongside
+ # # nomarchy.hardware.fingerprint.pam in
+ # # system.nix — hyprlock is configured here
+ # # and cannot read the NixOS side, and it
+ # # does not take a finger through PAM at all.
#
# Icon pack: Papirus ships by default (auto Dark/Light by theme mode) and
# is the ONLY icon pack in your closure. To use another, set the `icons`