[PR #424] macOS: QoL bundle (LSUIElement, TCC flow, quit-unfreezable, display wake) + UI polish #416

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

📋 Pull Request Information

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

Base: mainHead: split/05-macos-qol


📝 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

48 files changed (+4119 additions, -574 deletions)

View changed files

📝 .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 (+170 -13)
📝 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 (+36 -0)
📝 input-emulation/src/libei.rs (+41 -2)
📝 input-emulation/src/macos.rs (+100 -1)
📝 input-emulation/src/windows.rs (+24 -1)
📝 input-emulation/src/wlroots.rs (+190 -1)
📝 input-emulation/src/x11.rs (+27 -0)
📝 lan-mouse-gtk/resources/authorization_window.ui (+78 -82)
📝 lan-mouse-gtk/resources/client_row.ui (+17 -14)

...and 28 more files

📄 Description

Summary

Quality-of-life improvements primarily targeting the macOS bundle, plus generally-applicable UI polish that touches the same files.

macOS-specific

  • Cmd+W (afe9456) wires to GtkWindow's window.close action, which on macOS hides the window and flips the activation policy to Accessory — effectively collapses to the menu bar. Linux/Windows unchanged.
  • Default height 700→1400 (8a86b9d) fits every preference group on first paint on ≥1440px-tall displays. Tiling Wayland WMs ignore default-height, so no effect there.
  • Quit unfreezable (39752ee): 3s try_wait() poll on the daemon child with SIGKILL fallback, plus a process-level std::thread 5s force-exit backstop scheduled outside the GTK main loop (so a wedged loop can't prevent it). Worst-case quit latency 5s; normal completes in <1s.
  • Display wake on input (56f828f): emulation backend pokes IOPMAssertionDeclareUserActivity whenever a forwarded event arrives, so a peer-driven keystroke or click wakes the macOS display from idle-sleep. Without this, lan-mouse would keep pumping events to a blanked screen.
  • TCC.db watcher with fresh-subprocess AX probe (5aa3fcc): detects "remove from list" cases where AXIsProcessTrusted in the parent process keeps reporting cached-true even after the entry is removed. Triggers a relaunch prompt rather than letting the daemon silently lose Accessibility.
  • Quit on AX revoked mid-session (9708d9c): an active CGEventTap at HeadInsertEventTap can wedge system input if the process lingers after losing AX, so we exit immediately.
  • Re-present window on app re-launch (53c668b): register the existing status-item delegate as a direct handler for 'aevt'/'rapp' via NSAppleEventManager so reopening the app via Finder/Dock/open brings the window back.
  • Various TCC / Accessibility flow polish: per-pane navigation, Sequoia-tolerant permission flow, hide warning row once granted, fold relaunch prompt into the warning row.

Generally-applicable UI polish

  • Wrap window content in GtkScrolledWindow with propagate-natural-height — the window can shrink under tiling without clipping content.
  • Modal dialogs (Add Certificate, etc.): cap width at 460px and size to parent − 40, replace AdwPreferencesGroup wrappers with plain GtkEntry, tighten vertical spacing, close on Escape.
  • Title-case section labels, period-terminated subtitles, vertical-rhythm tightening, hostname:port collapsed row — cosmetic but consistent.
  • GUI quits when the daemon's IPC connection drops (7fcc08e): prevents a zombie window after the daemon exits.

Test plan

  • Cmd+W collapses the macOS app to the menu bar; the menubar item still works
  • Default height of 1400px shows all preference groups without scrolling on a 1440px-tall display
  • Quit completes in <1s normally; SIGKILL fires within 3s when the daemon is wedged; process-level backstop fires within 5s if the GTK loop itself is wedged
  • Forwarded keystroke from a peer wakes the macOS display from idle sleep
  • Revoking Accessibility mid-session causes the app to exit immediately (no zombie tap)
  • Reopening the app via Finder while it's running brings the window forward (no duplicate process)

Split out from #418, the umbrella PR collecting ~10 independent feature areas. This PR is the macOS QoL + UI polish 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/424 **Author:** [@jondkinney](https://github.com/jondkinney) **Created:** 5/6/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `split/05-macos-qol` --- ### 📝 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 **48 files changed** (+4119 additions, -574 deletions) <details> <summary>View changed files</summary> 📝 `.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` (+170 -13) 📝 `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` (+36 -0) 📝 `input-emulation/src/libei.rs` (+41 -2) 📝 `input-emulation/src/macos.rs` (+100 -1) 📝 `input-emulation/src/windows.rs` (+24 -1) 📝 `input-emulation/src/wlroots.rs` (+190 -1) 📝 `input-emulation/src/x11.rs` (+27 -0) 📝 `lan-mouse-gtk/resources/authorization_window.ui` (+78 -82) 📝 `lan-mouse-gtk/resources/client_row.ui` (+17 -14) _...and 28 more files_ </details> ### 📄 Description ## Summary Quality-of-life improvements primarily targeting the macOS bundle, plus generally-applicable UI polish that touches the same files. ### macOS-specific - **Cmd+W (`afe9456`)** wires to GtkWindow's `window.close` action, which on macOS hides the window and flips the activation policy to `Accessory` — effectively collapses to the menu bar. Linux/Windows unchanged. - **Default height 700→1400 (`8a86b9d`)** fits every preference group on first paint on ≥1440px-tall displays. Tiling Wayland WMs ignore `default-height`, so no effect there. - **Quit unfreezable (`39752ee`)**: 3s `try_wait()` poll on the daemon child with SIGKILL fallback, plus a process-level `std::thread` 5s force-exit backstop scheduled *outside* the GTK main loop (so a wedged loop can't prevent it). Worst-case quit latency 5s; normal completes in <1s. - **Display wake on input (`56f828f`)**: emulation backend pokes `IOPMAssertionDeclareUserActivity` whenever a forwarded event arrives, so a peer-driven keystroke or click wakes the macOS display from idle-sleep. Without this, lan-mouse would keep pumping events to a blanked screen. - **TCC.db watcher with fresh-subprocess AX probe (`5aa3fcc`)**: detects "remove from list" cases where `AXIsProcessTrusted` in the parent process keeps reporting cached-true even after the entry is removed. Triggers a relaunch prompt rather than letting the daemon silently lose Accessibility. - **Quit on AX revoked mid-session (`9708d9c`)**: an active CGEventTap at HeadInsertEventTap can wedge system input if the process lingers after losing AX, so we exit immediately. - **Re-present window on app re-launch (`53c668b`)**: register the existing status-item delegate as a direct handler for `'aevt'/'rapp'` via NSAppleEventManager so reopening the app via Finder/Dock/`open` brings the window back. - **Various TCC / Accessibility flow polish**: per-pane navigation, Sequoia-tolerant permission flow, hide warning row once granted, fold relaunch prompt into the warning row. ### Generally-applicable UI polish - **Wrap window content in `GtkScrolledWindow`** with `propagate-natural-height` — the window can shrink under tiling without clipping content. - **Modal dialogs** (Add Certificate, etc.): cap width at 460px and size to `parent − 40`, replace `AdwPreferencesGroup` wrappers with plain `GtkEntry`, tighten vertical spacing, close on Escape. - **Title-case section labels, period-terminated subtitles, vertical-rhythm tightening, hostname:port collapsed row** — cosmetic but consistent. - **GUI quits when the daemon's IPC connection drops (`7fcc08e`)**: prevents a zombie window after the daemon exits. ## Test plan - [x] Cmd+W collapses the macOS app to the menu bar; the menubar item still works - [x] Default height of 1400px shows all preference groups without scrolling on a 1440px-tall display - [x] Quit completes in <1s normally; SIGKILL fires within 3s when the daemon is wedged; process-level backstop fires within 5s if the GTK loop itself is wedged - [x] Forwarded keystroke from a peer wakes the macOS display from idle sleep - [x] Revoking Accessibility mid-session causes the app to exit immediately (no zombie tap) - [x] Reopening the app via Finder while it's running brings the window forward (no duplicate process) --- Split out from #418, the umbrella PR collecting ~10 independent feature areas. This PR is the macOS QoL + UI polish 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:36 -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#416
No description provided.