From ccd2694d43c2fdc52ab10c15b22778be3488ebf3 Mon Sep 17 00:00:00 2001 From: musistudio Date: Thu, 2 Jul 2026 18:30:24 +0800 Subject: [PATCH] Open main window from tray and hide it on close --- src/main/tray-controller.ts | 14 ++++++++++++++ src/main/windows.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/tray-controller.ts b/src/main/tray-controller.ts index 11d5b1e..7379dd0 100644 --- a/src/main/tray-controller.ts +++ b/src/main/tray-controller.ts @@ -6,6 +6,7 @@ import { loadAppConfig } from "./config"; import { APP_NAME } from "./constants"; import { getProviderAccountSnapshots } from "./provider-account-service"; import { getTodayUsageTotals, onUsageRecorded } from "./usage-store"; +import windowsManager from "./windows"; import type { AppConfig, ProviderAccountMeter, TrayBalanceProgressConfig, TrayIconPreference } from "../shared/app"; const popoverMenuWidth = 420; @@ -58,6 +59,10 @@ class TrayController { this.suppressMainWindowActivation(); this.togglePopover(); }); + this.tray.on("double-click", () => { + this.suppressMainWindowActivation(); + this.showMainWindow(); + }); this.tray.on("right-click", () => { this.suppressMainWindowActivation(); this.showContextMenu(); @@ -275,6 +280,10 @@ class TrayController { label: formatTokenTitle(this.trayTotalTokens) }, { type: "separator" }, + { + click: () => this.showMainWindow(), + label: `Open ${APP_NAME}` + }, { click: () => this.showPopover(), label: "Show Usage" @@ -289,6 +298,11 @@ class TrayController { this.tray?.popUpContextMenu(menu); } + private showMainWindow(): void { + this.hidePopover(); + windowsManager.showMainWindow(); + } + private showDetailPopover(provider?: string): void { if (!this.popover || this.popover.isDestroyed() || !this.popover.isVisible()) { return; diff --git a/src/main/windows.ts b/src/main/windows.ts index e010725..634ec51 100644 --- a/src/main/windows.ts +++ b/src/main/windows.ts @@ -57,6 +57,13 @@ class WindowsManager { window.show(); } }); + window.on("close", (event) => { + if (!shouldHideMainWindowOnClose()) { + return; + } + event.preventDefault(); + window.hide(); + }); window.on("closed", () => this.windows.delete("main")); window.webContents.on("page-title-updated", (_event, title) => { window.setTitle(title || APP_NAME); @@ -115,10 +122,17 @@ const windowsManager = new WindowsManager(); export default windowsManager; +let appIsQuitting = false; + app.on("before-quit", () => { + appIsQuitting = true; windowsManager.broadcast(IPC_CHANNELS.appBeforeQuit); }); +function shouldHideMainWindowOnClose(): boolean { + return process.platform === "win32" && !appIsQuitting; +} + function fitWindowSize(preferred: number, minimum: number, available: number): number { return Math.max(minimum, Math.min(preferred, available > 0 ? available : preferred)); }