Fix hook, display and daemon reliability issues - #513
Open
MathieuARS wants to merge 9 commits into
Open
Conversation
Preserve physical edge crossings at high velocity, defer resume re-hooking until the UI reloads the topology, and bind local IPC inside its Tokio runtime with a readiness handshake. Add regression coverage for crossing, resume, and synchronous daemon startup.
Bound cold-start IPC attempts so the UI can launch a missing daemon, initialize state conservatively, serialize daemon creation, and provide a session-scoped Stop fallback. Restore functional display-event debouncing, safe resume reconciliation, and persistent tray Start behavior, with regression coverage for missing-daemon startup.
Remove the obsolete UI loader project from the Linux solution filter so it matches the main solution and builds successfully.
This was referenced Jul 25, 2026
mgth
added a commit
that referenced
this pull request
Jul 25, 2026
…513) Adopts the transport rework from #513 (commits 3fdf340/6641ae5), reviewed fix by fix and rebased on the master elevation and exclusion models. Why the TCP transport had to go: port 25196 was open to every local process (any user could command the daemon or read FocusChanged paths), a squatted port made the daemon panic at boot, the client dispatched events out of order via Task.Run, swallowed send failures after 10 retries (a Stop could silently leave the hook capturing the mouse), and matched events by substring inside payloads. The replacement: a per-session named pipe with a user/SYSTEM DACL and session check on Windows, a 0600 Unix socket in XDG_RUNTIME_DIR on Linux; u32-length-prefixed UTF-8 frames capped at 1 MiB; bounded queues; a serialized command worker preserving Load-then-Run order; four-client cap. Same XML message contract - settings and Current.xml stay compatible; DaemonPort remains as a dead property so existing settings deserialize. Current.xml is now written atomically with a .bak the daemon falls back to only when the primary is unreadable or fails to parse - a valid stopped state no longer triggers recovery, and a Run without a successful Load is ignored. Stop gets a safety net: if IPC is down, known hook processes of this session (this UI's child on Unix) are killed rather than left routing input. On top of the #513 version, three of its bugs are fixed here: - the Windows accept loop died permanently on a transient create_pipe error; it now logs, backs off 500 ms and retries - the listener raised ConnectionFailed only once per connect cycle, so a daemon that crashed right after launch was never relaunched; it now re-raises every ~5 s (LaunchDaemon's already-running check makes that idempotent) - UnauthorizedAccessException or a malformed frame killed the event listener silently; both now reconnect like I/O failures And two of its regressions are not taken: the resume watchdog stays ungated (the #513 gating reintroduced the stale-layout-on-wake bug), and daemon launch keeps the #512 elevation model (no runas). The Unix bind also no longer chmods a parent directory it did not create (EPERM on shared parents like /tmp). LBM_HOOK_ENDPOINT replaces LBM_HOOK_PORT for side-by-side testing. The C++ LittleBigMouse.Hook daemon, which only speaks TCP, is retired from distributable builds (decision from the #513 review). Wire contract covered by tests on both sides, including full-duplex under load (events streaming while commands flow) and listener reconnection - the historical pipe failure modes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: MathieuARS <mathieu.maik.15@gmail.com>
Owner
|
Thank you very much for the work done. It's very useful and most work will be integrated, but I cannot merge as is. So I'll cherry-pick. For future collaboration you may want to split work in more mergeable work. But thanks again, its very welcome and useful. |
mgth
added a commit
that referenced
this pull request
Jul 25, 2026
Two independent fixes extracted from #513 (commits 8d2f7cc/6d5ccd8), without the injected-event resync mechanism they were entangled with: - The C++-inherited filter (wparam & WM_MOUSEMOVE) matched every mouse message (they all carry bit 0x200): clicks and wheel events entered the engine as moves, and a click landing on a border mid-crossing could be swallowed by the LRESULT(1) return. Exact match only, with a unit test. - exe_path_from_pid opened processes with PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, which is denied on elevated or anticheat-protected processes — exactly the games exclusions target. LIMITED is enough for QueryFullProcessImageNameW; the ERROR_INSUFFICIENT_BUFFER loop covers paths beyond MAX_PATH. - Examples gated cfg(linux) so cargo build --examples works on Windows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: MathieuARS <mathieu.maik.15@gmail.com>
mgth
pushed a commit
that referenced
this pull request
Jul 25, 2026
InvokeCommand on a ReactiveCommand drops values emitted while an execution is in flight: during a display-change burst (resume, topology change) the final wallpaper could be lost, and a bitmap replaced from an older render was never disposed. LatestResourceSlot serializes this: stale generations are rejected and disposed instead of replacing newer state, and disposal invalidates in-flight renders. Rendering failures now fall back to no wallpaper instead of an unobserved task exception. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mgth
pushed a commit
that referenced
this pull request
Jul 25, 2026
…lock (from #513) The close confirmation showed OkCancel buttons but tested the result against ButtonResult.Yes/No, which OkCancel can never return: the Close button silently did nothing. It also blocked the UI thread on ShowAsync().Result. Async Yes/No dialog with an honest message (the old 'Save your changes' text promised a save that has been commented out for years), shutdown on Yes only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mgth
added a commit
that referenced
this pull request
Jul 25, 2026
…513) Adopts the transport rework from #513 (commits 3fdf340/6641ae5), reviewed fix by fix and rebased on the master elevation and exclusion models. Why the TCP transport had to go: port 25196 was open to every local process (any user could command the daemon or read FocusChanged paths), a squatted port made the daemon panic at boot, the client dispatched events out of order via Task.Run, swallowed send failures after 10 retries (a Stop could silently leave the hook capturing the mouse), and matched events by substring inside payloads. The replacement: a per-session named pipe with a user/SYSTEM DACL and session check on Windows, a 0600 Unix socket in XDG_RUNTIME_DIR on Linux; u32-length-prefixed UTF-8 frames capped at 1 MiB; bounded queues; a serialized command worker preserving Load-then-Run order; four-client cap. Same XML message contract - settings and Current.xml stay compatible; DaemonPort remains as a dead property so existing settings deserialize. Current.xml is now written atomically with a .bak the daemon falls back to only when the primary is unreadable or fails to parse - a valid stopped state no longer triggers recovery, and a Run without a successful Load is ignored. Stop gets a safety net: if IPC is down, known hook processes of this session (this UI's child on Unix) are killed rather than left routing input. On top of the #513 version, three of its bugs are fixed here: - the Windows accept loop died permanently on a transient create_pipe error; it now logs, backs off 500 ms and retries - the listener raised ConnectionFailed only once per connect cycle, so a daemon that crashed right after launch was never relaunched; it now re-raises every ~5 s (LaunchDaemon's already-running check makes that idempotent) - UnauthorizedAccessException or a malformed frame killed the event listener silently; both now reconnect like I/O failures And two of its regressions are not taken: the resume watchdog stays ungated (the #513 gating reintroduced the stale-layout-on-wake bug), and daemon launch keeps the #512 elevation model (no runas). The Unix bind also no longer chmods a parent directory it did not create (EPERM on shared parents like /tmp). LBM_HOOK_ENDPOINT replaces LBM_HOOK_PORT for side-by-side testing. The C++ LittleBigMouse.Hook daemon, which only speaks TCP, is retired from distributable builds (decision from the #513 review). Wire contract covered by tests on both sides, including full-duplex under load (events streaming while commands flow) and listener reconnection - the historical pipe failure modes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: MathieuARS <mathieu.maik.15@gmail.com>
pull Bot
pushed a commit
to Mu-L/LittleBigMouse
that referenced
this pull request
Aug 1, 2026
The bounded KEY_NAME_INFORMATION decoding introduced by the mgth#513 review now lives in HLab.Core (WinReg.GetHKeyName/DecodeKeyNameInformation), so every caller of RegistryKey(nint) gets the fix, not just GetEdid. Drop the local duplicate in MonitorDeviceHelper and point the safety test at the shared helper. The shared version is also stricter on the sizing probe: it requires STATUS_BUFFER_TOO_SMALL rather than merely a non-zero status before allocating. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a larger fix pass over the problems that have accumulated around the mouse hook, games, display changes and daemon recovery.
Main changes:
Existing settings and recovery files remain compatible.
Tested locally:
cargo fmt --checkcargo test --all-targets(41 tests)cargo clippy --all-targets --all-features -- -D warningscargo auditThe installer/signing jobs and native Linux runtime still need to run in CI.