feat(menu): one fingerprint switch, an auto-login toggle, and the state bridge they needed
All checks were successful
Check / eval (push) Successful in 3m7s
All checks were successful
Check / eval (push) Successful in 3m7s
Bernardo, post-reboot: "Use for login" was the wrong question. Whether the
finger works is one decision, not two, and whether login prompts at all is
a different decision that was never in the menu.
System › Fingerprint is now a single Fingerprint (on/off) switch, leading
the menu with enroll/list/verify/delete as the plumbing behind it. It
writes the one settings.fingerprint.pam key, and modules/home/idle.nix now
defaults idle.fingerprint from that same key — so the lock screen and
login/sudo move together instead of drifting apart the way they did until
e2de906. nomarchy-fingerprint does the two rebuilds this needs (sudo
system for PAM, home switch for hyprlock) and refuses to turn on with no
finger enrolled.
System › Auto-login is new (nomarchy-autologin), and it is what decides
whether anything is asked at boot: auto-login on means no prompt whatever
the fingerprint switch says; off means the greeter asks, for a password or
a finger. Installer-seeded ON for LUKS machines — the passphrase already
gates the disk — and off without it, where the greeter is the only thing
between power-on and the desktop.
Both had to become state-owned to be toggleable at all, which surfaced two
real bugs:
* nomarchy.system.greeter.autoLogin defaulted from
`config.nomarchy.settings…` — an attribute that exists ONLY on the Home
Manager side. On NixOS it is absent and `or null` swallowed the error,
so the default silently evaluated to null on every machine ever built.
That is why the installer baked a Nix line: the state path never
worked. Now read via theme-state-read.nix (the hardware.nix/timezone.nix
pattern) and mkDefault'd, so the menu owns it and a hand-set line still
pins it. Two more options read the same phantom bridge — BACKLOG #116.
* `theme-sync get` printed Python's "None" for a JSON null, so every
`case … null)` a caller writes would miss. Now prints "null", as the
comment above it already promised for booleans.
The installer seeds the state instead of emitting the system.nix line,
because that line outranks the state and would strand the toggle.
V1 (V3 pending: HARDWARE-QUEUE). nix flake check --no-build, installer-
safety and option-docs all pass. Proved by eval/build, not assumed: a state
carrying autoLogin yields greetd initial_session {"user":"bernardo"}, the
template state (no autoLogin) yields none, and a hand-set null beats a state
that says otherwise; a state with only fingerprint.pam=true — nothing set by
hand — renders the hyprlock auth.fingerprint block; both new tools pass
bash -n and land in systemPackages (nomarchy-fingerprint only with a
reader); the patcher writes settings.greeter.autoLogin and no system.nix
line; and the get round trip prints null, so the menu reads "Auto-login
(off)" where it would have read "(on)".
The reader itself, the two rebuilds, and the reboot are hardware — queued.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -282,7 +282,7 @@ option, e.g. `services.easyeffects.enable = lib.mkForce false;` — see
|
|||||||
| `nomarchy.system.stateFile` | `null` | theme-state.json for the system-side consumers (the Plymouth tint); `lib.mkFlake` wires it for you — set it only when composing the modules by hand |
|
| `nomarchy.system.stateFile` | `null` | theme-state.json for the system-side consumers (the Plymouth tint); `lib.mkFlake` wires it for you — set it only when composing the modules by hand |
|
||||||
| `nomarchy.system.fileManager.enable` | `true` | Thunar GUI + gvfs/tumbler/udisks2 (the "open folder" handler) |
|
| `nomarchy.system.fileManager.enable` | `true` | Thunar GUI + gvfs/tumbler/udisks2 (the "open folder" handler) |
|
||||||
| `nomarchy.system.greeter.enable` | `true` | greetd/tuigreet |
|
| `nomarchy.system.greeter.enable` | `true` | greetd/tuigreet |
|
||||||
| `nomarchy.system.greeter.autoLogin` | `null` | Auto-login this user into Hyprland (installer sets it on LUKS machines) |
|
| `nomarchy.system.greeter.autoLogin` | state | Auto-login this user into Hyprland. Owned by System › Auto-login (`settings.greeter.autoLogin`; installer seeds it on LUKS machines) — set it here only to pin it against the menu |
|
||||||
| `nomarchy.system.audio.enable` | `true` | PipeWire stack; WirePlumber priority rules provide HDMI/USB preference/fallback, while the Home Manager dock watcher performs the fresh-display reprobe and explicit default selection |
|
| `nomarchy.system.audio.enable` | `true` | PipeWire stack; WirePlumber priority rules provide HDMI/USB preference/fallback, while the Home Manager dock watcher performs the fresh-display reprobe and explicit default selection |
|
||||||
| `nomarchy.system.bluetooth.enable` | `true` | Bluetooth + blueman |
|
| `nomarchy.system.bluetooth.enable` | `true` | Bluetooth + blueman |
|
||||||
| `nomarchy.system.autoTimezone.enable` | `false` | Automatic timezone (geoclue + automatic-timezoned) — the clock follows your location; toggle from System › Auto timezone (a menu enable rebuilds: it has to unset the static `time.timeZone`) |
|
| `nomarchy.system.autoTimezone.enable` | `false` | Automatic timezone (geoclue + automatic-timezoned) — the clock follows your location; toggle from System › Auto timezone (a menu enable rebuilds: it has to unset the static `time.timeZone`) |
|
||||||
|
|||||||
@@ -95,6 +95,59 @@ pre-existing ISO-pinning gap.
|
|||||||
|
|
||||||
## NEXT
|
## NEXT
|
||||||
|
|
||||||
|
### 115. Suspend-then-hibernate, with a way to set it up
|
||||||
|
|
||||||
|
Bernardo, 2026-07-14: a suspended laptop should be able to fall through to
|
||||||
|
hibernate after a while, so a bag-carried machine stops draining, and setting
|
||||||
|
that up must be easy — not a systemd-sleep man-page trip.
|
||||||
|
|
||||||
|
The mechanism is `systemd`'s `suspend-then-hibernate` plus
|
||||||
|
`HibernateDelaySec`; the work is the surfacing, and the constraints are
|
||||||
|
already in the tree. Hibernate needs the resume offset + swap the installer
|
||||||
|
detects (`resumeOffset`/`rootUuid` in patch-template.py) — on a machine
|
||||||
|
without them this must self-gate, not fail at suspend time, the way Battery
|
||||||
|
limit gates on a battery. `modules/nixos/default.nix` already declines to
|
||||||
|
hyprlock before an encrypted hibernate (the LUKS resume gates it); check that
|
||||||
|
reasoning still holds when the suspend leads to hibernate. Menu placement: it
|
||||||
|
belongs with the power settings, not the root (§ menu placement convention).
|
||||||
|
|
||||||
|
Settle first (`[human]`): whether the delay is a preset list (30 min / 1 h /
|
||||||
|
2 h / never) or a free-form entry, and whether it applies on battery only or
|
||||||
|
always — the same on-AC question `modules/home/idle.nix`'s suspend listener
|
||||||
|
already answers with `${onAc} ||`.
|
||||||
|
|
||||||
|
In-flake state like the rest (`settings.*`), menu-writable, and read via
|
||||||
|
`theme-state-read.nix` on the NixOS side — NOT `config.nomarchy.settings`,
|
||||||
|
which does not exist there (see #116). Pass = the toggle survives a rebuild,
|
||||||
|
a suspended machine hibernates after the configured delay and resumes, and a
|
||||||
|
machine without hibernate support hides the row instead of offering a
|
||||||
|
suspend that never wakes.
|
||||||
|
|
||||||
|
### 116. Three NixOS options read a `config.nomarchy.settings` that does not exist
|
||||||
|
|
||||||
|
Found while wiring System › Auto-login (2026-07-14). `nomarchy.settings` is
|
||||||
|
declared and populated **only on the Home Manager side** (`modules/home/
|
||||||
|
options.nix`, filled by `theme.nix`). On the NixOS side the attribute is
|
||||||
|
absent, and `or <fallback>` swallows the missing-attribute error — so these
|
||||||
|
defaults have silently always been their fallback on every machine:
|
||||||
|
|
||||||
|
- `nomarchy.system.greeter.autoLogin` — **fixed in this commit** (now reads
|
||||||
|
the state via `theme-state-read.nix` in `greeter.nix`, the working pattern
|
||||||
|
from `hardware.nix`/`timezone.nix`). Left here as the worked example.
|
||||||
|
- `modules/nixos/options.nix` `bluetooth.enable` — `settings.bluetooth.enable`
|
||||||
|
never read; benign today (fallback `true` = the intended default) but the
|
||||||
|
state key is dead.
|
||||||
|
- `modules/nixos/options.nix` `power.batteryChargeLimit` — `settings.power.
|
||||||
|
batteryChargeLimit` never read; the Battery limit menu works because it
|
||||||
|
patches the baked option in `system.nix` instead, which is the older model.
|
||||||
|
|
||||||
|
Decide per option whether the state key should work (wire it like the
|
||||||
|
greeter) or the phantom read should just go. The trap is that `or` makes both
|
||||||
|
a live bridge and a dead one look identical — a grep for
|
||||||
|
`config.nomarchy.settings` under `modules/nixos/` should return nothing when
|
||||||
|
this is done. Pass = no NixOS option claims a state default it cannot read,
|
||||||
|
and any bridge kept is proved by an eval that flips with the state file.
|
||||||
|
|
||||||
### 107. Rename `theme.json` to reflect that it is the system state
|
### 107. Rename `theme.json` to reflect that it is the system state
|
||||||
|
|
||||||
The state file long ago stopped being about themes: it carries night-light,
|
The state file long ago stopped being about themes: it carries night-light,
|
||||||
|
|||||||
@@ -181,9 +181,24 @@ the **T14s** (webcam case).
|
|||||||
authentication daemon to re-prove an evaluated invariant is a bad trade.
|
authentication daemon to re-prove an evaluated invariant is a bad trade.
|
||||||
- [ ] **#55 fingerprint enroll on real reader** — with
|
- [ ] **#55 fingerprint enroll on real reader** — with
|
||||||
`nomarchy.hardware.fingerprint.enable` and a physical reader: System ›
|
`nomarchy.hardware.fingerprint.enable` and a physical reader: System ›
|
||||||
Fingerprint › Enroll a finger; List shows it; Verify succeeds; optional
|
Fingerprint › Enroll a finger; List shows it; Verify succeeds.
|
||||||
Use for login (on) → `nomarchy-rebuild` → login/sudo accept fingerprint.
|
Enroll/List/Verify verified on hardware 2026-07-14 (T14s); the
|
||||||
Menu surface is V1/V2 without a reader (self-gate + dry paths).
|
remaining unknown is a reader-less machine's self-gate.
|
||||||
|
- [ ] **fingerprint + auto-login toggles on hardware** (this commit) — on the
|
||||||
|
T14s, after removing the pinning lines from `~/.nomarchy/system.nix`
|
||||||
|
(`greeter.autoLogin`, `hardware.fingerprint.pam`):
|
||||||
|
1. System › Fingerprint shows **Fingerprint (on)** (state already true).
|
||||||
|
Toggle it off → terminal opens, sudo system rebuild + home switch →
|
||||||
|
toast "Fingerprint off". Expect: sudo now refuses the finger and asks
|
||||||
|
only for a password; the lock screen (SUPER+CTRL+L) shows no
|
||||||
|
"or scan your finger" line. Toggle back on → both return.
|
||||||
|
2. With fingerprint OFF and no finger enrolled, the toggle must REFUSE
|
||||||
|
with "Enroll a finger first" and write nothing.
|
||||||
|
3. System › Auto-login shows **(on)**. Toggle off → sudo rebuild →
|
||||||
|
reboot → tuigreet asks, and accepts password OR finger (fingerprint
|
||||||
|
on). Toggle back on → reboot → straight to the session, no prompt.
|
||||||
|
Expected throughout: the two are independent, and auto-login on means
|
||||||
|
no boot prompt regardless of the fingerprint switch.
|
||||||
- [ ] **#60 non-BAT* battery name (if available)** — on a machine whose
|
- [ ] **#60 non-BAT* battery name (if available)** — on a machine whose
|
||||||
system battery is **not** named `BAT*` (e.g. `CMB0`): confirm
|
system battery is **not** named `BAT*` (e.g. `CMB0`): confirm
|
||||||
charge-limit oneshot writes the threshold, System › Battery limit
|
charge-limit oneshot writes the threshold, System › Battery limit
|
||||||
|
|||||||
@@ -173,9 +173,18 @@ nomarchy.hardware.fingerprint.enable = true; # services.fprintd
|
|||||||
### Enroll (menu or CLI)
|
### Enroll (menu or CLI)
|
||||||
|
|
||||||
**Shipped #55:** System › Fingerprint (self-gated when `fprintd-list` is
|
**Shipped #55:** System › Fingerprint (self-gated when `fprintd-list` is
|
||||||
on PATH) — Enroll / List / Verify / Delete all, plus **Use for login**
|
on PATH) — a single **Fingerprint (on/off)** switch, plus Enroll / List /
|
||||||
which writes `settings.fingerprint.pam` and applies on the next
|
Verify / Delete all (all usable while it's off — turning it on needs an
|
||||||
`sys-rebuild` (option default follows theme-state.json).
|
enrolled finger). The switch writes `settings.fingerprint.pam`, the one
|
||||||
|
state key behind *both* halves of "use my finger": login/sudo PAM here,
|
||||||
|
and the lock-screen unlock in `modules/home/idle.nix`. It runs
|
||||||
|
`nomarchy-fingerprint`, which sudos a system rebuild and then a home
|
||||||
|
switch, because the two halves live in different configurations.
|
||||||
|
|
||||||
|
It does **not** decide whether login prompts at all: auto-login skips the
|
||||||
|
greeter entirely, so this adds the finger to the prompts that actually
|
||||||
|
happen — sudo, the lock screen, and the greeter only when
|
||||||
|
[auto-login](#auto-login) is off.
|
||||||
|
|
||||||
**Hints (#73):** MOTD line when `fingerprint.enable` is on; first-boot
|
**Hints (#73):** MOTD line when `fingerprint.enable` is on; first-boot
|
||||||
tip when `fprintd-list` is on PATH (`SUPER+M → System › Fingerprint` /
|
tip when `fprintd-list` is on PATH (`SUPER+M → System › Fingerprint` /
|
||||||
@@ -185,12 +194,34 @@ tip when `fprintd-list` is on PATH (`SUPER+M → System › Fingerprint` /
|
|||||||
# CLI still works:
|
# CLI still works:
|
||||||
fprintd-enroll
|
fprintd-enroll
|
||||||
fprintd-list "$USER"
|
fprintd-list "$USER"
|
||||||
# or: System › Fingerprint › Use for login (on) → sys-rebuild
|
nomarchy-fingerprint toggle # or on | off | status — what the menu row runs
|
||||||
```
|
```
|
||||||
|
|
||||||
PAM stays opt-in on purpose: password-only remains the cautious default
|
PAM stays opt-in on purpose: password-only remains the cautious default
|
||||||
until a finger is enrolled. Full enroll on a real reader is V3/hardware.
|
until a finger is enrolled. Full enroll on a real reader is V3/hardware.
|
||||||
|
|
||||||
|
### Auto-login
|
||||||
|
|
||||||
|
`settings.greeter.autoLogin` (System › Auto-login, or `nomarchy-autologin
|
||||||
|
[toggle|on|off|status]`) decides whether boot goes straight to the desktop
|
||||||
|
or stops at the greeter. The installer seeds it ON for LUKS-encrypted
|
||||||
|
machines — the disk passphrase already gates the machine, so a greeter
|
||||||
|
password is a second prompt for the same thing — and leaves it off
|
||||||
|
without LUKS, where the greeter is the only thing between power-on and the
|
||||||
|
desktop. It's baked into greetd at system rebuild, so the change shows on
|
||||||
|
the next boot.
|
||||||
|
|
||||||
|
Auto-login and fingerprint are independent, and auto-login wins at boot:
|
||||||
|
with it on you are never asked for anything at startup, whatever the
|
||||||
|
fingerprint switch says. Turn auto-login off and the greeter asks — for a
|
||||||
|
password, or a password *or* finger when fingerprint is on.
|
||||||
|
|
||||||
|
Both are in-flake state rather than lines in `system.nix` on purpose: a
|
||||||
|
hand-set `nomarchy.system.greeter.autoLogin` (or
|
||||||
|
`nomarchy.hardware.fingerprint.pam`) outranks the state and pins the
|
||||||
|
setting, leaving the menu toggle unable to move it. That's the escape
|
||||||
|
hatch, not the default — leave those lines commented to use the menu.
|
||||||
|
|
||||||
### Parallel prompt (password *or* finger, whichever first)
|
### Parallel prompt (password *or* finger, whichever first)
|
||||||
|
|
||||||
With `fingerprint.pam` on, sudo/login/hyprlock show **one** prompt that
|
With `fingerprint.pam` on, sudo/login/hyprlock show **one** prompt that
|
||||||
|
|||||||
@@ -169,10 +169,11 @@ ryzenadj)**, **no Secure Boot**, and the **stateVersion override**.
|
|||||||
nomarchy.hardware.amd.enable = true; # amd-pstate + radeonsi VA-API
|
nomarchy.hardware.amd.enable = true; # amd-pstate + radeonsi VA-API
|
||||||
# nomarchy.hardware.amd.rocm.enable = true; # opt-in GPU compute (multi-GB)
|
# nomarchy.hardware.amd.rocm.enable = true; # opt-in GPU compute (multi-GB)
|
||||||
|
|
||||||
# LUKS machines: the disk passphrase already gates access, so boot
|
# Auto-login is NOT set here: it lives in theme-state.json
|
||||||
# straight into the session — this is what nomarchy-install sets on
|
# (settings.greeter.autoLogin) so System › Auto-login can move it — a line
|
||||||
# encrypted installs. Omit it on unencrypted machines.
|
# here would outrank the state and pin it. Turn it on after the first boot
|
||||||
nomarchy.system.greeter.autoLogin = username;
|
# with `nomarchy-autologin on` (what nomarchy-install seeds on encrypted
|
||||||
|
# installs: the LUKS passphrase already gates access).
|
||||||
|
|
||||||
# CRITICAL: keep your ORIGINAL install's value — never Nomarchy's 26.05.
|
# CRITICAL: keep your ORIGINAL install's value — never Nomarchy's 26.05.
|
||||||
system.stateVersion = "24.11";
|
system.stateVersion = "24.11";
|
||||||
|
|||||||
@@ -367,23 +367,29 @@ 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; };
|
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; };
|
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.enable = lib.mkEnableOption "hyprlock + hypridle (idle lock, display off, suspend)" // { default = true; };
|
||||||
idle.fingerprint = lib.mkEnableOption ''
|
idle.fingerprint = lib.mkOption {
|
||||||
unlocking the lock screen with a fingerprint as well as the password,
|
type = lib.types.bool;
|
||||||
and saying so on the input field.
|
default = config.nomarchy.settings.fingerprint.pam or false;
|
||||||
|
defaultText = lib.literalExpression
|
||||||
|
"(settings.fingerprint.pam from theme-state.json) or false";
|
||||||
|
description = ''
|
||||||
|
Unlock the lock screen with a fingerprint as well as the password, and
|
||||||
|
say so on the input field.
|
||||||
|
|
||||||
Mirrors `nomarchy.hardware.fingerprint.pam` in system.nix — keep the two
|
Reads the SAME `settings.fingerprint.pam` state key that
|
||||||
matched, the same way `nomarchy.keyboard.layout` matches
|
`nomarchy.hardware.fingerprint.pam` defaults from, so the one
|
||||||
`services.xserver.xkb.layout`. It cannot be derived: hyprlock is
|
System › Fingerprint toggle moves the lock screen and login/sudo
|
||||||
configured here, in standalone Home Manager, which has no `osConfig` to
|
together — "fingerprint on" is one decision, not two that can drift.
|
||||||
read the NixOS side from.
|
(It has to arrive by state, not by reading the NixOS side: hyprlock is
|
||||||
|
configured here, in standalone Home Manager, which has no `osConfig`.)
|
||||||
|
|
||||||
Deliberately separate from the PAM flag rather than implied by it:
|
The two remain separate *mechanisms*, which is why this option still
|
||||||
hyprlock does NOT unlock by fingerprint through PAM. Its PAM stack only
|
exists to be set by hand: hyprlock does NOT unlock by fingerprint
|
||||||
runs on submit, so a parallel module never gets to poll — hyprlock has
|
through PAM. Its PAM stack only runs on submit, so a parallel module
|
||||||
its own fprintd-over-D-Bus backend instead, and this is the switch for
|
never gets to poll — hyprlock has its own fprintd-over-D-Bus backend
|
||||||
it. With no reader present it advertises a scan that cannot happen, so
|
instead, and this is the switch for it.
|
||||||
it stays opt-in
|
'';
|
||||||
'';
|
};
|
||||||
yazi.enable = lib.mkEnableOption "the yazi TUI file manager, themed with a curated plugin set" // { default = true; };
|
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; };
|
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; };
|
shell.enable = lib.mkEnableOption "the zsh shell experience (starship prompt, bat/eza/zoxide)" // { default = true; };
|
||||||
|
|||||||
@@ -901,6 +901,16 @@ ${themeRows}
|
|||||||
|| { notify-send "Auto timezone" "Unavailable on this machine."; exit 0; }
|
|| { notify-send "Auto timezone" "Unavailable on this machine."; exit 0; }
|
||||||
exec ${cfg.terminal} -e nomarchy-autotimezone toggle ;;
|
exec ${cfg.terminal} -e nomarchy-autotimezone toggle ;;
|
||||||
|
|
||||||
|
autologin)
|
||||||
|
# Toggle booting straight into the session (greetd initial_session).
|
||||||
|
# A SYSTEM setting baked at rebuild, so this sudos a system switch in
|
||||||
|
# a terminal, like Auto timezone — and the change shows on the NEXT
|
||||||
|
# boot, not now. Off is what makes the greeter ask for a password (or
|
||||||
|
# a finger, when System › Fingerprint is on).
|
||||||
|
command -v nomarchy-autologin >/dev/null 2>&1 \
|
||||||
|
|| { notify-send "Auto-login" "Unavailable on this machine."; exit 0; }
|
||||||
|
exec ${cfg.terminal} -e nomarchy-autologin toggle ;;
|
||||||
|
|
||||||
autocommit)
|
autocommit)
|
||||||
# Toggle opt-in auto-commit: every menu/theme mutation also commits
|
# Toggle opt-in auto-commit: every menu/theme mutation also commits
|
||||||
# theme-state.json (that file only) in the downstream flake, so
|
# theme-state.json (that file only) in the downstream flake, so
|
||||||
@@ -977,13 +987,17 @@ ${themeRows}
|
|||||||
command -v fprintd-list >/dev/null 2>&1 \
|
command -v fprintd-list >/dev/null 2>&1 \
|
||||||
|| { notify-send "Fingerprint" "fprintd not available (nomarchy.hardware.fingerprint.enable?)."; exit 0; }
|
|| { notify-send "Fingerprint" "fprintd not available (nomarchy.hardware.fingerprint.enable?)."; exit 0; }
|
||||||
pam=$(nomarchy-theme-sync get settings.fingerprint.pam 2>/dev/null || echo false)
|
pam=$(nomarchy-theme-sync get settings.fingerprint.pam 2>/dev/null || echo false)
|
||||||
case "$pam" in true|True) pam_label="Use for login (on)" ;; *) pam_label="Use for login (off)" ;; esac
|
case "$pam" in true|True) pam_label="Fingerprint (on)" ;; *) pam_label="Fingerprint (off)" ;; esac
|
||||||
choice=$( {
|
choice=$( {
|
||||||
|
# The switch leads: it is the decision this menu exists for, and
|
||||||
|
# the rest (enroll/list/verify/delete) is the plumbing behind it —
|
||||||
|
# all still usable while the switch is off, since turning it on
|
||||||
|
# requires an enrolled finger.
|
||||||
|
row "$pam_label" system-lock-screen
|
||||||
row "Enroll finger" preferences-desktop-user-password
|
row "Enroll finger" preferences-desktop-user-password
|
||||||
row "List enrolled" view-list
|
row "List enrolled" view-list
|
||||||
row "Verify" dialog-password
|
row "Verify" dialog-password
|
||||||
row "Delete all" edit-delete
|
row "Delete all" edit-delete
|
||||||
row "$pam_label" system-lock-screen
|
|
||||||
back
|
back
|
||||||
} | rofi_menu -show-icons -p Fingerprint) || exit 0
|
} | rofi_menu -show-icons -p Fingerprint) || exit 0
|
||||||
case "$choice" in
|
case "$choice" in
|
||||||
@@ -1013,17 +1027,15 @@ ${themeRows}
|
|||||||
*) echo "Cancelled." ;;
|
*) echo "Cancelled." ;;
|
||||||
esac
|
esac
|
||||||
printf "\nEnter to close."; read -r _' ;;
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
*"Use for login"*)
|
*"Fingerprint ("*)
|
||||||
case "$pam" in true|True) new=false ;; *) new=true ;; esac
|
# Drives BOTH sides off one state key (sudo/login PAM + the
|
||||||
if [ "$new" = true ]; then
|
# hyprlock unlock), so it sudos a system rebuild and runs a home
|
||||||
if fprintd-list "$USER" 2>/dev/null | grep -qiE 'no fingers enrolled|No devices available'; then
|
# switch — in a terminal, like Auto timezone. The enrolled-finger
|
||||||
notify-send "Fingerprint" "Enroll a finger first, then enable login."
|
# guard and the state write live in the tool, so the CLI and this
|
||||||
exit 0
|
# row can't disagree.
|
||||||
fi
|
command -v nomarchy-fingerprint >/dev/null 2>&1 \
|
||||||
fi
|
|| { notify-send "Fingerprint" "nomarchy-fingerprint not on PATH (hardware.fingerprint.enable?)."; exit 0; }
|
||||||
nomarchy-theme-sync --quiet set settings.fingerprint.pam "$new" --no-switch
|
exec ${cfg.terminal} -e nomarchy-fingerprint toggle ;;
|
||||||
notify-send "Fingerprint" "Use for login: $new — applies on next nomarchy-rebuild."
|
|
||||||
;;
|
|
||||||
esac ;;
|
esac ;;
|
||||||
|
|
||||||
controlcenter)
|
controlcenter)
|
||||||
@@ -1139,6 +1151,17 @@ ${themeRows}
|
|||||||
then row "Auto timezone (on)" preferences-system-time
|
then row "Auto timezone (on)" preferences-system-time
|
||||||
else row "Auto timezone (off)" preferences-system-time
|
else row "Auto timezone (off)" preferences-system-time
|
||||||
fi
|
fi
|
||||||
|
# Auto-login — self-gated on the tool (greeter.enable). Off = the
|
||||||
|
# greeter asks; that's the prompt the Fingerprint switch feeds.
|
||||||
|
if command -v nomarchy-autologin >/dev/null 2>&1; then
|
||||||
|
# Unset (get exits 1, empty) and null both read as off. "None" is
|
||||||
|
# what an older theme-sync printed for null — accepted so a menu
|
||||||
|
# from a newer generation can't misreport against an older tool.
|
||||||
|
case "$(nomarchy-theme-sync get settings.greeter.autoLogin 2>/dev/null)" in
|
||||||
|
null|""|None) row "Auto-login (off)" system-users ;;
|
||||||
|
*) row "Auto-login (on)" system-users ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
if [ -e "''${NOMARCHY_PATH:-$HOME/.nomarchy}/.git" ]; then
|
if [ -e "''${NOMARCHY_PATH:-$HOME/.nomarchy}/.git" ]; then
|
||||||
if [ "$(nomarchy-theme-sync get settings.autoCommit 2>/dev/null)" = true ]
|
if [ "$(nomarchy-theme-sync get settings.autoCommit 2>/dev/null)" = true ]
|
||||||
then row "Auto-commit (on)" git
|
then row "Auto-commit (on)" git
|
||||||
@@ -1178,6 +1201,7 @@ ${themeRows}
|
|||||||
*Printers*) exec "$0" printers ;;
|
*Printers*) exec "$0" printers ;;
|
||||||
*"Do Not Disturb"*) exec "$0" dnd ;;
|
*"Do Not Disturb"*) exec "$0" dnd ;;
|
||||||
*"Auto timezone"*) exec "$0" autotimezone ;;
|
*"Auto timezone"*) exec "$0" autotimezone ;;
|
||||||
|
*"Auto-login"*) exec "$0" autologin ;;
|
||||||
*"Auto-commit"*) exec "$0" autocommit ;;
|
*"Auto-commit"*) exec "$0" autocommit ;;
|
||||||
*Snapshots*) exec "$0" snapshot ;;
|
*Snapshots*) exec "$0" snapshot ;;
|
||||||
*Rollback*) exec "$0" rollback ;;
|
*Rollback*) exec "$0" rollback ;;
|
||||||
@@ -1294,7 +1318,7 @@ ${themeRows}
|
|||||||
esac ;;
|
esac ;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|keyboard|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autocommit|vpn|snapshot|doctor|firmware|fingerprint|controlcenter|rollback|whatchanged]" >&2
|
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|keyboard|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autologin|autocommit|vpn|snapshot|doctor|firmware|fingerprint|controlcenter|rollback|whatchanged]" >&2
|
||||||
exit 64 ;;
|
exit 64 ;;
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -14,16 +14,67 @@
|
|||||||
# theme's colors). ANSI "black" stays dark even in light themes —
|
# theme's colors). ANSI "black" stays dark even in light themes —
|
||||||
# the greeter reads terminal-dark there, the same convention every
|
# the greeter reads terminal-dark there, the same convention every
|
||||||
# terminal applies to ANSI colors.
|
# terminal applies to ANSI colors.
|
||||||
|
#
|
||||||
|
# Auto-login is in-flake state like the rest (settings.greeter.autoLogin,
|
||||||
|
# written by System › Auto-login via nomarchy-autologin below), NOT a baked
|
||||||
|
# line in system.nix: a hand-set `nomarchy.system.greeter.autoLogin` outranks
|
||||||
|
# the state default, which would leave the menu toggle flipping JSON that
|
||||||
|
# nothing reads. The installer therefore seeds the STATE on LUKS machines and
|
||||||
|
# the template keeps its example commented (templates/downstream/system.nix).
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.nomarchy.system;
|
cfg = config.nomarchy.system;
|
||||||
distroName = config.system.nixos.distroName;
|
distroName = config.system.nixos.distroName;
|
||||||
|
|
||||||
|
sync = lib.getExe pkgs.nomarchy-theme-sync;
|
||||||
|
|
||||||
|
# Menu/CLI toggle, same shape as nomarchy-autotimezone: runs as the normal
|
||||||
|
# user (it owns the flake checkout + writes the state), sudos only the
|
||||||
|
# system switch. greetd's initial_session is baked at system rebuild, so
|
||||||
|
# there is nothing to apply live — the next boot is the observable change.
|
||||||
|
nomarchy-autologin = pkgs.writeShellScriptBin "nomarchy-autologin" ''
|
||||||
|
set -e
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
echo "nomarchy-autologin: run as your normal user (it sudos the rebuild itself)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}"
|
||||||
|
|
||||||
|
cur=$(${sync} get settings.greeter.autoLogin 2>/dev/null) || cur=null
|
||||||
|
case "''${1:-toggle}" in
|
||||||
|
on) new="\"$USER\"" ;;
|
||||||
|
off) new=null ;;
|
||||||
|
toggle) case "$cur" in null|""|None) new="\"$USER\"" ;; *) new=null ;; esac ;;
|
||||||
|
status) echo "$cur"; exit 0 ;;
|
||||||
|
*) echo "usage: nomarchy-autologin [toggle|on|off|status]" >&2; exit 64 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
${sync} --quiet set settings.greeter.autoLogin "$new" --no-switch
|
||||||
|
|
||||||
|
notify-send "Auto-login" "Rebuilding the system…" 2>/dev/null || true
|
||||||
|
sudo nixos-rebuild switch --flake "$flake#default"
|
||||||
|
|
||||||
|
if [ "$new" = null ]; then
|
||||||
|
notify-send "Auto-login off" "The greeter asks who you are on the next boot." 2>/dev/null || true
|
||||||
|
else
|
||||||
|
notify-send "Auto-login on" "Next boot goes straight to the desktop." 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
state =
|
state =
|
||||||
if cfg.stateFile != null
|
if cfg.stateFile != null
|
||||||
then builtins.fromJSON (builtins.readFile cfg.stateFile)
|
then builtins.fromJSON (builtins.readFile cfg.stateFile)
|
||||||
else { };
|
else { };
|
||||||
|
|
||||||
|
# The auto-login user from the state, or null. Read here via the state file
|
||||||
|
# — NOT `config.nomarchy.settings`, which exists only on the Home Manager
|
||||||
|
# side: on NixOS that attribute is missing, and `or null` swallows the
|
||||||
|
# error, so the old default silently evaluated to null on every machine.
|
||||||
|
stateAutoLogin =
|
||||||
|
let v = (state.settings or { }).greeter.autoLogin or null;
|
||||||
|
in if builtins.isString v && v != "" then v else null;
|
||||||
|
|
||||||
# A sparse/hand-rolled state without a proper ansi block just skips the
|
# A sparse/hand-rolled state without a proper ansi block just skips the
|
||||||
# theming (stock tuigreet grey) — never an eval error.
|
# theming (stock tuigreet grey) — never an eval error.
|
||||||
ansi = state.ansi or [ ];
|
ansi = state.ansi or [ ];
|
||||||
@@ -44,6 +95,15 @@ let
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
|
# Shipped unconditionally so the menu can turn auto-login back ON while
|
||||||
|
# it's off — the same reason nomarchy-autotimezone is unconditional.
|
||||||
|
environment.systemPackages = [ nomarchy-autologin ];
|
||||||
|
|
||||||
|
# Track the in-flake flag; mkDefault so a hand-set
|
||||||
|
# nomarchy.system.greeter.autoLogin in system.nix still wins (the
|
||||||
|
# autoTimezone pattern).
|
||||||
|
nomarchy.system.greeter.autoLogin = lib.mkDefault stateAutoLogin;
|
||||||
|
|
||||||
# VT palette from the theme (RRGGBB, no #; lands as vt.default_* kernel
|
# VT palette from the theme (RRGGBB, no #; lands as vt.default_* kernel
|
||||||
# params). mkDefault so a downstream console.colors wins.
|
# params). mkDefault so a downstream console.colors wins.
|
||||||
console.colors = lib.mkIf themed (lib.mkDefault (map (lib.removePrefix "#") ansi));
|
console.colors = lib.mkIf themed (lib.mkDefault (map (lib.removePrefix "#") ansi));
|
||||||
|
|||||||
@@ -23,6 +23,58 @@ let
|
|||||||
then import ../theme-state-read.nix { inherit lib; } config.nomarchy.system.stateFile
|
then import ../theme-state-read.nix { inherit lib; } config.nomarchy.system.stateFile
|
||||||
else { };
|
else { };
|
||||||
pamFromState = (hwState.settings or { }).fingerprint.pam or false;
|
pamFromState = (hwState.settings or { }).fingerprint.pam or false;
|
||||||
|
|
||||||
|
sync = lib.getExe pkgs.nomarchy-theme-sync;
|
||||||
|
|
||||||
|
# The single fingerprint on/off switch (System › Fingerprint). One state key
|
||||||
|
# for one user-facing decision — it drives login/sudo PAM here AND the
|
||||||
|
# hyprlock unlock in modules/home/idle.nix, which reads the same
|
||||||
|
# settings.fingerprint.pam. Two rebuilds, because the two live in different
|
||||||
|
# configurations: sudo the system switch (PAM), then a home switch
|
||||||
|
# (hyprlock). Same user-owns-the-flake shape as nomarchy-autotimezone.
|
||||||
|
#
|
||||||
|
# This does NOT decide whether login prompts at all — auto-login skips the
|
||||||
|
# greeter entirely, so "fingerprint on" adds the finger to whatever prompts
|
||||||
|
# actually happen (sudo, lock screen, and the greeter only when auto-login
|
||||||
|
# is off). See nomarchy-autologin in ./greeter.nix.
|
||||||
|
nomarchy-fingerprint = pkgs.writeShellScriptBin "nomarchy-fingerprint" ''
|
||||||
|
set -e
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
echo "nomarchy-fingerprint: run as your normal user (it sudos the rebuild itself)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}"
|
||||||
|
|
||||||
|
cur=$(${sync} get settings.fingerprint.pam 2>/dev/null) || cur=false
|
||||||
|
case "''${1:-toggle}" in
|
||||||
|
on) new=true ;;
|
||||||
|
off) new=false ;;
|
||||||
|
toggle) case "$cur" in true|True) new=false ;; *) new=true ;; esac ;;
|
||||||
|
status) echo "$cur"; exit 0 ;;
|
||||||
|
*) echo "usage: nomarchy-fingerprint [toggle|on|off|status]" >&2; exit 64 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Turning it ON with no enrolled finger would advertise a scan that cannot
|
||||||
|
# succeed on every prompt — refuse instead, and say where to go.
|
||||||
|
if [ "$new" = true ] \
|
||||||
|
&& fprintd-list "$USER" 2>/dev/null | grep -qiE 'no fingers enrolled|No devices available'; then
|
||||||
|
notify-send "Fingerprint" "Enroll a finger first (System › Fingerprint › Enroll)." 2>/dev/null || true
|
||||||
|
echo "nomarchy-fingerprint: no finger enrolled — run fprintd-enroll first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
${sync} --quiet set settings.fingerprint.pam "$new" --no-switch
|
||||||
|
|
||||||
|
notify-send "Fingerprint" "Rebuilding…" 2>/dev/null || true
|
||||||
|
sudo nixos-rebuild switch --flake "$flake#default"
|
||||||
|
home-manager switch --flake "$flake"
|
||||||
|
|
||||||
|
if [ "$new" = true ]; then
|
||||||
|
notify-send "Fingerprint on" "Password or finger — at sudo, the lock screen, and the greeter." 2>/dev/null || true
|
||||||
|
else
|
||||||
|
notify-send "Fingerprint off" "Password only. Enrolled fingers are kept." 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.nomarchy.hardware = {
|
options.nomarchy.hardware = {
|
||||||
@@ -214,6 +266,9 @@ in
|
|||||||
# every interactive service we care about to follow our opt-in flag.
|
# every interactive service we care about to follow our opt-in flag.
|
||||||
(lib.mkIf cfg.fingerprint.enable {
|
(lib.mkIf cfg.fingerprint.enable {
|
||||||
services.fprintd.enable = true;
|
services.fprintd.enable = true;
|
||||||
|
# Ships whenever a reader exists, regardless of the pam flag: the
|
||||||
|
# toggle's whole job is to turn the flag back on while it's off.
|
||||||
|
environment.systemPackages = [ nomarchy-fingerprint ];
|
||||||
security.pam.services = lib.genAttrs [
|
security.pam.services = lib.genAttrs [
|
||||||
"login" "sudo" "su" "greetd" "hyprlock" "sshd"
|
"login" "sudo" "su" "greetd" "hyprlock" "sshd"
|
||||||
"passwd" "chsh" "chfn" "chpasswd"
|
"passwd" "chsh" "chfn" "chpasswd"
|
||||||
|
|||||||
@@ -11,13 +11,20 @@
|
|||||||
|
|
||||||
greeter.autoLogin = lib.mkOption {
|
greeter.autoLogin = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = config.nomarchy.settings.greeter.autoLogin or null;
|
default = null;
|
||||||
|
defaultText = lib.literalExpression
|
||||||
|
"(settings.greeter.autoLogin from theme-state.json) or null";
|
||||||
example = "ada";
|
example = "ada";
|
||||||
description = ''
|
description = ''
|
||||||
Log this user straight into Hyprland on boot (greetd
|
Log this user straight into Hyprland on boot (greetd
|
||||||
initial_session); logging out lands on the normal greeter.
|
initial_session); logging out lands on the normal greeter.
|
||||||
The installer sets it on LUKS-encrypted machines — the disk
|
|
||||||
passphrase already gates access, a second prompt is ceremony.
|
Normally you leave this alone and use System › Auto-login, which
|
||||||
|
writes `settings.greeter.autoLogin` in theme-state.json —
|
||||||
|
./greeter.nix mkDefaults this option from it. The installer seeds
|
||||||
|
that state on LUKS-encrypted machines: the disk passphrase already
|
||||||
|
gates access, so a second prompt is ceremony. Setting this option by
|
||||||
|
hand pins the choice and the menu toggle can no longer move it.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -104,12 +104,10 @@ def build_installer_region(v: dict) -> str:
|
|||||||
" # active; heavier opt-ins stay in the commented catalog below.",
|
" # active; heavier opt-ins stay in the commented catalog below.",
|
||||||
]
|
]
|
||||||
|
|
||||||
if v.get("autoLogin"):
|
# Auto-login is deliberately NOT emitted here — it is seeded into
|
||||||
user = nix_str(v["username"])
|
# theme-state.json instead (patch_state). A line in system.nix outranks
|
||||||
lines += [
|
# the state default, which would make the System › Auto-login toggle
|
||||||
" # LUKS passphrase already gates this machine — skip the greeter password.",
|
# write JSON that nothing reads.
|
||||||
f' nomarchy.system.greeter.autoLogin = "{user}";',
|
|
||||||
]
|
|
||||||
|
|
||||||
if v.get("laptop"):
|
if v.get("laptop"):
|
||||||
lines += [
|
lines += [
|
||||||
@@ -250,6 +248,23 @@ def patch_system(text: str, v: dict) -> str:
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def patch_state(text: str, v: dict) -> str:
|
||||||
|
"""Seed menu-owned settings into theme-state.json.
|
||||||
|
|
||||||
|
These live in the state rather than system.nix precisely so the menu can
|
||||||
|
change them later: a baked Nix assignment would outrank the state default
|
||||||
|
and strand the toggle. Auto-login is on when the disk is encrypted — the
|
||||||
|
LUKS passphrase already gates the machine, so a greeter password is a
|
||||||
|
second prompt for the same thing; without LUKS it stays off, where the
|
||||||
|
greeter is the only thing standing between power-on and the desktop.
|
||||||
|
"""
|
||||||
|
state = json.loads(text)
|
||||||
|
settings = state.setdefault("settings", {})
|
||||||
|
if v.get("autoLogin"):
|
||||||
|
settings.setdefault("greeter", {})["autoLogin"] = v["username"]
|
||||||
|
return json.dumps(state, indent=2) + "\n"
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
sys.exit("usage: patch-template.py <flake-dir>")
|
sys.exit("usage: patch-template.py <flake-dir>")
|
||||||
@@ -260,6 +275,7 @@ def main() -> None:
|
|||||||
"flake.nix": patch_flake,
|
"flake.nix": patch_flake,
|
||||||
"home.nix": patch_home,
|
"home.nix": patch_home,
|
||||||
"system.nix": patch_system,
|
"system.nix": patch_system,
|
||||||
|
"theme-state.json": patch_state,
|
||||||
}
|
}
|
||||||
for name, fn in mapping.items():
|
for name, fn in mapping.items():
|
||||||
path = flake_dir / name
|
path = flake_dir / name
|
||||||
|
|||||||
@@ -589,10 +589,13 @@ def cmd_get(args) -> None:
|
|||||||
node = node[key]
|
node = node[key]
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
die(f"no such key: {args.path}")
|
die(f"no such key: {args.path}")
|
||||||
# Booleans print JSON-style (true/false, not Python's True/False) so
|
# Booleans and null print JSON-style (true/false/null, not Python's
|
||||||
# shell consumers can compare against the same literal they `set`.
|
# True/False/None) so shell consumers can compare against the same
|
||||||
|
# literal they `set`. null matters for genuinely-nullable keys like
|
||||||
|
# settings.greeter.autoLogin, where "None" would silently miss every
|
||||||
|
# `case ... null)` a caller writes.
|
||||||
print(json.dumps(node, indent=2)
|
print(json.dumps(node, indent=2)
|
||||||
if isinstance(node, (dict, list, bool)) else node)
|
if node is None or isinstance(node, (dict, list, bool)) else node)
|
||||||
else:
|
else:
|
||||||
print(json.dumps(state, indent=2))
|
print(json.dumps(state, indent=2))
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,13 @@
|
|||||||
# nomarchy.waybar.enable = false; # bring your own bar
|
# nomarchy.waybar.enable = false; # bring your own bar
|
||||||
# nomarchy.stylix.enable = false; # opt out of GTK/Qt theming
|
# nomarchy.stylix.enable = false; # opt out of GTK/Qt theming
|
||||||
# nomarchy.dockAudio.enable = false; # keep audio put when docking
|
# nomarchy.dockAudio.enable = false; # keep audio put when docking
|
||||||
# nomarchy.idle.fingerprint = true; # unlock the lock screen by finger too, and
|
# nomarchy.idle.fingerprint = true; # pin lock-screen finger unlock on/off. Normally
|
||||||
# # say so on the field. Set it alongside
|
# # you want System › Fingerprint instead: it moves
|
||||||
# # nomarchy.hardware.fingerprint.pam in
|
# # this AND login/sudo together off one state key,
|
||||||
# # system.nix — hyprlock is configured here
|
# # and this line would override it. Separate options
|
||||||
# # and cannot read the NixOS side, and it
|
# # only because hyprlock is configured here (it can't
|
||||||
# # does not take a finger through PAM at all.
|
# # read the NixOS side) and doesn't take a finger
|
||||||
|
# # through PAM at all — it has its own fprintd backend.
|
||||||
#
|
#
|
||||||
# Icon pack: Papirus ships by default (auto Dark/Light by theme mode) and
|
# 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`
|
# is the ONLY icon pack in your closure. To use another, set the `icons`
|
||||||
|
|||||||
@@ -62,7 +62,9 @@
|
|||||||
# amd.rocm.enable = true; # ROCm GPU compute (multi-GB, opt-in)
|
# amd.rocm.enable = true; # ROCm GPU compute (multi-GB, opt-in)
|
||||||
# amd.rocm.gfxOverride = "11.0.0"; # HSA override for an unlisted iGPU
|
# amd.rocm.gfxOverride = "11.0.0"; # HSA override for an unlisted iGPU
|
||||||
# fingerprint.enable = true; # fprintd; installer-set when a reader is detected
|
# fingerprint.enable = true; # fprintd; installer-set when a reader is detected
|
||||||
# fingerprint.pam = true; # use the fingerprint for login + sudo
|
# fingerprint.pam = true; # pin the fingerprint on/off instead of letting the
|
||||||
|
# # System › Fingerprint toggle own it (this line WINS
|
||||||
|
# # over the menu — leave it commented to use the menu)
|
||||||
# fingerprint.parallel = false; # sequential prompt instead of password-or-finger
|
# fingerprint.parallel = false; # sequential prompt instead of password-or-finger
|
||||||
# npu.enable = true; # on-die NPU driver (experimental; userspace runtime BYO)
|
# npu.enable = true; # on-die NPU driver (experimental; userspace runtime BYO)
|
||||||
# latestKernel = true; # newest kernel for very-new hardware (drivers not yet in the default)
|
# latestKernel = true; # newest kernel for very-new hardware (drivers not yet in the default)
|
||||||
|
|||||||
Reference in New Issue
Block a user