!416 (titleBar): 使用 Font Awesome 图标集替代字符形式窗口控制标识, 且状态由根组件维护

Merge pull request !416 from zinface/styles/window-title-bar
This commit is contained in:
2026-08-18 05:50:21 +00:00
committed by Gitee
5 changed files with 24 additions and 6 deletions
+8
View File
@@ -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 // New window example arg: new windows url
// ipcMain.handle('open-win', (_, arg) => { // ipcMain.handle('open-win', (_, arg) => {
// const childWindow = new BrowserWindow({ // const childWindow = new BrowserWindow({
+2
View File
@@ -51,6 +51,7 @@ type WindowControlBridge = {
minimize: () => void; minimize: () => void;
toggleMaximize: () => void; toggleMaximize: () => void;
close: () => void; close: () => void;
state: () => Promise<| 'normal' | 'maximized' | 'minimized'>;
}; };
type UpdateCenterStateListener = (snapshot: UpdateCenterSnapshot) => void; type UpdateCenterStateListener = (snapshot: UpdateCenterSnapshot) => void;
@@ -110,6 +111,7 @@ contextBridge.exposeInMainWorld("windowControls", {
minimize: () => ipcRenderer.send("window-control-minimize"), minimize: () => ipcRenderer.send("window-control-minimize"),
toggleMaximize: () => ipcRenderer.send("window-control-toggle-maximize"), toggleMaximize: () => ipcRenderer.send("window-control-toggle-maximize"),
close: () => ipcRenderer.send("window-control-close"), close: () => ipcRenderer.send("window-control-close"),
state: () => ipcRenderer.invoke("window:state"),
} satisfies WindowControlBridge); } satisfies WindowControlBridge);
contextBridge.exposeInMainWorld("updateCenter", { contextBridge.exposeInMainWorld("updateCenter", {
+8
View File
@@ -14,6 +14,7 @@
@toggle-theme="toggleTheme" @toggle-theme="toggleTheme"
@toggle-sidebar="isSidebarOpen = !isSidebarOpen" @toggle-sidebar="isSidebarOpen = !isSidebarOpen"
@spk-link="handleSpkLink" @spk-link="handleSpkLink"
:is-maximized="isMaximized"
/> />
<div class="flex min-h-0 flex-1 flex-col lg:flex-row"> <div class="flex min-h-0 flex-1 flex-col lg:flex-row">
@@ -546,6 +547,11 @@ const isDarkTheme = computed(() => {
return themeMode.value === "dark"; 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); const isSubmitterView = ref(false);
// 启动参数 --no-apm => 仅 Spark--no-spark => 仅 APM;由主进程 IPC 提供 // 启动参数 --no-apm => 仅 Spark--no-spark => 仅 APM;由主进程 IPC 提供
@@ -923,6 +929,8 @@ const handleWindowResize = () => {
saveBoundsTimer = window.setTimeout(() => { saveBoundsTimer = window.setTimeout(() => {
void window.ipcRenderer.invoke("save-window-bounds"); void window.ipcRenderer.invoke("save-window-bounds");
}, 400); }, 400);
updateIsMaximizedState()
}; };
// —— 以下为可复用的事件/IPC 监听处理器(命名函数,便于 onUnmounted 统一移除)—— // —— 以下为可复用的事件/IPC 监听处理器(命名函数,便于 onUnmounted 统一移除)——
+5 -6
View File
@@ -75,30 +75,28 @@
<div class="mx-1 h-6 w-px bg-slate-300/70 dark:bg-slate-700/70"></div> <div class="mx-1 h-6 w-px bg-slate-300/70 dark:bg-slate-700/70"></div>
<button <button
type="button" type="button"
class="rounded-md px-3 py-1.5 text-base transition hover:bg-slate-200/80 dark:hover:bg-slate-800" class="fas fa-window-minimize rounded-md px-3 py-1.5 text-base transition hover:bg-slate-200/80 dark:hover:bg-slate-800"
aria-label="最小化" aria-label="最小化"
title="最小化" title="最小化"
@click="minimize" @click="minimize"
> >
</button> </button>
<button <button
type="button" type="button"
class="rounded-md px-3 py-1.5 text-base transition hover:bg-slate-200/80 dark:hover:bg-slate-800" class="fas rounded-md px-3 py-1.5 text-base transition hover:bg-slate-200/80 dark:hover:bg-slate-800"
:class="isMaximized ? 'fa-window-restore' : 'fa-window-maximize'"
aria-label="最大化或还原" aria-label="最大化或还原"
title="最大化或还原" title="最大化或还原"
@click="toggleMaximize" @click="toggleMaximize"
> >
</button> </button>
<button <button
type="button" type="button"
class="rounded-md px-3 py-1 text-sm transition hover:bg-red-500 hover:text-white" class="fas fa-times rounded-md px-3 py-1.5 text-base transition hover:bg-red-500 hover:text-white"
aria-label="关闭" aria-label="关闭"
title="关闭" title="关闭"
@click="close" @click="close"
> >
×
</button> </button>
</div> </div>
</header> </header>
@@ -110,6 +108,7 @@ import ThemeToggle from "./ThemeToggle.vue";
defineProps<{ defineProps<{
searchQuery: string; searchQuery: string;
themeMode: "light" | "dark" | "auto"; themeMode: "light" | "dark" | "auto";
isMaximized: boolean
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
+1
View File
@@ -39,6 +39,7 @@ interface WindowControlBridge {
minimize: () => void; minimize: () => void;
toggleMaximize: () => void; toggleMaximize: () => void;
close: () => void; close: () => void;
state: () => Promise<| 'normal' | 'maximized' | 'minimized'>
} }
// IPC channel type definitions // IPC channel type definitions