Asger Geel Weirsøe 702f449d0e
Some checks failed
Test / test (push) Failing after 1m23s
fix: PID-based volume lock with state persistence and multiarch default path
Volume lock file now stores {pid}:{volume}:{muted} instead of "1":
- Allows recovery of saved volume state if the holder is SIGKILLed
- On stale lock detection (holder PID not alive), inherit saved volume state
  and take ownership — prevents permanent volume loss and infinite lockout

PAM module DEFAULT_PATH now baked in at build time via AHFAIL_LIBDIR env var
passed by Meson, fixing the wrong path on multiarch Debian/Ubuntu where libdir
is /usr/lib/x86_64-linux-gnu rather than /usr/lib.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 12:41:06 +02:00
2025-11-30 21:08:42 +01:00
2025-11-30 21:08:42 +01:00
2025-11-30 21:08:42 +01:00
2026-05-06 09:25:39 +02:00
2026-05-06 09:25:39 +02:00
2025-12-01 08:57:48 +01:00

Ah ah ah, you didn't say the magic word

This gtklock module listens for failed unlock attempts and recreates Dennis Nedrys “ah ah ah” lockout scene from Jurassic Park.

  • Animation: Spawns a looping "Nedry" sprite at a random location on the screen.
  • Audio: Plays the "ah ah ah, you didn't say the magic word" clip.
  • Safety: Sprites avoid overlapping a configurable "deadzone" (e.g., your login box).
  • Performance: Uses pre-warmed audio players for low latency

Requirements

  • Build: Meson, Ninja, Rust (Cargo), GTK+3 development headers.
  • Runtime: gtklock, gstreamer, gst-plugins-base, gst-plugins-good (for audio playback).

Build & Install

  1. Install Dependencies:

    sudo pacman -S meson ninja rust gtk3 gstreamer gst-plugins-base gst-plugins-good
    
  2. Build:

    meson setup builddir
    meson compile -C builddir
    
  3. Install:

    sudo meson install -C builddir
    

Usage

Run gtklock with the module path:

gtklock -m /usr/lib/gtklock/ahfail-module.so

Arguments

  • --deadzone=X,Y,W,H: Defines a rectangle where sprites will not spawn (e.g., to keep your password field visible).

    gtklock -m ahfail-module.so -- --deadzone=860,440,200,200
    

    (Note the -- separator before module arguments)

  • --audio-uri=URI: Override the default audio clip.

    gtklock -m ahfail-module.so -- --audio-uri=file:///home/user/custom.mp3
    

macOS (build from source)

Prerequisites

brew install gtk+3 gstreamer gst-plugins-base gst-plugins-good meson ninja rust

Build

meson setup builddir
meson compile -C builddir

Produces:

  • builddir/ahfail-module.so — gtklock module (Wayland/Linux only)
  • builddir/libahfail_pam.so — PAM module (macOS + X11 Linux)
  • builddir/ahfail-display — display binary (spawned by PAM module)

Install

sudo mkdir -p /usr/local/lib/ahfail
sudo cp builddir/libahfail_pam.so /usr/local/lib/ahfail/
sudo cp builddir/ahfail-display /usr/local/lib/ahfail/

Configure PAM (macOS)

Find your screen locker's PAM service file. On macOS 13+ the screensaver uses /etc/pam.d/screensaverui; on older versions it may be /etc/pam.d/screensaver. Add the following line after the existing auth entries (requires sudo):

auth optional /usr/local/lib/ahfail/libahfail_pam.so

Configure PAM (Linux/X11)

Add to /etc/pam.d/gtklock (or i3lock, xscreensaver, etc.). Use the full path because $(libdir)/ahfail is not in PAM's default search path:

auth optional /usr/lib/ahfail/libahfail_pam.so

On Fedora/RHEL replace /usr/lib with /usr/lib64.

Development

  • Run Tests: cargo test
  • Benchmarks: cargo test --test benchmarks -- --nocapture
  • Linting: cargo clippy

Customization

To change the default sprite or audio:

  1. Replace files in assets/.
  2. Update assets/ahfail.gresource.xml.
  3. Rebuild with Meson.
Description
gtklock module for going jurassic
Readme AGPL-3.0 2.5 MiB
v0.9.0 Latest
2026-05-07 22:01:02 +02:00
Languages
Rust 79.6%
Shell 10.8%
C 5.2%
Meson 4.4%