fix(fingerprint): reconnect to fprint service after resume from suspend#971
fix(fingerprint): reconnect to fprint service after resume from suspend#971fcatuhe wants to merge 2 commits into
Conversation
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.
|
I think to explain this I can just mention that for applications to even recognize suspend and wake, they have to use Ideally applications shouldn't need to handle suspend at all. And when we have to, it's not a good thing. |
|
Thanks @PointerDilemma for pointing us in the right direction. We didn't know about We've submitted fixes upstream instead:
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, |
Problem
After suspend/resume, fingerprint drivers like
open-fprintd+python-validitycrash and restart due to stale USB/TLS state. hyprlock attempts to verify immediately on wake via thePrepareForSleepsignal, 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:009aon ThinkPad X1 Carbon) that rely on reverse-engineered drivers, though the fix is not hardware-specific.Fixes #531
Solution
Add a DBus
NameOwnerChangedwatcher that detects when thenet.reactivated.Fprintservice disappears. When this happens, reset the device proxy and schedule reconnection attempts until the service is back. Also retry whencreateDeviceProxy()fails, covering the case where hyprlock tries to reconnect before the service has fully restarted.The
open-fprintdpackage ships apython3-validity-suspend-hotfixsystemd service that automatically restartspython3-validityandopen-fprintdafter resume. This means the fprint service reliably comes back — hyprlock just needs to wait for it and reconnect.Changes
net.reactivated.Fprintservice disappearing via DBusNameOwnerChangedsignal ininit()scheduleRetry()for centralized reconnect with attempt counting (max 20 attempts, 100ms interval)createDeviceProxy()on failure instead of silently giving upDesign decisions
Why
NameOwnerChangedinstead 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_ATTEMPTSandRECONNECT_DELAY_MSare internal implementation details of the reconnect mechanism, unlike the existingretry_delaywhich controls user-visible UX (delay between mismatch retries). Adding config surface for these provides no user benefit.Why the watcher lives in
init()instead ofcreateDeviceProxy(): 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
thispointer passed toaddTimercarries a theoretical use-after-free risk ifCFingerprintis destroyed before the timer fires. This is the existing pattern used by theMATCH_NO_MATCHretry handler and appears to be an accepted project convention. A broader fix usingweak_ptror 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:009afingerprint reader usingopen-fprintd+python-validity. Fingerprint auth reliably recovers within ~1 second after resume.