Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ fn normalize_typescript_bindings(content: &str) -> String {
}
}

/// RunEvent::Exit 是 Cmd+Q 路径下唯一能拿到的收尾时机,且此后 tao 不会再有任何事件
/// 循环轮次、立刻硬退出,NSStatusBar 又没有暴露"状态栏图标已确认移除"的回调,
/// 只能用短暂延迟换取跨进程注销落地的经验窗口;数值来自实测,不是文档承诺。
#[cfg(target_os = "macos")]
const TRAY_EXIT_GRACE_MS: u64 = 150;

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
logging::install_panic_hook();
Expand Down Expand Up @@ -310,10 +316,22 @@ pub fn run() {
.build(tauri::generate_context!())
.expect("error while running tauri application")
.run(|app_handle, event| {
// 所有退出路径(托盘 Quit / macOS Cmd+Q / 自更新 relaunch)最终都汇聚到
// RunEvent::Exit,在此统一移除托盘图标,规避 macOS 菜单栏进程被系统复活。
if let tauri::RunEvent::Exit = event {
tray::remove_trays(app_handle);
match event {
// ExitRequested 覆盖托盘 Quit(app.exit)与自更新 relaunch(request_restart)
// 两条路径:此刻事件循环仍会至少再跑一轮,足够让状态栏图标的跨进程注销
// 真正生效。Cmd+Q 不会触发这个事件,不能只依赖这里。
tauri::RunEvent::ExitRequested { .. } => {
tray::remove_trays(app_handle);
}
// 所有退出路径最终都汇聚到这里,是 Cmd+Q(原生 [NSApp terminate:],AppKit
// 自己的终止流程,不会触发 ExitRequested)唯一能拿到的收尾时机。对已在
// ExitRequested 移除过的托盘再次调用是无副作用的空操作,兜底覆盖 Cmd+Q。
tauri::RunEvent::Exit => {
tray::remove_trays(app_handle);
#[cfg(target_os = "macos")]
std::thread::sleep(std::time::Duration::from_millis(TRAY_EXIT_GRACE_MS));
}
_ => {}
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions src-tauri/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,8 +1275,9 @@ pub fn setup_tray(app: &tauri::App) -> tauri::Result<()> {

/// 移除两个状态栏托盘图标。macOS 上应用退出前必须调用:否则 FrontBoard 会把菜单栏
/// 应用标记为 after-life.interrupted 并通过 MenuBarAgent 复活以恢复状态栏图标,
/// 表现为“退出后自动重开”。挂在 RunEvent::Exit 上覆盖托盘 Quit / Cmd+Q / 自更新
/// relaunch 等所有退出路径;非 macOS 平台调用无副作用(进程本就在退出)。
/// 表现为“退出后自动重开”。lib.rs 在 RunEvent::ExitRequested(托盘 Quit / 自更新
/// relaunch)与 RunEvent::Exit(含 Cmd+Q 兜底)两处都会调用;重复调用对已移除的
/// 托盘无副作用。非 macOS 平台调用无副作用(进程本就在退出)。
pub(crate) fn remove_trays(app: &tauri::AppHandle) {
let _ = app.remove_tray_by_id(MAIN_TRAY_ID);
let _ = app.remove_tray_by_id(SESSIONS_TRAY_ID);
Expand Down