[PR #426] feat(gui): cross-platform GUI singleton via dedicated socket #418

Open
opened 2026-05-05 22:18:37 -06:00 by gitea-mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/feschber/lan-mouse/pull/426
Author: @jondkinney
Created: 5/6/2026
Status: 🔄 Open

Base: mainHead: split/07-singleton


📝 Commits (10+)

  • 31298f2 feat: cross-platform wall-press auto-release fallback
  • bffbef0 proto: add Bounds(width, height) event variant
  • 2219f45 feat(emulation): display_bounds + warp_cursor for all backends
  • 5de5016 feat(emulation): send Bounds + warp cursor on Enter
  • 68fab55 feat(capture): cache peer bounds and use as wall-press upper clamp
  • 944e758 ui: wrap window content in GtkScrolledWindow
  • 56f7730 ui: rename Auto-Release group to scope it to outgoing capture
  • cd63f5d fix: preserve cross-axis cursor position across machine transitions
  • 2571b47 fix(capture/layer_shell): report screen-space cursor position on Enter
  • cbe2ec1 fix(capture): warp host cursor to guest position on release

📊 Changes

51 files changed (+4748 additions, -597 deletions)

View changed files

.claude/scheduled_tasks.lock (+1 -0)
📝 .gitignore (+1 -0)
📝 Cargo.lock (+494 -204)
📝 Cargo.toml (+5 -1)
📝 input-capture/Cargo.toml (+1 -0)
📝 input-capture/src/dummy.rs (+2 -2)
📝 input-capture/src/layer_shell.rs (+67 -17)
📝 input-capture/src/lib.rs (+574 -11)
📝 input-capture/src/libei.rs (+5 -2)
📝 input-capture/src/macos.rs (+257 -20)
📝 input-capture/src/windows.rs (+1 -1)
📝 input-capture/src/windows/event_thread.rs (+66 -12)
📝 input-capture/src/x11.rs (+1 -1)
📝 input-emulation/src/lib.rs (+49 -0)
📝 input-emulation/src/libei.rs (+49 -2)
📝 input-emulation/src/macos.rs (+110 -1)
📝 input-emulation/src/windows.rs (+41 -4)
📝 input-emulation/src/wlroots.rs (+219 -5)
📝 input-emulation/src/x11.rs (+38 -1)
📝 input-emulation/src/xdg_desktop_portal.rs (+13 -1)

...and 31 more files

📄 Description

Summary

Cross-platform GUI singleton — lan-mouse launched twice no longer opens a second window.

Dedicated lan-mouse-gui.sock (Unix) / 127.0.0.1:5253 (Windows), separate from the daemon socket. First GUI binds; later launches connect, send a byte, and exit. Primary forwards into the GTK main loop and calls window.present().

Decoupled from the daemon socket on purpose: lan-mouse daemon headless workflow is unchanged. Stale-socket recovery if the primary crashed without cleanup. Defense-in-depth via app.windows().first() for the in-process activation path. Unit test covers acquire → signal → re-acquire.

Test plan

  • First GUI invocation binds the singleton socket; window opens
  • Second invocation while the first is running: the second exits cleanly and the first's window is brought forward
  • Primary crashed without cleanup → next GUI invocation reclaims the stale socket and starts fresh
  • Headless lan-mouse daemon workflow unchanged (singleton lock only exists while a GUI is running)
  • In-process activation (DBus single-instance on Linux, kAEReopenApplication on macOS) reuses the existing window via app.windows().first()

Split out from #418, the umbrella PR collecting ~10 independent feature areas. This PR is the GUI singleton subset. See #418 for the full picture.

Stack overview

These PRs are split out from #418 and stack in this order:

  1. #420 — cursor sync + wall-press + host-lock + slider/UI
  2. #421 — peer version exchange
  3. #422 — hostname resolver + multi-homed DTLS listener
  4. #423 — mDNS-SD service-order discovery
  5. #424 — macOS QoL + UI polish
  6. #425 — scroll forwarding
  7. #426 — GUI singleton

Each PR's branch builds on the previous one, so until earlier PRs are merged the cumulative diff against main includes all preceding work. Reviewing in order is easiest.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/feschber/lan-mouse/pull/426 **Author:** [@jondkinney](https://github.com/jondkinney) **Created:** 5/6/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `split/07-singleton` --- ### 📝 Commits (10+) - [`31298f2`](https://github.com/feschber/lan-mouse/commit/31298f29577e06d4fda36188f5721cd93123e17a) feat: cross-platform wall-press auto-release fallback - [`bffbef0`](https://github.com/feschber/lan-mouse/commit/bffbef0875257c24227e6599e64b4e7a0030e1b2) proto: add Bounds(width, height) event variant - [`2219f45`](https://github.com/feschber/lan-mouse/commit/2219f45a1c37ac9f324728470ea7900eb804c2f6) feat(emulation): display_bounds + warp_cursor for all backends - [`5de5016`](https://github.com/feschber/lan-mouse/commit/5de501637d1e6a5e486c9a3799d8c069ae0d5184) feat(emulation): send Bounds + warp cursor on Enter - [`68fab55`](https://github.com/feschber/lan-mouse/commit/68fab558b340a224e075b842f6182b2c7d6646a3) feat(capture): cache peer bounds and use as wall-press upper clamp - [`944e758`](https://github.com/feschber/lan-mouse/commit/944e7582b783252e07c895b16c5440253b8ecbfe) ui: wrap window content in GtkScrolledWindow - [`56f7730`](https://github.com/feschber/lan-mouse/commit/56f7730164171cbb3dfb0176ca2eae7e314460c6) ui: rename Auto-Release group to scope it to outgoing capture - [`cd63f5d`](https://github.com/feschber/lan-mouse/commit/cd63f5d42875bd27f4724eb9fe3ce787e5725c6c) fix: preserve cross-axis cursor position across machine transitions - [`2571b47`](https://github.com/feschber/lan-mouse/commit/2571b47074da9f68e56501eefbb8ea959b67f5a7) fix(capture/layer_shell): report screen-space cursor position on Enter - [`cbe2ec1`](https://github.com/feschber/lan-mouse/commit/cbe2ec13030fa565f1e562ecf5e09cc5d2a8c637) fix(capture): warp host cursor to guest position on release ### 📊 Changes **51 files changed** (+4748 additions, -597 deletions) <details> <summary>View changed files</summary> ➕ `.claude/scheduled_tasks.lock` (+1 -0) 📝 `.gitignore` (+1 -0) 📝 `Cargo.lock` (+494 -204) 📝 `Cargo.toml` (+5 -1) 📝 `input-capture/Cargo.toml` (+1 -0) 📝 `input-capture/src/dummy.rs` (+2 -2) 📝 `input-capture/src/layer_shell.rs` (+67 -17) 📝 `input-capture/src/lib.rs` (+574 -11) 📝 `input-capture/src/libei.rs` (+5 -2) 📝 `input-capture/src/macos.rs` (+257 -20) 📝 `input-capture/src/windows.rs` (+1 -1) 📝 `input-capture/src/windows/event_thread.rs` (+66 -12) 📝 `input-capture/src/x11.rs` (+1 -1) 📝 `input-emulation/src/lib.rs` (+49 -0) 📝 `input-emulation/src/libei.rs` (+49 -2) 📝 `input-emulation/src/macos.rs` (+110 -1) 📝 `input-emulation/src/windows.rs` (+41 -4) 📝 `input-emulation/src/wlroots.rs` (+219 -5) 📝 `input-emulation/src/x11.rs` (+38 -1) 📝 `input-emulation/src/xdg_desktop_portal.rs` (+13 -1) _...and 31 more files_ </details> ### 📄 Description ## Summary Cross-platform GUI singleton — `lan-mouse` launched twice no longer opens a second window. Dedicated `lan-mouse-gui.sock` (Unix) / `127.0.0.1:5253` (Windows), separate from the daemon socket. First GUI binds; later launches connect, send a byte, and exit. Primary forwards into the GTK main loop and calls `window.present()`. Decoupled from the daemon socket on purpose: `lan-mouse daemon` headless workflow is unchanged. Stale-socket recovery if the primary crashed without cleanup. Defense-in-depth via `app.windows().first()` for the in-process activation path. Unit test covers acquire → signal → re-acquire. ## Test plan - [x] First GUI invocation binds the singleton socket; window opens - [x] Second invocation while the first is running: the second exits cleanly and the first's window is brought forward - [x] Primary crashed without cleanup → next GUI invocation reclaims the stale socket and starts fresh - [x] Headless `lan-mouse daemon` workflow unchanged (singleton lock only exists while a GUI is running) - [x] In-process activation (DBus single-instance on Linux, `kAEReopenApplication` on macOS) reuses the existing window via `app.windows().first()` --- Split out from #418, the umbrella PR collecting ~10 independent feature areas. This PR is the GUI singleton subset. See #418 for the full picture. ## Stack overview These PRs are split out from #418 and stack in this order: 1. #420 — cursor sync + wall-press + host-lock + slider/UI 2. #421 — peer version exchange 3. #422 — hostname resolver + multi-homed DTLS listener 4. #423 — mDNS-SD service-order discovery 5. #424 — macOS QoL + UI polish 6. #425 — scroll forwarding 7. #426 — GUI singleton Each PR's branch builds on the previous one, so until earlier PRs are merged the cumulative diff against `main` includes all preceding work. Reviewing in order is easiest. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
gitea-mirror added the
pull-request
label 2026-05-05 22:18:37 -06:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/lan-mouse#418
No description provided.