From a0ca8c251781dfc3838c917c1da24c971dc6e3f4 Mon Sep 17 00:00:00 2001 From: funnytime <162818986+funnytime75@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:54:59 +0800 Subject: [PATCH] feat: add silent startup option to prevent window popup on launch (issue #708) (#713) --- src-tauri/src/lib.rs | 18 ++++++++++++++++++ src-tauri/src/settings.rs | 4 ++++ src/components/settings/WindowSettings.tsx | 10 +++++++++- src/hooks/useSettingsForm.ts | 2 ++ src/i18n/locales/en.json | 2 ++ src/i18n/locales/ja.json | 2 ++ src/i18n/locales/zh.json | 2 ++ src/types.ts | 2 ++ 8 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 06ee64564..4f9c84871 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -745,6 +745,24 @@ pub fn run() { restore_proxy_state_on_startup(&state).await; }); + // 静默启动:根据设置决定是否显示主窗口 + let settings = crate::settings::get_settings(); + if let Some(window) = app.get_webview_window("main") { + if settings.silent_startup { + // 静默启动模式:保持窗口隐藏 + let _ = window.hide(); + #[cfg(target_os = "windows")] + let _ = window.set_skip_taskbar(true); + #[cfg(target_os = "macos")] + tray::apply_tray_policy(app.handle(), false); + log::info!("静默启动模式:主窗口已隐藏"); + } else { + // 正常启动模式:显示窗口 + let _ = window.show(); + log::info!("正常启动模式:主窗口已显示"); + } + } + Ok(()) }) .invoke_handler(tauri::generate_handler![ diff --git a/src-tauri/src/settings.rs b/src-tauri/src/settings.rs index d6e3c2990..301151a27 100644 --- a/src-tauri/src/settings.rs +++ b/src-tauri/src/settings.rs @@ -79,6 +79,9 @@ pub struct AppSettings { /// 是否开机自启 #[serde(default)] pub launch_on_startup: bool, + /// 静默启动(程序启动时不显示主窗口,仅托盘运行) + #[serde(default)] + pub silent_startup: bool, #[serde(default, skip_serializing_if = "Option::is_none")] pub language: Option, @@ -132,6 +135,7 @@ impl Default for AppSettings { enable_claude_plugin_integration: false, skip_claude_onboarding: false, launch_on_startup: false, + silent_startup: false, language: None, visible_apps: None, claude_config_dir: None, diff --git a/src/components/settings/WindowSettings.tsx b/src/components/settings/WindowSettings.tsx index 47f69e311..cc2cf0dfa 100644 --- a/src/components/settings/WindowSettings.tsx +++ b/src/components/settings/WindowSettings.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "react-i18next"; import type { SettingsFormState } from "@/hooks/useSettings"; -import { AppWindow, MonitorUp, Power } from "lucide-react"; +import { AppWindow, MonitorUp, Power, EyeOff } from "lucide-react"; import { ToggleRow } from "@/components/ui/toggle-row"; interface WindowSettingsProps { @@ -27,6 +27,14 @@ export function WindowSettings({ settings, onChange }: WindowSettingsProps) { onCheckedChange={(value) => onChange({ launchOnStartup: value })} /> + } + title={t("settings.silentStartup")} + description={t("settings.silentStartupDescription")} + checked={!!settings.silentStartup} + onCheckedChange={(value) => onChange({ silentStartup: value })} + /> + } title={t("settings.enableClaudePluginIntegration")} diff --git a/src/hooks/useSettingsForm.ts b/src/hooks/useSettingsForm.ts index 7eee9af91..a10f57acc 100644 --- a/src/hooks/useSettingsForm.ts +++ b/src/hooks/useSettingsForm.ts @@ -83,6 +83,7 @@ export function useSettingsForm(): UseSettingsFormResult { minimizeToTrayOnClose: data.minimizeToTrayOnClose ?? true, enableClaudePluginIntegration: data.enableClaudePluginIntegration ?? false, + silentStartup: data.silentStartup ?? false, skipClaudeOnboarding: data.skipClaudeOnboarding ?? false, claudeConfigDir: sanitizeDir(data.claudeConfigDir), codexConfigDir: sanitizeDir(data.codexConfigDir), @@ -138,6 +139,7 @@ export function useSettingsForm(): UseSettingsFormResult { minimizeToTrayOnClose: serverData.minimizeToTrayOnClose ?? true, enableClaudePluginIntegration: serverData.enableClaudePluginIntegration ?? false, + silentStartup: serverData.silentStartup ?? false, skipClaudeOnboarding: serverData.skipClaudeOnboarding ?? false, claudeConfigDir: sanitizeDir(serverData.claudeConfigDir), codexConfigDir: sanitizeDir(serverData.codexConfigDir), diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 00c9af3e7..ccbf27089 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -265,6 +265,8 @@ "windowBehaviorHint": "Configure window minimize and Claude plugin integration policies.", "launchOnStartup": "Launch on Startup", "launchOnStartupDescription": "Automatically run CC Switch when system starts", + "silentStartup": "Silent Startup", + "silentStartupDescription": "Start in background mode without showing main window", "autoLaunchFailed": "Failed to set auto-launch", "minimizeToTray": "Minimize to tray on close", "minimizeToTrayDescription": "When checked, clicking the close button will hide to system tray, otherwise the app will exit directly.", diff --git a/src/i18n/locales/ja.json b/src/i18n/locales/ja.json index a9254f47b..1b04d6fda 100644 --- a/src/i18n/locales/ja.json +++ b/src/i18n/locales/ja.json @@ -265,6 +265,8 @@ "windowBehaviorHint": "最小化動作や Claude プラグイン連携を設定します。", "launchOnStartup": "起動時に自動実行", "launchOnStartupDescription": "システム起動時に CC Switch を自動起動します", + "silentStartup": "サイレント起動", + "silentStartupDescription": "起動時にメインウィンドウを表示せず、トレイのみで起動", "autoLaunchFailed": "自動起動の設定に失敗しました", "minimizeToTray": "閉じるときトレイへ最小化", "minimizeToTrayDescription": "チェックすると閉じるボタンでトレイに隠し、オフならアプリを終了します。", diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index e86c7aae6..4f492857d 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -265,6 +265,8 @@ "windowBehaviorHint": "配置窗口最小化与 Claude 插件联动策略。", "launchOnStartup": "开机自启", "launchOnStartupDescription": "随系统启动自动运行 CC Switch", + "silentStartup": "静默启动", + "silentStartupDescription": "程序启动时不显示主窗口,仅在系统托盘运行", "autoLaunchFailed": "设置开机自启失败", "minimizeToTray": "关闭时最小化到托盘", "minimizeToTrayDescription": "勾选后点击关闭按钮会隐藏到系统托盘,取消则直接退出应用。", diff --git a/src/types.ts b/src/types.ts index c4fba8fb7..dc2c1a3c3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -162,6 +162,8 @@ export interface Settings { skipClaudeOnboarding?: boolean; // 是否开机自启 launchOnStartup?: boolean; + // 静默启动(程序启动时不显示主窗口) + silentStartup?: boolean; // 首选语言(可选,默认中文) language?: "en" | "zh" | "ja";