use tauri::Manager; mod clipboard; mod constants; mod download_engine; mod logger; mod mihomo_manager; mod monitor_kernel; mod music; mod network_monitor; mod osd_window; mod process_manager; mod quickpanel; mod screenshot; mod secrets; mod setup; mod shortcut; mod snap_fix; mod terminal; mod translate; mod tray_menu; mod updater; mod win32_util; use download_engine::{ DownloadEngine, downloader_add_task, downloader_cancel_task, downloader_check_url, downloader_focus_window, downloader_get_extension_info, downloader_get_settings, downloader_get_tasks, downloader_inspect, downloader_select_bt_files, downloader_open_dir, downloader_open_url, downloader_pause_task, downloader_redownload, downloader_remove_task, downloader_resume_task, downloader_save_settings, downloader_status, }; use logger::{ log_clear, log_info_state, log_list, log_message, }; use mihomo_manager::{ proxy_activate_profile, proxy_apply_kernel_update, proxy_cancel_kernel_install, proxy_check_kernel_update, proxy_clear_system_proxy, proxy_close_connection, proxy_confirm_install, proxy_delete_profile, proxy_get_connections, proxy_get_proxies, proxy_get_settings, proxy_get_system_proxy, proxy_import_profile, proxy_kernel_info, proxy_patch_configs, proxy_restart, proxy_save_settings, proxy_select_proxy, proxy_set_system_proxy, proxy_start, proxy_status, proxy_stop, proxy_traffic, proxy_test_delay, proxy_update_profile, proxy_version, MihomoManager, }; use monitor_kernel::{ monitor_elevate_self, monitor_get_auto_start, monitor_get_elevate_on_launch, monitor_get_hardware_config, monitor_get_snapshot, monitor_get_status, monitor_kernel_info, monitor_repair_pawnio, monitor_set_auto_start, monitor_set_elevate_on_launch, monitor_set_hardware_config, monitor_start, monitor_start_elevated, monitor_status, monitor_stop, MonitorKernel, }; use music::{ feiniu_activate_connection, feiniu_cache_clear, feiniu_cache_fetch, feiniu_cache_status, feiniu_delete_connection, feiniu_delete_local, feiniu_fnconnect_resolve, feiniu_get_config, feiniu_list_connections, feiniu_list_audio_files, feiniu_list_tracks, feiniu_login, feiniu_logout, feiniu_lyric, feiniu_media_prefix, feiniu_save_connection, feiniu_scan_local, feiniu_test_connection, music_cancel_runtime_install, music_download, music_download_cancel, music_env_status, music_get_settings, music_get_sources, music_install_runtime, music_parse_playlist, music_ping, music_resolve, music_save_settings, music_search, music_secret_get, music_secret_set, music_stop_bridge, music_update_musicdl, webdav_delete, webdav_get_secret, webdav_save_secret, webdav_test, webdav_upload, MusicManager, }; use network_monitor::network_status; use osd_window::{ osd_apply_overlay_style, osd_begin_drag, osd_set_bounds, osd_set_click_through, osd_set_topmost, osd_start_drag_watch, osd_start_game_watch, osd_start_topmost_watch, osd_stop_watch, }; use process_manager::{ process_all_status, process_start, process_status, process_stop, process_stop_all, ProcessManager, }; use screenshot::commands::{ screenshot_capture_fullscreen, screenshot_capture_window, screenshot_clear_fullscreen, screenshot_compose_copy, screenshot_compose_png, screenshot_copy_image, screenshot_crop_copy_stored, screenshot_crop_stored, screenshot_cursor_pos, screenshot_delete_cache, screenshot_disable_transitions, screenshot_enum_windows, screenshot_fullscreen_png, screenshot_get_fullscreen_bmp, screenshot_load_cache, screenshot_load_cache_raw, screenshot_pick_list, screenshot_register_pin_shortcut, screenshot_register_shortcut, screenshot_save_cache, screenshot_save_png, screenshot_scroll_capture, screenshot_scroll_cancel, screenshot_scroll_finish, screenshot_scroll_start, screenshot_set_scroll_hole, screenshot_show_overlay, screenshot_take_editor_image_raw, screenshot_unregister_pin_shortcut, screenshot_unregister_shortcut, }; use clipboard::{ ClipboardManager, clipboard_clear, clipboard_copy_back, clipboard_count, clipboard_delete, clipboard_get_history, clipboard_get_item, clipboard_get_pinned, clipboard_get_settings, clipboard_get_thumb, clipboard_hide_popup, clipboard_hide_preview, clipboard_paste_to_target, clipboard_preview_interacted, clipboard_register_shortcut, clipboard_reveal_preview, clipboard_save_settings, clipboard_search, clipboard_set_pinned, clipboard_resize_preview, clipboard_show_popup, clipboard_show_preview, clipboard_show_window, clipboard_start, clipboard_status, clipboard_stop, clipboard_unregister_shortcut, }; use quickpanel::{ quickpanel_apply_rename, quickpanel_batch_extract, quickpanel_build_file_index, quickpanel_clear_app_icon_cache, quickpanel_delete_file, quickpanel_delete_files, quickpanel_file_index_stats, quickpanel_get_app_icon, quickpanel_get_settings, quickpanel_get_special_locations, quickpanel_hide_popup, quickpanel_init_file_index, quickpanel_list_archives, quickpanel_list_dir, quickpanel_lock_screen, quickpanel_open_file, quickpanel_open_special, quickpanel_preview_rename, quickpanel_register_shortcut, quickpanel_reveal_in_explorer, quickpanel_run_custom_command, quickpanel_run_system_command, quickpanel_save_settings, quickpanel_scan_apps, quickpanel_search_files, quickpanel_show_popup, quickpanel_show_window, quickpanel_unregister_shortcut, quickpanel_focus_main_window, }; use tray_menu::{tray_menu_action, tray_menu_hide, tray_menu_ready}; use terminal::commands::{ terminal_attach_session, terminal_clear_known_hosts, terminal_clear_session, terminal_close_session, terminal_confirm_host_key, terminal_default_cwd, terminal_delete_host, terminal_delete_key, terminal_delete_shell, terminal_detach_session, terminal_export_known_hosts, terminal_forget_host, terminal_generate_key, terminal_get_settings, terminal_import_key, terminal_import_known_hosts, terminal_import_ssh_config, terminal_key_public, terminal_list_hosts, terminal_list_known_hosts, terminal_list_keys, terminal_list_sessions, terminal_list_shells, terminal_new_host_id, terminal_open_local, terminal_open_ssh, terminal_open_local_path, terminal_reveal_local_path, terminal_refresh_shells, terminal_rename_key, terminal_rename_session, terminal_resize, terminal_save_appearance, terminal_save_host, terminal_save_layout, terminal_save_security, terminal_save_selection, terminal_save_settings, terminal_save_shell, terminal_save_shortcuts, terminal_send_key, terminal_session_alive, terminal_session_cwd, terminal_session_cwd_value, terminal_set_host_password, terminal_set_encoding, terminal_set_key_passphrase, terminal_set_last_shell, terminal_test_shell, terminal_write, // SFTP 文件管理(P1) terminal_sftp_close, terminal_sftp_delete, terminal_sftp_download, terminal_sftp_is_open, terminal_sftp_list, terminal_sftp_mkdir, terminal_sftp_open, terminal_sftp_parent, terminal_sftp_read_link, terminal_sftp_rename, terminal_sftp_upload, // 命令片段(P1) terminal_delete_snippet, terminal_list_snippets, terminal_render_snippet, terminal_restore_default_snippets, terminal_run_snippet, terminal_save_snippet, // 命令历史(P1) terminal_history_clear, terminal_history_delete, terminal_history_query, terminal_history_run, terminal_history_sources, terminal_history_toggle_favorite, // 端口转发(P2) terminal_add_forward, terminal_list_forwards, terminal_remove_forward, // 会话日志(P2) terminal_log_path, terminal_toggle_logging, // 主机配置同步(P2) terminal_export_hosts, terminal_import_hosts, // 会话模板(P2) terminal_delete_template, terminal_save_template, // AI 命令助手(P2) terminal_ai_engines, terminal_ai_suggest, }; use terminal::TerminalManager; use translate::{ translate_abort, translate_apply_shortcuts, translate_copy_text, translate_engine_delete, translate_engine_models, translate_engine_save, translate_engine_test_config, translate_engines_list, translate_get_settings, translate_history_clear, translate_history_delete, translate_history_list, translate_history_set_favorited, translate_ocr_languages, translate_paste_back, translate_popup_edit_mode, translate_popup_hide, translate_popup_prefs_set, translate_popup_ready, translate_popup_resize, translate_popup_set_pinned, translate_preview_popup, translate_run, translate_save_settings, translate_screenshot_region, translate_secret_clear, translate_secret_set, translate_stream_start, }; use updater::{ app_version, update_check, update_install, update_thinghk_apply, update_thinghk_cancel, update_thinghk_confirm, ThinghkUpdateState, }; #[tauri::command] fn quit_app(app: tauri::AppHandle) { // 资源清理统一收敛到 RunEvent::ExitRequested(覆盖所有退出路径),此处仅请求退出 app.exit(0); } /// 导出 tauri-specta 生成的 TypeScript 类型与命令绑定(仅 debug 构建,开发时自动刷新)。 /// 覆盖 proxy / quickpanel / clipboard / download_engine / screenshot / translate 等模块; /// 豁免清单(返回 serde_json::Value 或 tauri::ipc::Response/Request,specta 无法生成): /// proxy_version / proxy_get_proxies / proxy_get_connections / proxy_patch_configs、 /// downloader_status / downloader_get_extension_info、 /// screenshot_get_fullscreen_bmp(返回 ipc::Response)/ screenshot_compose_copy(接收 ipc::Request)、 /// music_ping / music_get_sources / music_search(返回 serde_json::Value)。 /// /// 注意:export 结果写入 `../src/lib/bindings.ts`,因此**新增模块的命令后需至少以 debug /// 构建运行一次**,前端才能用 `commands.xxx` 拿到类型。在此之前前端若需调用, /// 只能退回原生 `invoke`(返回类型需自行声明)。 #[cfg(debug_assertions)] fn export_bindings() { use specta_typescript::Typescript; use tauri_specta::{Builder, ErrorHandlingMode, collect_commands}; Builder::::new() // 全局把 u64/i64 映射为 number(项目取值均在 JS 安全整数范围:大小/时间戳/limit) .dangerously_cast_bigints_to_number() // 生成命令失败时直接 throw,与原生 invoke 一致,前端无需解包 helper .error_handling(ErrorHandlingMode::Throw) .commands(collect_commands![ // 应用更新(6) app_version, update_check, update_install, update_thinghk_apply, update_thinghk_confirm, update_thinghk_cancel, // proxy(20) proxy_activate_profile, proxy_apply_kernel_update, proxy_cancel_kernel_install, proxy_check_kernel_update, proxy_clear_system_proxy, proxy_close_connection, proxy_confirm_install, proxy_delete_profile, proxy_get_settings, proxy_get_system_proxy, proxy_import_profile, proxy_kernel_info, proxy_restart, proxy_save_settings, proxy_select_proxy, proxy_set_system_proxy, proxy_start, proxy_status, proxy_stop, proxy_traffic, proxy_test_delay, proxy_update_profile, // quickpanel(22) quickpanel_get_settings, quickpanel_save_settings, quickpanel_register_shortcut, quickpanel_unregister_shortcut, quickpanel_show_popup, quickpanel_hide_popup, quickpanel_show_window, quickpanel_lock_screen, quickpanel_init_file_index, quickpanel_build_file_index, quickpanel_search_files, quickpanel_file_index_stats, quickpanel_scan_apps, quickpanel_get_app_icon, quickpanel_clear_app_icon_cache, quickpanel_reveal_in_explorer, quickpanel_open_file, quickpanel_get_special_locations, quickpanel_open_special, quickpanel_delete_file, quickpanel_run_custom_command, quickpanel_run_system_command, quickpanel_list_archives, quickpanel_list_dir, quickpanel_batch_extract, quickpanel_preview_rename, quickpanel_apply_rename, quickpanel_delete_files, quickpanel_focus_main_window, // clipboard(23) clipboard_get_history, clipboard_get_pinned, clipboard_search, clipboard_get_item, clipboard_get_thumb, clipboard_set_pinned, clipboard_delete, clipboard_clear, clipboard_copy_back, clipboard_count, clipboard_get_settings, clipboard_save_settings, clipboard_status, clipboard_start, clipboard_stop, clipboard_register_shortcut, clipboard_unregister_shortcut, clipboard_show_popup, clipboard_hide_popup, clipboard_show_window, clipboard_paste_to_target, clipboard_show_preview, clipboard_hide_preview, clipboard_resize_preview, clipboard_reveal_preview, clipboard_preview_interacted, // download_engine(10,豁免 2) downloader_get_tasks, downloader_check_url, downloader_add_task, downloader_pause_task, downloader_resume_task, downloader_cancel_task, downloader_redownload, downloader_remove_task, downloader_get_settings, downloader_save_settings, downloader_open_dir, downloader_open_url, downloader_focus_window, downloader_inspect, downloader_select_bt_files, // music(6,豁免 3:music_ping / music_get_sources / music_search 返回 serde_json::Value) music_env_status, music_install_runtime, music_cancel_runtime_install, music_stop_bridge, music_get_settings, music_save_settings, // screenshot(23,豁免 3:get_fullscreen_bmp / take_editor_image_raw 返回 ipc::Response、 // compose_copy / compose_png 接收 ipc::Request) screenshot_disable_transitions, screenshot_show_overlay, screenshot_register_shortcut, screenshot_unregister_shortcut, screenshot_register_pin_shortcut, screenshot_unregister_pin_shortcut, screenshot_capture_fullscreen, screenshot_fullscreen_png, screenshot_clear_fullscreen, screenshot_crop_stored, screenshot_crop_copy_stored, screenshot_pick_list, screenshot_cursor_pos, screenshot_enum_windows, screenshot_capture_window, screenshot_scroll_capture, screenshot_scroll_cancel, screenshot_scroll_finish, screenshot_scroll_start, screenshot_set_scroll_hole, screenshot_copy_image, screenshot_save_png, screenshot_save_cache, screenshot_load_cache, screenshot_delete_cache, // translate(20) translate_get_settings, translate_save_settings, translate_apply_shortcuts, translate_engines_list, translate_engine_save, translate_engine_delete, translate_secret_set, translate_secret_clear, translate_engine_test_config, translate_engine_models, translate_run, translate_copy_text, translate_preview_popup, translate_popup_ready, translate_popup_hide, translate_popup_edit_mode, translate_popup_set_pinned, translate_popup_prefs_set, translate_popup_resize, translate_screenshot_region, translate_ocr_languages, translate_history_list, translate_history_delete, translate_history_clear, translate_history_set_favorited, translate_stream_start, translate_abort, translate_paste_back, // terminal(41:39 业务 + key_public / new_host_id 两个辅助) terminal_get_settings, terminal_save_settings, terminal_save_appearance, terminal_save_layout, terminal_save_selection, terminal_save_security, terminal_save_shortcuts, terminal_list_shells, terminal_refresh_shells, terminal_save_shell, terminal_delete_shell, terminal_set_last_shell, terminal_test_shell, terminal_default_cwd, terminal_open_local, terminal_open_ssh, terminal_list_sessions, terminal_close_session, terminal_write, terminal_resize, terminal_rename_session, terminal_detach_session, terminal_attach_session, terminal_session_cwd, terminal_send_key, terminal_clear_session, terminal_session_alive, terminal_set_encoding, terminal_list_hosts, terminal_save_host, terminal_delete_host, terminal_set_host_password, terminal_import_ssh_config, terminal_list_keys, terminal_generate_key, terminal_import_key, terminal_delete_key, terminal_rename_key, terminal_set_key_passphrase, terminal_key_public, terminal_new_host_id, terminal_list_known_hosts, terminal_forget_host, terminal_clear_known_hosts, terminal_export_known_hosts, terminal_import_known_hosts, terminal_confirm_host_key, // 命令历史(6 个) // // 注意:这 6 个命令**必须与 `run()` 里那份 `collect_commands!` 同时登记**。 // 只登记其中一处不会报错:漏了这里 = 运行时能调但 `bindings.ts` 里没有类型; // 漏了那边 = 有类型但调用失败。两种都是「编译/启动全绿但功能静默不可用」。 terminal_history_query, terminal_history_sources, terminal_history_toggle_favorite, terminal_history_delete, terminal_history_clear, terminal_history_run, ]) .export(Typescript::default(), "../src/lib/bindings.ts") .expect("failed to export bindings"); } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { #[cfg(debug_assertions)] export_bindings(); tauri::Builder::default() .plugin(tauri_plugin_autostart::Builder::new().build()) .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_dialog::init()) // 截图快捷键改由 screenshot::shortcut::register_shortcut(on_shortcut)按需注册, // 支持自定义;默认 Ctrl+Alt+A 由前端 store 启动时注册 .plugin(tauri_plugin_global_shortcut::Builder::new().build()) .plugin(tauri_plugin_notification::init()) .plugin( tauri_plugin_snap_layout::init() .button_id("titlebar-maximize") .build() ) .manage(ProcessManager::new()) .manage(ThinghkUpdateState::new()) .invoke_handler(tauri::generate_handler![ quit_app, app_version, update_check, update_install, update_thinghk_apply, update_thinghk_confirm, update_thinghk_cancel, process_start, process_stop, process_status, process_all_status, process_stop_all, log_message, log_list, log_clear, log_info_state, proxy_get_settings, proxy_save_settings, proxy_kernel_info, proxy_check_kernel_update, proxy_apply_kernel_update, proxy_cancel_kernel_install, proxy_confirm_install, proxy_status, proxy_start, proxy_stop, proxy_traffic, proxy_restart, proxy_version, proxy_get_proxies, proxy_select_proxy, proxy_test_delay, proxy_get_connections, proxy_close_connection, proxy_patch_configs, proxy_import_profile, proxy_update_profile, proxy_delete_profile, proxy_activate_profile, proxy_set_system_proxy, proxy_clear_system_proxy, proxy_get_system_proxy, monitor_kernel_info, monitor_status, monitor_start, monitor_start_elevated, monitor_elevate_self, monitor_stop, monitor_get_status, monitor_repair_pawnio, monitor_get_snapshot, monitor_get_elevate_on_launch, monitor_set_elevate_on_launch, monitor_get_auto_start, monitor_set_auto_start, monitor_get_hardware_config, monitor_set_hardware_config, music_env_status, music_install_runtime, music_cancel_runtime_install, music_update_musicdl, music_ping, music_stop_bridge, music_get_sources, music_search, music_parse_playlist, music_resolve, music_get_settings, music_save_settings, music_download, music_download_cancel, feiniu_list_connections, feiniu_save_connection, feiniu_delete_connection, feiniu_activate_connection, feiniu_test_connection, feiniu_login, feiniu_logout, feiniu_get_config, feiniu_list_tracks, feiniu_lyric, feiniu_media_prefix, feiniu_scan_local, feiniu_list_audio_files, feiniu_cache_status, feiniu_cache_clear, feiniu_cache_fetch, feiniu_fnconnect_resolve, webdav_test, webdav_upload, webdav_delete, webdav_get_secret, webdav_save_secret, music_secret_get, music_secret_set, feiniu_delete_local, network_status, osd_apply_overlay_style, osd_begin_drag, osd_set_bounds, osd_set_click_through, osd_set_topmost, osd_start_drag_watch, osd_start_topmost_watch, osd_start_game_watch, osd_stop_watch, downloader_get_tasks, downloader_add_task, downloader_check_url, downloader_pause_task, downloader_resume_task, downloader_cancel_task, downloader_redownload, downloader_remove_task, downloader_get_settings, downloader_save_settings, downloader_status, downloader_get_extension_info, downloader_open_dir, downloader_open_url, downloader_focus_window, downloader_inspect, downloader_select_bt_files, clipboard_get_history, clipboard_get_pinned, clipboard_search, clipboard_get_item, clipboard_get_thumb, clipboard_set_pinned, clipboard_delete, clipboard_clear, clipboard_copy_back, clipboard_count, clipboard_get_settings, clipboard_save_settings, clipboard_status, clipboard_start, clipboard_stop, clipboard_register_shortcut, clipboard_unregister_shortcut, clipboard_show_popup, clipboard_show_window, clipboard_hide_popup, clipboard_paste_to_target, clipboard_show_preview, clipboard_hide_preview, clipboard_resize_preview, clipboard_reveal_preview, clipboard_preview_interacted, quickpanel_get_settings, quickpanel_save_settings, quickpanel_register_shortcut, quickpanel_unregister_shortcut, quickpanel_show_popup, quickpanel_show_window, quickpanel_hide_popup, quickpanel_lock_screen, quickpanel_init_file_index, quickpanel_build_file_index, quickpanel_search_files, quickpanel_file_index_stats, quickpanel_scan_apps, quickpanel_get_app_icon, quickpanel_clear_app_icon_cache, quickpanel_reveal_in_explorer, quickpanel_open_file, quickpanel_delete_file, quickpanel_delete_files, quickpanel_run_custom_command, quickpanel_run_system_command, quickpanel_get_special_locations, quickpanel_open_special, quickpanel_list_archives, quickpanel_list_dir, quickpanel_batch_extract, quickpanel_preview_rename, quickpanel_apply_rename, quickpanel_focus_main_window, tray_menu_action, tray_menu_hide, tray_menu_ready, snap_fix::fix_snap_background, screenshot_capture_fullscreen, screenshot_get_fullscreen_bmp, screenshot_fullscreen_png, screenshot_clear_fullscreen, screenshot_crop_stored, screenshot_crop_copy_stored, screenshot_pick_list, screenshot_show_overlay, screenshot_cursor_pos, screenshot_enum_windows, screenshot_capture_window, screenshot_scroll_capture, screenshot_scroll_cancel, screenshot_scroll_finish, screenshot_scroll_start, screenshot_set_scroll_hole, screenshot_take_editor_image_raw, screenshot_copy_image, screenshot_save_png, screenshot_save_cache, screenshot_load_cache, screenshot_load_cache_raw, screenshot_delete_cache, screenshot_register_shortcut, screenshot_unregister_shortcut, screenshot_register_pin_shortcut, screenshot_unregister_pin_shortcut, screenshot_disable_transitions, screenshot_compose_copy, screenshot_compose_png, translate_get_settings, translate_save_settings, translate_apply_shortcuts, translate_engines_list, translate_engine_save, translate_engine_delete, translate_secret_set, translate_secret_clear, translate_engine_test_config, translate_engine_models, translate_run, translate_copy_text, translate_preview_popup, translate_popup_ready, translate_popup_hide, translate_popup_edit_mode, translate_popup_set_pinned, translate_popup_prefs_set, translate_popup_resize, translate_screenshot_region, translate_ocr_languages, translate_history_list, translate_history_delete, translate_history_clear, translate_history_set_favorited, translate_stream_start, translate_abort, translate_paste_back, terminal_get_settings, terminal_save_settings, terminal_save_appearance, terminal_save_layout, terminal_save_selection, terminal_save_security, terminal_save_shortcuts, terminal_list_shells, terminal_refresh_shells, terminal_save_shell, terminal_delete_shell, terminal_set_last_shell, terminal_test_shell, terminal_default_cwd, terminal_open_local, terminal_open_ssh, terminal_list_sessions, terminal_close_session, terminal_write, terminal_resize, terminal_rename_session, terminal_detach_session, terminal_attach_session, terminal_session_cwd, terminal_set_encoding, terminal_send_key, terminal_clear_session, terminal_session_alive, terminal_list_hosts, terminal_save_host, terminal_delete_host, terminal_set_host_password, terminal_import_ssh_config, terminal_list_keys, terminal_generate_key, terminal_import_key, terminal_delete_key, terminal_rename_key, terminal_set_key_passphrase, terminal_key_public, terminal_new_host_id, terminal_list_known_hosts, terminal_forget_host, terminal_clear_known_hosts, terminal_export_known_hosts, terminal_import_known_hosts, terminal_confirm_host_key, // SFTP 文件管理(P1) terminal_sftp_is_open, terminal_sftp_open, terminal_sftp_close, terminal_sftp_list, terminal_sftp_parent, terminal_sftp_read_link, terminal_sftp_mkdir, terminal_sftp_delete, terminal_sftp_rename, terminal_sftp_upload, terminal_sftp_download, terminal_session_cwd_value, // 本地文件操作(SFTP 面板的「打开 / 在资源管理器中显示」) terminal_open_local_path, terminal_reveal_local_path, // 命令片段(P1) terminal_list_snippets, terminal_save_snippet, terminal_delete_snippet, terminal_render_snippet, terminal_run_snippet, terminal_restore_default_snippets, // 命令历史(P1) terminal_history_query, terminal_history_sources, terminal_history_toggle_favorite, terminal_history_delete, terminal_history_clear, terminal_history_run, // 端口转发(P2) terminal_add_forward, terminal_list_forwards, terminal_remove_forward, // 会话日志(P2) terminal_log_path, terminal_toggle_logging, // 主机配置同步(P2) terminal_export_hosts, terminal_import_hosts, // 会话模板(P2) terminal_delete_template, terminal_save_template, // AI 命令助手(P2) terminal_ai_engines, terminal_ai_suggest ]) .setup(setup::init) .on_window_event(|window, event| { // 仅主窗口拦截关闭(隐藏到托盘)。其他窗口(截图编辑器/OSD 等) // 调用 close() 是真实销毁语义,全局拦截会导致隐藏窗口累积泄漏。 if window.label() == constants::windows::MAIN { if let tauri::WindowEvent::CloseRequested { api, .. } = event { window.hide().ok(); api.prevent_close(); } } }) .build(tauri::generate_context!()) .expect("error while building tauri application") .run(|app, event| { if let tauri::RunEvent::ExitRequested { .. } = event { if let Some(mihomo) = app.try_state::() { mihomo.cleanup_on_exit(); } if let Some(engine) = app.try_state::() { engine.cleanup_on_exit(); } if let Some(monitor) = app.try_state::() { // cleanup_on_exit 是 async;在事件循环回调中直接 block_on 有 panic 风险且阻塞退出, // 放到独立 OS 线程执行并通过 channel 限时等待 3s,超时放弃等待直接退出 // (进程终止时 OS 回收残留资源),避免清理挂起导致退出卡死。 let app_clone = app.clone(); let monitor_clone = monitor.inner().clone(); let (tx, rx) = std::sync::mpsc::channel::<()>(); std::thread::spawn(move || { tauri::async_runtime::block_on(async move { monitor_clone.cleanup_on_exit(&app_clone).await; }); let _ = tx.send(()); }); let _ = rx.recv_timeout(std::time::Duration::from_secs(3)); } if let Some(music) = app.try_state::() { // 停止音乐桥接进程(kill 快速返回,wait 在后台线程完成) music.cleanup_on_exit(); } if let Some(term) = app.try_state::() { // 关闭全部终端会话。**不等待**:ConPTY 的 ClosePseudoConsole 会 // 阻塞到所有句柄关闭,退出路径上等待会卡死(会话侧已把关闭动作 // 放进后台线程,进程终止时 OS 回收剩余资源)。 term.cleanup_on_exit(); } if let Some(clip) = app.try_state::() { clip.stop(); } if let Some(pm) = app.try_state::() { pm.stop_all(); } } }); }