From 01bc780f89211a5457808cb7dffa411f14f072f0 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 19 Oct 2026 18:26:40 +0800 Subject: [PATCH] feat(tray): make the tray panel the default again Clicking the tray icon on macOS and Windows opens the panel again by default. A settings.json without nativeTrayMenu now reads as the panel; an explicitly saved true keeps the native menu, which stays available under Settings > General > Tray style. --- src-tauri/src/settings.rs | 16 ++++++------- .../settings/sections/GeneralSection.tsx | 2 +- src/types.ts | 2 +- .../GeneralSection.trayStyle.test.tsx | 23 ++++++++----------- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src-tauri/src/settings.rs b/src-tauri/src/settings.rs index dbf5c96c3..9e142a2af 100644 --- a/src-tauri/src/settings.rs +++ b/src-tauri/src/settings.rs @@ -450,8 +450,8 @@ pub struct AppSettings { #[serde(default)] pub check_tool_updates_on_startup: bool, /// 点托盘图标出原生菜单,不出托盘面板(macOS / Windows;Linux 只能出原生菜单,不看这一项)。 - /// 默认开:用原生菜单,托盘面板要在设置里手动选。 - #[serde(default = "default_true")] + /// 默认关:用托盘面板,想要原生菜单在设置里换回。 + #[serde(default)] pub native_tray_menu: bool, /// Keep Codex ChatGPT login material in auth.json when switching to third-party providers. /// Opt-in: defaults to false so third-party switches cleanly overwrite auth.json. @@ -638,7 +638,7 @@ impl Default for AppSettings { show_profile_switcher: false, show_provider_search: true, check_tool_updates_on_startup: false, - native_tray_menu: true, + native_tray_menu: false, preserve_codex_official_auth_on_switch: false, unify_codex_session_history: false, unify_codex_migrate_existing: None, @@ -1618,12 +1618,12 @@ mod tests { } #[test] - fn native_tray_menu_defaults_on_and_keeps_a_saved_panel_choice() { - assert!(AppSettings::default().native_tray_menu); + fn native_tray_menu_defaults_off_and_keeps_a_saved_menu_choice() { + assert!(!AppSettings::default().native_tray_menu); let missing: AppSettings = serde_json::from_str("{}").unwrap(); - assert!(missing.native_tray_menu); - let panel: AppSettings = serde_json::from_str(r#"{"nativeTrayMenu":false}"#).unwrap(); - assert!(!panel.native_tray_menu); + assert!(!missing.native_tray_menu); + let menu: AppSettings = serde_json::from_str(r#"{"nativeTrayMenu":true}"#).unwrap(); + assert!(menu.native_tray_menu); } #[test] diff --git a/src/components/settings/sections/GeneralSection.tsx b/src/components/settings/sections/GeneralSection.tsx index 88cd3f42a..c0fc3b76c 100644 --- a/src/components/settings/sections/GeneralSection.tsx +++ b/src/components/settings/sections/GeneralSection.tsx @@ -228,7 +228,7 @@ export function GeneralSection({ void onAutoSave({ nativeTrayMenu: value === "menu" }) } diff --git a/src/types.ts b/src/types.ts index bb8a670b1..b254bf096 100644 --- a/src/types.ts +++ b/src/types.ts @@ -422,7 +422,7 @@ export interface Settings { showProviderSearch?: boolean; // 启动时检查已安装的命令行应用有没有新版本(默认关) checkToolUpdatesOnStartup?: boolean; - // 点托盘图标出原生菜单,不出托盘面板(macOS / Windows;Linux 一律原生菜单;默认开,没写过视为开) + // 点托盘图标出原生菜单,不出托盘面板(macOS / Windows;Linux 一律原生菜单;默认关,没写过视为关,即用托盘面板) nativeTrayMenu?: boolean; // Preserve Codex ChatGPT login in auth.json when switching third-party providers preserveCodexOfficialAuthOnSwitch?: boolean; diff --git a/tests/components/GeneralSection.trayStyle.test.tsx b/tests/components/GeneralSection.trayStyle.test.tsx index 270f83a18..d09dac633 100644 --- a/tests/components/GeneralSection.trayStyle.test.tsx +++ b/tests/components/GeneralSection.trayStyle.test.tsx @@ -45,33 +45,30 @@ describe("GeneralSection tray style", () => { platform.linux = false; }); - it("defaults to the native menu and saves the panel when Panel is picked", () => { + it("defaults to the panel and saves the native menu when Menu is picked", () => { const onAutoSave = renderSection(); const group = screen.getByRole("group", { name: "settings.general.trayStyle", }); expect(group).toBeInTheDocument(); - expect( - screen.getByRole("button", { name: "settings.general.trayStyleMenu" }), - ).toHaveAttribute("aria-pressed", "true"); - - fireEvent.click( - screen.getByRole("button", { name: "settings.general.trayStylePanel" }), - ); - expect(onAutoSave).toHaveBeenCalledWith({ nativeTrayMenu: false }); - }); - - it("switches back to the native menu", () => { - const onAutoSave = renderSection({ nativeTrayMenu: false }); expect( screen.getByRole("button", { name: "settings.general.trayStylePanel" }), ).toHaveAttribute("aria-pressed", "true"); + fireEvent.click( screen.getByRole("button", { name: "settings.general.trayStyleMenu" }), ); expect(onAutoSave).toHaveBeenCalledWith({ nativeTrayMenu: true }); }); + it("switches back to the panel", () => { + const onAutoSave = renderSection({ nativeTrayMenu: true }); + fireEvent.click( + screen.getByRole("button", { name: "settings.general.trayStylePanel" }), + ); + expect(onAutoSave).toHaveBeenCalledWith({ nativeTrayMenu: false }); + }); + it("is hidden on Linux, which only has the native menu", () => { platform.linux = true; renderSection();