fix(linux): stabilize connection state and replay HID settings on reconnect#55
fix(linux): stabilize connection state and replay HID settings on reconnect#55hieshima wants to merge 3 commits intoTomBadash:masterfrom
Conversation
Keep Linux in a single connected-state model while restoring HID-only settings when HID feature readiness returns after startup or reconnect. This commit combines the existing second-stage UI/backend cleanup with the first reconnect-focused fix. The UI continues to treat evdev readiness as the main connection signal, while HID-only controls stay gated behind hidFeaturesReady so DPI controls do not appear during the evdev-only gap. On the engine side, reconnect handling now watches hid_features_ready instead of plain connected=True. When HID identity transitions from unavailable to available, Engine queues a daemon replay worker that reapplies the saved DPI and Smart Shift mode. The temporary delayed startup restore path is kept only as a transitional safety net and now routes through the same replay helper, while staying dormant once a HID-ready replay has already been requested. Replay failures are no longer silent. Engine now exposes a status callback, and Backend forwards those messages onto the existing statusMessage signal with queued cross-thread delivery so the UI can surface replay problems without new public API. This commit also closes a Linux diagnostics gap in hid_gesture: if a candidate interface opens successfully but REPROG_V4 cannot be found on any tested device index, Mouser now logs that explicitly instead of falling through to a generic reconnect retry. Tests added and updated: - engine: hid_features_ready detection, duplicate refreshes not restarting the battery poller, HID-ready replay triggering, startup fallback suppression, replay failure status callback - backend: hidFeaturesReady refreshes without re-emitting a false connection edge, engine status callback wiring, replay failure reaching statusMessage - hid_gesture: opened-without-REPROG_V4 diagnostic, successful discovery path still unchanged Validation: - uv run python -m unittest tests.test_backend tests.test_engine tests.test_hid_gesture tests.test_mouse_hook tests.test_app_detector
|
@hieshima i tried your PR. My mouse (Mx anywhere 3) is "recognized" as i i see on the UI, button mappings are working. But dpi is is not EDIT: i got it to work But also bumped hid dependency in requirements.txt. |
|
Thanks @hieshima for the continued work on Linux support -- this is shaping up really nicely. The approach of separating evdev readiness from HID++ feature readiness makes a lot of sense, and the HID settings replay on reconnect is a solid improvement. And @farfromrefug, thanks for jumping in and testing with your MX Anywhere 3! Your feedback about the udev rules and hid dependency is really valuable. A few things I want to make sure are solid before merging: The udev rules issue @farfromrefug hit -- should we document the required udev rules somewhere (README or a setup script)? If _hid.enumerate(LOGI_VID, 0) returns nothing without them, that's going to be a common stumbling block for Linux users. The hid dependency bump -- @farfromrefug, could you clarify which version you bumped to? If that's needed for Linux HID to work, we should include it in this PR. Cross-platform safety -- the PR notes that macOS and Windows share the same HID++ replay and UI-gating code paths but weren't runtime-tested at the same depth. I tested on Windows + MX Master 3S and can confirm the existing HID++ paths are working fine on master, but I want to make sure nothing regresses. @hieshima, are there any code paths that could affect Windows/macOS behavior, or are the changes scoped to Linux-only branches? The follow-up reconnect polish commit -- sounds promising. Happy to review that as a separate PR once this one lands. I don't have a Linux setup to test on my end, so I'm relying on you both to validate. If you can confirm the above points, I'm ready to merge. Looking forward to hearing how it holds up -- let me know if you run into anything else! |
|
@TomBadash i was talking about "hid" dep. But i am really not sure this made a difference as i did both at the same time. |
The existing Linux permissions note only mentioned evdev and uinput. HID++ features (DPI, battery, Smart Shift) also need read/write access to /dev/hidraw*, which defaults to root-only on most distros. Add the udev rule snippet so Linux users can enable HID++ without running as root.
a5f1714 to
b5f20f1
Compare
|
Thanks @TomBadash for the review, and @farfromrefug for testing on Ubuntu — really helpful to get coverage on a second distro. Addressing each point: udev rules documentation Already done — commit b5f20f1 on this branch adds a Linux Prerequisites section to the README with the udev rules snippet. I also like @farfromrefug's idea of showing an in-app hint when hid dependency bump @farfromrefug — the udev rules are what fixed it. Cross-platform safety The changes are scoped to Linux-only code paths:
Follow-up I have a reconnect polish commit ready — will open as a separate PR once this lands. |
Summary
This PR improves Linux reconnect correctness by separating evdev input readiness from HID++ feature readiness, and by restoring HID-only settings when HID++ becomes available again.
What changes
Connection state stability on Linux
HID setting replay
UI gating
Diagnostics
REPROG_V4is not found on any tested device index, Mouser now logs that explicitly instead of falling through to a generic reconnect retry.Notes
mouseConnectedcontinues to mean the input path is ready.hidFeaturesReadyis used to gate HID-only controls and replay HID-only settings.Cross-platform note
The HID++ communication path is cross-platform by design. This round of fixes was developed and runtime-tested on Linux (Nobara 43 KDE Wayland). macOS and Windows share the same HID++ replay and UI-gating code paths, but were not runtime-tested at the same depth in this round.
Validation
Targeted validation:
uv run python -m unittest tests.test_backend tests.test_engine tests.test_hid_gesture tests.test_mouse_hook tests.test_app_detectorCovered cases include:
REPROG_V4failures are logged explicitlyFollow-up work
I have a separate reconnect polish commit that keeps retries aggressive for longer after disconnect, reuses the last successful HID candidate and device index, and improves reconnect diagnostics. I kept it out of this PR to focus the first review on correctness.
Separately, I prototyped a pyudev-based wakeup path to reduce reconnect latency further, but I left that experiment out of this PR. In my testing, the dominant reconnect delay was upstream of Mouser: there was still a long gap before Linux re-exposed usable input/hidraw nodes after BT reconnect. Because the watcher only helps after those nodes exist, the improvement over staged polling was not perceptible in my setup.