From 4a6b5da793e0fde623b957a16dd735501a1967fb Mon Sep 17 00:00:00 2001 From: Johnny Boero Date: Mon, 20 Jul 2026 14:40:10 -0500 Subject: [PATCH] fix(linux): skip click-through toggle on dictate pill to prevent startup crash (#906) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dictate pill window is built hidden at setup and the frontend emits dictate:hide as soon as it mounts. The handler calls set_ignore_cursor_events(true) on a window GTK has never realized, and tao's CursorIgnoreEvents path unwraps the missing GdkWindow (tao-0.34.5 event_loop.rs:449), panicking inside a glib dispatch that cannot unwind — the process aborts within seconds of launch on Linux. The click-through toggle exists as a macOS workaround for transparent always-on-top NSWindows lingering as invisible click targets; it was never needed on Linux. Gate all three call sites so Linux never toggles it: the true/false pair stays balanced (never set, never unset), and macOS/Windows builds are unchanged. Co-authored-by: Claude Fable 5 --- tauri/src-tauri/src/hotkey_monitor.rs | 3 +++ tauri/src-tauri/src/main.rs | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/tauri/src-tauri/src/hotkey_monitor.rs b/tauri/src-tauri/src/hotkey_monitor.rs index c2c01e98..bb0cbd12 100644 --- a/tauri/src-tauri/src/hotkey_monitor.rs +++ b/tauri/src-tauri/src/hotkey_monitor.rs @@ -264,6 +264,9 @@ fn apply_effect(app: &AppHandle, effect: Effect) { let _ = window.set_position(tauri::PhysicalPosition::new(x, y)); } } + // Skip on Linux: aborts if the window was never realized + // (see show_dictate_window in main.rs). + #[cfg(not(target_os = "linux"))] let _ = window.set_ignore_cursor_events(false); // Deliberately no set_focus() — taking key focus would yank // it out of whatever app the user was typing in, which is diff --git a/tauri/src-tauri/src/main.rs b/tauri/src-tauri/src/main.rs index cd5f405b..0f44ac90 100644 --- a/tauri/src-tauri/src/main.rs +++ b/tauri/src-tauri/src/main.rs @@ -112,6 +112,10 @@ pub fn show_dictate_window(app: &tauri::AppHandle) { let _ = window.set_position(PhysicalPosition::new(x, y)); } } + // Skip on Linux: tao's CursorIgnoreEvents handler unwraps the GdkWindow, + // which is None until the window is first shown, aborting the process. + // The click-through toggle is a macOS workaround and is never set on Linux. + #[cfg(not(target_os = "linux"))] let _ = window.set_ignore_cursor_events(false); let _ = window.show(); } @@ -1421,6 +1425,9 @@ pub fn run() { let handle_for_hide = app.handle().clone(); app.handle().listen("dictate:hide", move |_event| { if let Some(window) = handle_for_hide.get_webview_window(DICTATE_WINDOW_LABEL) { + // Skip on Linux: aborts if the window was never realized + // (see show_dictate_window). + #[cfg(not(target_os = "linux"))] let _ = window.set_ignore_cursor_events(true); let _ = window.set_position(PhysicalPosition::new(-10_000, -10_000)); let _ = window.hide();