mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-05-09 07:38:05 +03:00
macos: fold relaunch prompt into the warning row instead of a toast
The cut-off toast UX ("Accessibility granted. Relaunch Lan Mouse so
capture and emulat…") was unreadable in a compact window and split
the "grant" and "relaunch" flows into two disconnected surfaces. Fold
everything into the existing warning row with state-dependent content:
- AX missing:
title = "input capture is disabled"
subtitle = "grant Accessibility permission to enable"
button = "Grant" → opens System Settings → Accessibility
- AX granted, daemon still bailed:
title = "relaunch required"
subtitle = "Accessibility granted — restart to activate capture
and emulation"
button = "Relaunch" → spawns a fresh bundle via `open` after
a 1s delay, then quits.
- Both active: row hidden.
The emulation_status_row is kept hidden on macOS because capture and
emulation share the same TCC gate — a single row is sufficient and
two identical-looking warnings were noisy. `handle_emulation` still
exists for the non-macOS platforms where the rows are distinct.
Side effects:
- `relaunch_bundle` moved from lib.rs to macos_privacy so imp.rs can
call it from the row button handler.
- AX watcher callback shrinks to `window.present()` +
`refresh_capture_emulation_status()`; the toast-based dialog is
gone along with its helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Ferdinand Schober
parent
2dc9ebb6cd
commit
5d7d14fbf7
@@ -104,6 +104,33 @@ pub fn open_accessibility_settings() {
|
||||
open_url("x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility");
|
||||
}
|
||||
|
||||
/// Spawn a fresh instance of the current `.app` bundle via Launch Services
|
||||
/// after a 1-second delay, so the new instance starts *after* the current
|
||||
/// process has exited — otherwise Launch Services reactivates the existing
|
||||
/// process instead of launching a fresh one, and the stale IPC socket
|
||||
/// would block the new daemon subprocess. The caller is responsible for
|
||||
/// quitting the current process (e.g. `Application::quit()`) after this.
|
||||
pub fn relaunch_bundle() {
|
||||
// Resolve the .app bundle path from the current executable: it lives
|
||||
// at <bundle>/Contents/MacOS/lan-mouse, so three parents up is the
|
||||
// bundle root we hand to `open`.
|
||||
let Ok(exe) = std::env::current_exe() else {
|
||||
return;
|
||||
};
|
||||
let Some(bundle) = exe
|
||||
.parent()
|
||||
.and_then(std::path::Path::parent)
|
||||
.and_then(std::path::Path::parent)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Trailing `&` backgrounds the sleep+open so our shell call returns
|
||||
// immediately; the spawned shell is adopted by launchd once we exit.
|
||||
let cmd = format!("(sleep 1 && open {bundle:?}) &");
|
||||
let _ = Command::new("sh").arg("-c").arg(cmd).spawn();
|
||||
}
|
||||
|
||||
/// Make sure the app appears in System Settings → Privacy → Input Monitoring.
|
||||
///
|
||||
/// `CGRequestListenEventAccess()` is *supposed* to register the app in the
|
||||
|
||||
Reference in New Issue
Block a user