diff --git a/electron/main/index.ts b/electron/main/index.ts index 941d8a1e..6f5a7a53 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -876,6 +876,14 @@ app.whenReady().then(() => { }); }); +ipcMain.handle('window:state', () => { + const win = BrowserWindow.getFocusedWindow() + if (!win) return 'normal' + if (win.isMaximized()) return 'maximized' + if (win.isMinimized()) return 'minimized' + return 'normal' +}) + // New window example arg: new windows url // ipcMain.handle('open-win', (_, arg) => { // const childWindow = new BrowserWindow({ diff --git a/electron/preload/index.ts b/electron/preload/index.ts index da219272..27f490b5 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -51,6 +51,7 @@ type WindowControlBridge = { minimize: () => void; toggleMaximize: () => void; close: () => void; + state: () => Promise<| 'normal' | 'maximized' | 'minimized'>; }; type UpdateCenterStateListener = (snapshot: UpdateCenterSnapshot) => void; @@ -110,6 +111,7 @@ contextBridge.exposeInMainWorld("windowControls", { minimize: () => ipcRenderer.send("window-control-minimize"), toggleMaximize: () => ipcRenderer.send("window-control-toggle-maximize"), close: () => ipcRenderer.send("window-control-close"), + state: () => ipcRenderer.invoke("window:state"), } satisfies WindowControlBridge); contextBridge.exposeInMainWorld("updateCenter", { diff --git a/src/App.vue b/src/App.vue index d5bb3b55..ff74079f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -14,6 +14,7 @@ @toggle-theme="toggleTheme" @toggle-sidebar="isSidebarOpen = !isSidebarOpen" @spk-link="handleSpkLink" + :is-maximized="isMaximized" />
@@ -546,6 +547,11 @@ const isDarkTheme = computed(() => { return themeMode.value === "dark"; }); +const isMaximized = ref(false) +const updateIsMaximizedState = async () => { + const state = await window.windowControls.state() + isMaximized.value = state === 'maximized' +} const isSubmitterView = ref(false); // 启动参数 --no-apm => 仅 Spark;--no-spark => 仅 APM;由主进程 IPC 提供 @@ -923,6 +929,8 @@ const handleWindowResize = () => { saveBoundsTimer = window.setTimeout(() => { void window.ipcRenderer.invoke("save-window-bounds"); }, 400); + + updateIsMaximizedState() }; // —— 以下为可复用的事件/IPC 监听处理器(命名函数,便于 onUnmounted 统一移除)—— diff --git a/src/components/WindowTitleBar.vue b/src/components/WindowTitleBar.vue index b1c90d88..0f4fb408 100644 --- a/src/components/WindowTitleBar.vue +++ b/src/components/WindowTitleBar.vue @@ -75,30 +75,28 @@
@@ -110,6 +108,7 @@ import ThemeToggle from "./ThemeToggle.vue"; defineProps<{ searchQuery: string; themeMode: "light" | "dark" | "auto"; + isMaximized: boolean }>(); const emit = defineEmits<{ diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index e4409466..09878e28 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -39,6 +39,7 @@ interface WindowControlBridge { minimize: () => void; toggleMaximize: () => void; close: () => void; + state: () => Promise<| 'normal' | 'maximized' | 'minimized'> } // IPC channel type definitions