# 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).