diff --git a/src-tauri/src/feat/window.rs b/src-tauri/src/feat/window.rs index a5b88544..d8975482 100644 --- a/src-tauri/src/feat/window.rs +++ b/src-tauri/src/feat/window.rs @@ -1,6 +1,9 @@ use crate::utils::resolve; use crate::core::handle; +use crate::core::{sysopt, CoreManager, clash_api}; +use crate::config::Config; use tauri::Manager; +use futures; use tauri_plugin_window_state::{AppHandleExt, StateFlags}; /// Open or close the dashboard window @@ -75,12 +78,57 @@ pub fn setup_window_state_monitor(app_handle: &tauri::AppHandle) { }); } -/// Quit the application +/// 优化的应用退出函数 pub fn quit(code: Option) { + log::debug!(target: "app", "启动退出流程"); + + // 获取应用句柄并设置退出标志 let app_handle = handle::Handle::global().app_handle().unwrap(); handle::Handle::global().set_is_exiting(); - super::toggle_tun_mode(Some(true)); - resolve::resolve_reset(); - let _ = handle::Handle::global().get_window().unwrap().close(); - app_handle.exit(code.unwrap_or(0)); + + // 优先关闭窗口,提供立即反馈 + if let Some(window) = handle::Handle::global().get_window() { + let _ = window.hide(); + } + + // 在单独线程中处理资源清理,避免阻塞主线程 + std::thread::spawn(move || { + // 使用tokio运行时执行异步清理任务 + tauri::async_runtime::block_on(async { + // 使用超时机制处理清理操作 + use tokio::time::{timeout, Duration}; + + // 1. 直接关闭TUN模式 (优先处理,通常最容易卡住) + if Config::verge().data().enable_tun_mode.unwrap_or(false) { + let mut disable = serde_yaml::Mapping::new(); + let mut tun = serde_yaml::Mapping::new(); + tun.insert("enable".into(), false.into()); + disable.insert("tun".into(), tun.into()); + + // 设置1秒超时 + let _ = timeout(Duration::from_secs(1), + clash_api::patch_configs(&disable)).await; + } + + // 2. 并行处理系统代理和核心进程清理 + let proxy_future = timeout(Duration::from_secs(1), + sysopt::Sysopt::global().reset_sysproxy()); + + let core_future = timeout(Duration::from_secs(1), + CoreManager::global().stop_core()); + + // 同时等待两个任务完成 + let _ = futures::join!(proxy_future, core_future); + + // 3. 处理macOS特定清理 + #[cfg(target_os = "macos")] + { + let _ = timeout(Duration::from_millis(500), + resolve::restore_public_dns()).await; + } + }); + + // 无论清理结果如何,确保应用退出 + app_handle.exit(code.unwrap_or(0)); + }); }