Files
dotfiles/docs/superpowers/specs/2026-05-25-hyprlock-replace-gtklock-design.md
funman300 d7ab4baf7e docs: spec for hyprlock migration (replaces gtklock)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:08:38 -07:00

7.0 KiB

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:

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 = <i>Touch fingerprint or type password</i>
    fail_text = <i>$FAIL</i>
    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 gtklockhyprlock. 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:

ln -sf "$(pwd)/gtklock/config.ini" ~/.config/gtklock/config
ln -sf "$(pwd)/gtklock/style.css" ~/.config/gtklock/style.css

Replace with:

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 gtklockhyprlock; 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).