Skip to content

fix(fingerprint): reconnect to fprint service after resume from suspend#971

Closed
fcatuhe wants to merge 2 commits into
hyprwm:mainfrom
fcatuhe:fix/fingerprint-reconnect-on-resume
Closed

fix(fingerprint): reconnect to fprint service after resume from suspend#971
fcatuhe wants to merge 2 commits into
hyprwm:mainfrom
fcatuhe:fix/fingerprint-reconnect-on-resume

Conversation

@fcatuhe

@fcatuhe fcatuhe commented Mar 15, 2026

Copy link
Copy Markdown

Problem

After suspend/resume, fingerprint drivers like open-fprintd + python-validity crash and restart due to stale USB/TLS state. hyprlock attempts to verify immediately on wake via the PrepareForSleep signal, but the fprint service disappears during this window. Previously, hyprlock had no way to detect this and would silently lose fingerprint auth for the remainder of the lock session.

This affects users of Synaptics fingerprint readers (e.g. 06cb:009a on ThinkPad X1 Carbon) that rely on reverse-engineered drivers, though the fix is not hardware-specific.

Fixes #531

Solution

Add a DBus NameOwnerChanged watcher that detects when the net.reactivated.Fprint service disappears. When this happens, reset the device proxy and schedule reconnection attempts until the service is back. Also retry when createDeviceProxy() fails, covering the case where hyprlock tries to reconnect before the service has fully restarted.

The open-fprintd package ships a python3-validity-suspend-hotfix systemd service that automatically restarts python3-validity and open-fprintd after resume. This means the fprint service reliably comes back — hyprlock just needs to wait for it and reconnect.

Changes

  • Watch for net.reactivated.Fprint service disappearing via DBus NameOwnerChanged signal in init()
  • Add scheduleRetry() for centralized reconnect with attempt counting (max 20 attempts, 100ms interval)
  • Retry createDeviceProxy() on failure instead of silently giving up
  • Reset reconnect counter on successful device claim

Design decisions

Why NameOwnerChanged instead of blind retry polling: PR #943 takes a timer-based retry approach that retries without knowing whether the service is available. Our approach reacts to the actual DBus event — we know exactly when the service disappears and can respond immediately. This is more reliable and avoids wasted retry attempts.

Why constants instead of config values: RECONNECT_MAX_ATTEMPTS and RECONNECT_DELAY_MS are internal implementation details of the reconnect mechanism, unlike the existing retry_delay which controls user-visible UX (delay between mismatch retries). Adding config surface for these provides no user benefit.

Why the watcher lives in init() instead of createDeviceProxy(): The watcher monitors the service name, not the device path. It only needs to be created once and persists for the lifetime of the lock screen.

Note on timer lifetime safety: The raw this pointer passed to addTimer carries a theoretical use-after-free risk if CFingerprint is destroyed before the timer fires. This is the existing pattern used by the MATCH_NO_MATCH retry handler and appears to be an accepted project convention. A broader fix using weak_ptr or guard checks would be welcome but is outside the scope of this change.

Testing

Tested across multiple suspend/resume cycles on a ThinkPad X1 Carbon 6th Gen with Synaptics 06cb:009a fingerprint reader using open-fprintd + python-validity. Fingerprint auth reliably recovers within ~1 second after resume.

fcatuhe added 2 commits March 15, 2026 15:12
After suspend/resume, fingerprint drivers like open-fprintd + python-validity
crash and restart due to stale USB/TLS state. Previously, hyprlock would
attempt to verify immediately on wake, fail when the service disappeared,
and permanently abort fingerprint auth.

This adds a NameOwnerChanged DBus watcher that detects when the fprint
service disappears and schedules reconnection attempts. Combined with
retry logic when the device proxy cannot be created, hyprlock now
recovers automatically once the service restarts.

Changes:
- Watch for net.reactivated.Fprint service disappearing via DBus
  NameOwnerChanged signal
- Add scheduleRetry() for centralized retry with attempt counting
- Retry createDeviceProxy() on failure instead of silently giving up
- Reset reconnect counter on successful device claim

Fixes: hyprwm#531
The NameOwnerChanged watcher monitors the service name, not the device
path, so it doesn't need to be recreated on every createDeviceProxy()
call. Move it to init() where it's created once and persists for the
lifetime of the lock screen.
@PointerDilemma

Copy link
Copy Markdown
Collaborator

open-fprintd + python-validity I am sorry, but those projects are so bad that I don't want to fix the dbus service suddenly disappearing.

I think to explain this I can just mention that for applications to even recognize suspend and wake, they have to use PreparingForSleep via org.freedesktop.login1. That is just to illustrate that we need the dbus connections and interfaces should live through a suspend cycle. We already need to release and reclaim the fingerprint device on suspend because it seemingly can cause problems if we don't.

Ideally applications shouldn't need to handle suspend at all. And when we have to, it's not a good thing.

@fcatuhe

fcatuhe commented Mar 17, 2026

Copy link
Copy Markdown
Author

Thanks @PointerDilemma for pointing us in the right direction. We didn't know about PrepareForSleep and were approaching this from the wrong end entirely — your explanation of how suspend should work via logind was really helpful.

We've submitted fixes upstream instead:

  • open-fprintd PR #24 — the Manager now listens to PrepareForSleep directly and calls Device.Suspend() / Device.Resume() on sleep/wake
  • python-validity PR #249 — fixes Resume() to properly reinitialize the USB device with a retry loop for enumeration timing

Together, the services stay alive across suspend and hyprlock doesn't need to deal with them disappearing at all. Tested across multiple cycles on the same hardware (ThinkPad X1 Carbon, 06cb:009a) — works reliably. Closing this in favor of the upstream fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[open-fprintd] Hyprlock fingerprint not working after idle

2 participants