From 7ac0421a3f90e435d05852dad26fc9242fab7e07 Mon Sep 17 00:00:00 2001 From: baiqing Date: Sat, 2 May 2026 10:44:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(macos):=20stop=5Fqa=5Fhotkey=5Flistener=20?= =?UTF-8?q?=E5=8C=85=20run=5Fon=5Fmain=5Fthread=20(closes=20#169)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QaHotkeyMonitor::drop 在 macOS 底层调 Carbon RemoveEventHotKey,要求主线程。 RunEvent::Exit 回调不保证在 AppKit 主线程跑——drop 漏到 tokio worker 上 触发 macOS dispatch_assert_queue_fail SIGTRAP,退出时偶发崩溃。 修: - coordinator.rs::stop_qa_hotkey_listener 把 .take() 包到 run_on_main_thread - AppHandle 已 None 时(极端 shutdown 序)直接 drop 兜底(最坏崩也是退出时机) 测试: - cargo check ✅ --- openless-all/app/src-tauri/src/coordinator.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/openless-all/app/src-tauri/src/coordinator.rs b/openless-all/app/src-tauri/src/coordinator.rs index 98c25487..9dbd6313 100644 --- a/openless-all/app/src-tauri/src/coordinator.rs +++ b/openless-all/app/src-tauri/src/coordinator.rs @@ -220,7 +220,20 @@ impl Coordinator { } pub fn stop_qa_hotkey_listener(&self) { - self.inner.qa_hotkey.lock().take(); + // QaHotkeyMonitor::drop 在 macOS 底层是 Carbon RemoveEventHotKey,要求主线程。 + // RunEvent::Exit 回调不保证在 AppKit 主线程跑,drop 漏到 tokio worker 上会 + // 触发 macOS dispatch_assert_queue_fail SIGTRAP。包到 run_on_main_thread 让 + // drop 在主线程发生;AppHandle 已 None 时直接 drop(最坏 crash 也是退出时刻)。 + // 详见 issue #169。 + let app = self.inner.app.lock().clone(); + if let Some(app) = app { + let inner = Arc::clone(&self.inner); + let _ = app.run_on_main_thread(move || { + inner.qa_hotkey.lock().take(); + }); + } else { + self.inner.qa_hotkey.lock().take(); + } } /// 用户在设置里改了 QA 组合键时调用。先持久化(由 prefs.set 完成),