fix: auto-recover input listeners after X server restart#78
Conversation
There was a problem hiding this comment.
Important
Looks good to me! 👍
Reviewed everything up to 984a2ae in 7 seconds. Click for details.
- Reviewed
179lines of code in3files - Skipped
0files when reviewing. - Skipped posting
0draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
Workflow ID: wflow_gRfg3AG7kcx36ho1
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
Greptile SummaryThis PR adds auto-recovery for input listeners after X server restarts by implementing health checks and reinitialization logic. The implementation successfully addresses the long-standing issue where pynput listener threads silently die after X server restarts, causing permanent AFK reporting. Key changes:
Issues found:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Watcher as AFK Watcher
participant Unix as LastInputUnix
participant ML as MouseListener
participant KL as KeyboardListener
participant Pynput as pynput threads
Note over Unix,Pynput: Normal Operation
Watcher->>Unix: seconds_since_last_input()
Unix->>Unix: _check_listeners()
Unix->>ML: is_alive()
ML->>Pynput: check thread state
Pynput-->>ML: alive
ML-->>Unix: True
Unix->>KL: is_alive()
KL->>Pynput: check thread state
Pynput-->>KL: alive
KL-->>Unix: True
Unix->>ML: has_new_event()
Unix->>KL: has_new_event()
Unix-->>Watcher: seconds since last input
Note over Pynput: X Server Restarts
Note over Pynput: Threads die silently
Watcher->>Unix: seconds_since_last_input()
Unix->>Unix: _check_listeners()
Unix->>ML: is_alive()
ML->>Pynput: check thread state
Pynput-->>ML: dead
ML-->>Unix: False
Unix->>Unix: _start_listeners()
Unix->>ML: new MouseListener()
Unix->>ML: start()
Unix->>KL: new KeyboardListener()
Unix->>KL: start()
Unix->>Unix: reset last_activity
Unix-->>Watcher: 0 seconds (recovered)
Last reviewed commit: 984a2ae |
| @@ -0,0 +1,81 @@ | |||
| """Tests for listener health checking and auto-recovery.""" | |||
|
|
|||
| import threading | |||
There was a problem hiding this comment.
threading imported but never used
There was a problem hiding this comment.
Fixed in 885de45 — removed the unused threading import.
984a2ae to
28e3942
Compare
|
@TimeToBuildBob Rebase and address review comments |
When the X server restarts (e.g. after suspend/resume, display server crash, or session switch), pynput listener threads silently die. Without health checking, the watcher would permanently report AFK since no new input events would ever be detected. Add is_alive() to KeyboardListener and MouseListener, and check listener health on every poll cycle. When a dead listener is detected, reinitialize both listeners and reset the activity timestamp. Fixes ActivityWatch#27
- Add stop() method to KeyboardListener and MouseListener - Call _stop_listeners() in _check_listeners() before reinitializing to prevent two listener instances running simultaneously when only one dies (e.g. only keyboard thread dies after X server restart) - Remove unused threading import from test file (Greptile review)
28e3942 to
885de45
Compare
Review feedback addressedRebased onto current master and fixed both Greptile review comments:
All 7 tests still pass. |
Summary
is_alive()method toKeyboardListenerandMouseListenerthat checks if the underlying pynput listener thread is still runningLastInputUnix.seconds_since_last_input()— on every poll cycle, checks if listeners are alive and reinitializes them if deadlast_activitytimestamp on reinitialization to prevent reporting a spurious AFK gapProblem
When the X server restarts (suspend/resume, display server crash, session switch), pynput listener threads silently die — they stop receiving events but don't raise any errors. The watcher then permanently reports AFK because
has_new_event()always returnsFalse.This is a long-standing issue reported in #27 (2017).
Test plan
is_alive()returnsFalsebeforestart()is calledis_alive()correctly reflects underlying pynput thread stateLastInputUnixdetects dead listeners and reinitializes themFixes #27
Important
Fixes issue where input listeners die after X server restart by adding health checks and auto-recovery.
is_alive()toKeyboardListenerandMouseListenerto check if pynput listener threads are running.LastInputUnix.seconds_since_last_input(), checks listener health and reinitializes if dead.last_activitytimestamp on reinitialization to avoid false AFK reporting.test_listener_health.pywith tests foris_alive()behavior and listener reinitialization.This description was created by
for 984a2ae. You can customize this summary. It will automatically update as commits are pushed.