hyprlock doesn't poll fprintd by default — pam_authenticate() is
only invoked on password submission. Adding the auth.fingerprint
block tells hyprlock to launch fprintd polling in parallel with the
password input, so touching the reader unlocks immediately without
typing first.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final-review caveats:
- ARCHITECTURE.md hyprlock section was a generic one-liner inherited
from gtklock; now mentions fprintd integration + GPU + blur.
- hyprlock label blocks didn't set font_family; clock/date now
pinned to JetBrains Mono Nerd Font (same as rest of desktop).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace all gtklock mentions in README, ARCHITECTURE, CLAUDE.md with
hyprlock, and drop the stale gtklock consumer note from theme/colors.css
header comment (hyprlock uses Hyprlang, not CSS imports).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds hyprlock/hyprlock.conf with Tomorrow Night colors, replaces gtklock
with hyprlock in packages.txt, and updates install.sh to symlink
hyprlock.conf into ~/.config/hypr/ instead of the old gtklock symlinks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Discovered while re-adding network-manager-applet that the
networkmanager daemon was already installed locally but never tracked
in packages.txt. Track it now so a fresh install gets both the daemon
and the applet, making the README's NetworkManager activation step
work end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
snixembed registered as the StatusNotifierWatcher but its
RegisterStatusNotifierItem implementation didn't accept SNI publishers
— Telegram, Vesktop, blueman-tray, and a libayatana-appindicator test
script all failed to register, leaving waybar's tray empty.
Removing snixembed lets waybar's tray module register itself as both
host AND watcher (when no other watcher exists). After this change,
all three SNI items registered immediately.
Trade-off: legacy XEmbed-based Wine tray icons no longer bridge to
SNI. The Wine System Tray host window rule is kept (still hides the
empty window off-screen) and the comment updated.
- niri/config.kdl: drop snixembed spawn-at-startup; update Wine rule
- packages.txt: drop snixembed (no longer used)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The niri 'environment' block only affects processes niri spawns
directly. Apps launched via dbus activation or systemd-user (most
.desktop launches go through one of these) get systemd-user's env,
which still has bare 'niri' — set by niri-session BEFORE niri itself
runs.
Adding a one-shot spawn-at-startup that re-imports XDG_CURRENT_DESKTOP
from niri's env into both systemd-user and dbus-activation, after
niri starts. Future dbus-activated apps will see niri:GNOME.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Many tray libraries (Electron's, Qt's StatusNotifier) gate icon
creation on a recognised XDG_CURRENT_DESKTOP value. Bare "niri"
makes them silently skip tray creation. Adding ":GNOME" as a
fallback identifier keeps niri primary while letting apps create
their tray icons.
Vesktop and Telegram are confirmed to want tray icons but were
not creating them; this fix unblocks both.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both daemons were running but not registering SNI items on niri/Wayland,
leaving the waybar tray slot permanently empty. Network is already
accessible via the waybar network module (left-click → networkmanager_dmenu).
Bluetooth GUI (blueman-manager) is still available on demand; only the
applet is dropped.
Tray module stays configured so Electron apps (Discord/Vesktop, Steam,
etc.) still get a tray slot when they're running.
- niri/config.kdl: drop nm-applet and blueman-applet spawn-at-startup
- packages.txt: drop network-manager-applet (nothing else uses it);
keep blueman package for blueman-manager GUI
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aligns the third sleep path (power menu) with the lid handler and
the swayidle 30-min timer — all three now suspend immediately and
hibernate after HibernateDelaySec (30 min).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Spec said `findmnt -no UUID /` and `resume=UUID=` but the script
correctly uses PARTUUID throughout (matches the system's existing
root=PARTUUID= convention).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
If `findmnt -no PARTUUID /` returns nothing (root on LVM, no GPT,
unusual mount state) the script would silently write a broken
resume=PARTUUID= line to /etc/kernel/cmdline. Bail with an error
message instead.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Flameshot's portal-based capture path on niri triggers an
xdg-desktop-portal access prompt on every invocation, blocking
the screenshot itself. grim talks to wlr-screencopy directly and
never touches the portal, so no prompt.
Pipeline: slurp (region) → grim (capture) → satty (annotate +
copy + save). satty replaces the wofi action menu by being the
post-capture surface itself.
- scripts/screenshot.sh added
- install.sh symlinks it; flameshot.ini generator removed
- niri Mod+Print → "screenshot"
- packages.txt drops flameshot
- docs tables updated
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both plans were generated during their respective implementation
runs but never committed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Tooling" tables in README.md and ARCHITECTURE.md still listed
grim + slurp after the flameshot swap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>