diff --git a/modules/home/idle.nix b/modules/home/idle.nix index bdb3226..67922fc 100644 --- a/modules/home/idle.nix +++ b/modules/home/idle.nix @@ -43,17 +43,19 @@ in check_color = rgb c.warn; fail_color = rgb c.bad; rounding = t.ui.rounding; - # $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…"; + placeholder_text = "password…"; }]; + # The lock screen is deliberately just the clock: the input field + # fades out while empty (hyprlock's fade_on_empty default) and only + # appears once you type. So the fingerprint hint CANNOT live in the + # field's placeholder — $FPRINTPROMPT renders faithfully into a widget + # nobody sees until they have already given up on the reader and + # started typing. It needs a surface that is visible at rest, and a + # label is the one that keeps the clock-only look. (Confirmed on + # hardware 2026-07-14: labels do expand $FPRINTPROMPT, so the line is + # live — "password… or scan finger", then "scanning finger…" on touch — + # and not static text.) label = [{ monitor = ""; text = "$TIME"; @@ -63,7 +65,20 @@ in position = "0, 120"; halign = "center"; valign = "center"; - }]; + }] ++ lib.optional cfg.idle.fingerprint { + monitor = ""; + text = "$FPRINTPROMPT"; + # subtext-on-base is the palette's secondary-text role and is held + # to a 3.0 contrast floor on every theme by checks.theme-contrast — + # the same guard that exists because two themes once shipped + # subtext == base and made hint text invisible. + color = rgb c.subtext; + font_size = 16; + font_family = t.fonts.ui; + position = "0, -160"; + 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.