From d7ab4baf7e63f7468f0d95d774ab7390705d527a Mon Sep 17 00:00:00 2001 From: funman300 Date: Mon, 25 May 2026 11:08:38 -0700 Subject: [PATCH] docs: spec for hyprlock migration (replaces gtklock) Co-Authored-By: Claude Opus 4.7 (1M context) --- ...6-05-25-hyprlock-replace-gtklock-design.md | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md diff --git a/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md b/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md new file mode 100644 index 0000000..69c9fbe --- /dev/null +++ b/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md @@ -0,0 +1,175 @@ +# Replace gtklock with hyprlock Design + +**Date:** 2026-05-25 +**Status:** Approved + +## Summary + +Migrate the lockscreen from `gtklock` to `hyprlock`. Hyprlock has native fprintd polling: touching the reader on the lockscreen unlocks immediately, without the user having to first type / press Enter to trigger PAM (the limitation that motivated this change). + +## Current Behaviour + +- `gtklock` is the lockscreen, bound to `Mod+Shift+E` and to swayidle's 10-minute lock + before-sleep hooks. +- `gtklock/style.css` (72 lines) + `gtklock/config.ini` are tracked and symlinked to `~/.config/gtklock/`. +- `/etc/pam.d/gtklock` has `auth sufficient pam_fprintd.so` (from `scripts/enable-fingerprint.sh`). +- Pain point: gtklock doesn't poll fprintd until PAM is invoked, which only happens once the user submits something in the password field. Touching the reader on a freshly-locked screen does nothing. + +## Target Behaviour + +- `hyprlock` is the lockscreen, bound to the same keybind, called by the same swayidle hooks. +- Touch the reader on the locked screen → unlocks immediately. +- Type the password and press Enter → also unlocks (fallback). +- Visual: centred 96 px clock, smaller date below, password input field with placeholder text, blurred-screenshot background. Colors map the Tomorrow Night palette. + +## Implementation + +### `hyprlock/hyprlock.conf` (new) + +Single Hyprlang file, deployed to `~/.config/hypr/hyprlock.conf`: + +```hyprlang +general { + grace = 0 + hide_cursor = true +} + +background { + monitor = + path = screenshot + blur_passes = 3 + blur_size = 8 +} + +label { + monitor = + text = cmd[update:1000] date +"%-I:%M %p" + font_size = 96 + color = rgba(c5c8c6ff) + position = 0, 150 + halign = center + valign = center +} + +label { + monitor = + text = cmd[update:60000] date +"%A, %B %-d" + font_size = 24 + color = rgba(969896ff) + position = 0, 40 + halign = center + valign = center +} + +input-field { + monitor = + size = 300, 50 + outline_thickness = 2 + dots_size = 0.25 + dots_spacing = 0.4 + inner_color = rgba(282a2eff) + outer_color = rgba(81a2beff) + font_color = rgba(c5c8c6ff) + fail_color = rgba(cc6666ff) + check_color = rgba(b5bd68ff) + placeholder_text = Touch fingerprint or type password + fail_text = $FAIL + fade_on_empty = false + position = 0, -50 + halign = center + valign = center +} +``` + +Color mapping: +- `c5c8c6` = `@tn-fg` (clock text, input font) +- `969896` = `@tn-fg-dim` (date label) +- `282a2e` = `@tn-bg-alt` (input fill) +- `81a2be` = `@tn-blue` (focus ring) +- `cc6666` = `@tn-red` (auth failure) +- `b5bd68` = `@tn-green` (auth success) + +### `packages.txt` + +Swap `gtklock` → `hyprlock`. Drop the AUR `gtklock-userinfo-module` entry too (not used in the new config). `hyprlock` is in the `extra` repo — no AUR helper needed for it. + +### `install.sh` + +Remove the two gtklock symlink lines: +```bash +ln -sf "$(pwd)/gtklock/config.ini" ~/.config/gtklock/config +ln -sf "$(pwd)/gtklock/style.css" ~/.config/gtklock/style.css +``` + +Replace with: +```bash +mkdir -p ~/.config/hypr +ln -sf "$(pwd)/hyprlock/hyprlock.conf" ~/.config/hypr/hyprlock.conf +``` + +Also drop the `gtklock` entry from the brace-expansion `mkdir -p` near the top of install.sh. + +### `niri/config.kdl` + +Three changes: +1. The keybind `Mod+Shift+E { spawn "gtklock" "-d"; }` → `Mod+Shift+E { spawn "hyprlock"; }` +2. Swayidle's 600 s timer action `"gtklock" "-d"` → `"hyprlock"` +3. Swayidle's `before-sleep` action `"gtklock" "-d"` → `"hyprlock"` + +`hyprlock` takes no `-d` flag — it daemonises by default. + +### `scripts/enable-fingerprint.sh` + +Change `TARGETS=(/etc/pam.d/sudo /etc/pam.d/gtklock)` → `TARGETS=(/etc/pam.d/sudo /etc/pam.d/hyprlock)`. The script remains idempotent for the new target. Existing `/etc/pam.d/gtklock` pam_fprintd line stays untouched (harmless dead config; the user can `sed -i '/pam_fprintd/d' /etc/pam.d/gtklock` if they want). + +### `gtklock/` (deletion) + +Delete the tracked directory: `gtklock/config.ini` + `gtklock/style.css`. The packages get uninstalled (or remain installed, user's call); the tracked config files are gone. + +### Documentation updates + +- `README.md`: change Tooling table row for Lockscreen from `gtklock` to `hyprlock`. Update the `### One-time fingerprint setup` subsection's reference to gtklock's lockscreen (test instruction mentions `Mod+Shift+E`, still valid). +- `ARCHITECTURE.md`: same table row change. +- `CLAUDE.md`: replace "gtklock" mentions with "hyprlock" in the Theming + Tooling sections. + +### Theme + +The repo's `theme/colors.css` is the source of truth for GTK CSS variables. Hyprlock doesn't use CSS — colors are hand-mapped in `hyprlock.conf`. Not a regression in DRY (the values map 1:1 to entries in `theme/colors.json`); no new color source created. + +## Files Touched + +| File | Action | +|---|---| +| `hyprlock/hyprlock.conf` | created | +| `packages.txt` | swap `gtklock` → `hyprlock`; drop `gtklock-userinfo-module` if present | +| `install.sh` | swap symlinks (and mkdir entry) | +| `niri/config.kdl` | swap 3 gtklock invocations to hyprlock | +| `scripts/enable-fingerprint.sh` | swap target in `TARGETS` array | +| `gtklock/config.ini` | deleted | +| `gtklock/style.css` | deleted | +| `README.md` | update lockscreen reference | +| `ARCHITECTURE.md` | update lockscreen reference | +| `CLAUDE.md` | update lockscreen reference | + +## Manual user steps after merge + +1. `bash install.sh` — installs hyprlock, deploys config, replaces symlinks. +2. `sudo bash scripts/enable-fingerprint.sh` — re-runs idempotently; adds `pam_fprintd.so` to the new `/etc/pam.d/hyprlock`. +3. Test: `Mod+Shift+E` to lock → touch reader → unlocks immediately. +4. Optional cleanup: `sudo pacman -Rns gtklock gtklock-userinfo-module` if you want the old package gone. + +## Verification + +- `which hyprlock` returns `/usr/bin/hyprlock` +- `grep pam_fprintd /etc/pam.d/hyprlock` shows the line +- `hyprlock` (run from terminal) launches the lockscreen with clock, date, input field; Ctrl-C in the terminal won't kill it (it's its own GPU surface); use the password to unlock. +- Touching the reader unlocks without typing anything first. + +## Out of Scope + +- **Porting gtklock's CSS layout / theming verbatim.** Hyprlock doesn't use CSS. The new config achieves a comparable look via the palette mapping; further visual polish (avatars, music controls, last-login time) is a future incremental edit to `hyprlock.conf`. +- **Migrating swayidle's behaviour beyond changing the lock command.** Timers stay (300/600/1800 s). +- **Cleaning up `/etc/pam.d/gtklock`** — the existing pam_fprintd line in that file becomes harmless dead config since gtklock won't be launched. Manual cleanup if desired. +- **Uninstalling the `gtklock` system package** — out of scope; user decides. +- **Hyprlock styling beyond colors + clock + input field** — keep it minimal. +- **Solid-color background fallback** if the blurred screenshot renders poorly — easy follow-up edit, not part of this spec. +- **Custom font selection** — uses system default (likely JetBrainsMono Nerd Font since it's installed).