完善桌面壳托盘关闭行为

主窗口关闭在托盘可用时隐藏到托盘

托盘不可用时保持默认关闭避免窗口无法恢复

补充关闭策略检查测试和架构文档
This commit is contained in:
2026-06-18 08:01:21 +08:00
parent 45a9f9b0cd
commit 88e363586e
4 changed files with 55 additions and 5 deletions

View File

@@ -143,6 +143,11 @@ const requiredMainSnippets = [
'TRAY_MENU_QUIT',
'show_main_window',
'reload_main_window',
'register_desktop_window_close_events',
'resolve_desktop_window_close_action',
'WindowEvent::CloseRequested',
'api.prevent_close()',
'close_window.hide()',
'desktop tray registration failed',
'"appearance.getColorScheme"',
'"app.lifecycle"',

View File

@@ -898,6 +898,12 @@ enum DesktopTrayAction {
Ignore,
}
#[derive(Debug, PartialEq, Eq)]
enum DesktopWindowCloseAction {
HideToTray,
CloseWindow,
}
fn resolve_desktop_tray_menu_action(menu_id: &str) -> DesktopTrayAction {
match menu_id {
TRAY_MENU_SHOW => DesktopTrayAction::ShowMainWindow,
@@ -918,6 +924,14 @@ fn resolve_desktop_tray_icon_action(
}
}
fn resolve_desktop_window_close_action(tray_registered: bool) -> DesktopWindowCloseAction {
if tray_registered {
DesktopWindowCloseAction::HideToTray
} else {
DesktopWindowCloseAction::CloseWindow
}
}
fn show_main_window(app: &tauri::AppHandle) -> tauri::Result<()> {
if let Some(window) = app.get_webview_window("main") {
window.show()?;
@@ -984,6 +998,20 @@ fn register_desktop_tray(app: &tauri::App) -> tauri::Result<()> {
Ok(())
}
fn register_desktop_window_close_events(window: &WebviewWindow, tray_registered: bool) {
let close_window = window.clone();
window.on_window_event(move |event| {
if let WindowEvent::CloseRequested { api, .. } = event {
if resolve_desktop_window_close_action(tray_registered)
== DesktopWindowCloseAction::HideToTray
{
api.prevent_close();
let _ = close_window.hide();
}
}
});
}
fn payload_string<'a>(value: &'a Value, field: &str) -> Option<&'a str> {
value
.get(field)
@@ -1447,13 +1475,18 @@ fn main() {
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_opener::init())
.setup(|app| {
if let Err(error) = register_desktop_tray(app) {
eprintln!("desktop tray registration failed: {error}");
}
let tray_registered = match register_desktop_tray(app) {
Ok(()) => true,
Err(error) => {
eprintln!("desktop tray registration failed: {error}");
false
}
};
let window_config = app.config().app.windows.get(0).cloned();
if let Some(config) = window_config {
let window =
tauri::WebviewWindowBuilder::from_config(app.handle(), &config)?.build()?;
register_desktop_window_close_events(&window, tray_registered);
register_desktop_lifecycle_events(&window);
let _ = emit_desktop_lifecycle_event(&window, "active", true, "created");
let _ = register_desktop_network_events(&window);
@@ -1728,6 +1761,18 @@ mod tests {
);
}
#[test]
fn desktop_close_hides_to_tray_only_when_tray_is_registered() {
assert_eq!(
resolve_desktop_window_close_action(true),
DesktopWindowCloseAction::HideToTray
);
assert_eq!(
resolve_desktop_window_close_action(false),
DesktopWindowCloseAction::CloseWindow
);
}
#[test]
fn external_url_normalization_allows_only_safe_protocols() {
assert_eq!(