diff --git a/apps/desktop/main/index.ts b/apps/desktop/main/index.ts index e55b9d66..1e6701f6 100644 --- a/apps/desktop/main/index.ts +++ b/apps/desktop/main/index.ts @@ -22,7 +22,11 @@ import { import { migrateAllDatabases, checkMigrationNeeded } from './database/core' import { initLocale } from './i18n' import { MigrationRunner, ALL_MIGRATIONS } from '@openchatlab/config' -import { applyCurrentTitleBarOverlay, getTitleBarOverlayOptions } from './window-titlebar' +import { + applyCurrentTitleBarOverlay, + getTitleBarOverlayOptions, + resetCurrentTitleBarOverlayColor, +} from './window-titlebar' type AppWithQuitFlag = typeof app & { isQuiting?: boolean } // 统一通过扩展类型访问退出标记,避免使用 @ts-ignore。 @@ -243,6 +247,7 @@ class MainProcess { // 监听主题变化,动态更新颜色 nativeTheme.on('updated', () => { if (this.mainWindow && platform.isWindows) { + resetCurrentTitleBarOverlayColor() applyCurrentTitleBarOverlay(this.mainWindow, nativeTheme.shouldUseDarkColors) } }) diff --git a/apps/desktop/main/ipc/window.ts b/apps/desktop/main/ipc/window.ts index 9ed2e4c4..a32a2686 100644 --- a/apps/desktop/main/ipc/window.ts +++ b/apps/desktop/main/ipc/window.ts @@ -7,7 +7,11 @@ import * as fs from 'fs/promises' import type { IpcContext } from './types' import { simulateUpdateDialog, manualCheckForUpdates } from '../update' import { t } from '../i18n' -import { applyCurrentTitleBarOverlay, applyTitleBarOverlayColor } from '../window-titlebar' +import { + applyCurrentTitleBarOverlay, + applyTitleBarOverlayColor, + resetCurrentTitleBarOverlayColor, +} from '../window-titlebar' type AppWithQuitFlag = typeof app & { isQuiting?: boolean } // 通过类型扩展记录应用退出意图,避免使用 @ts-ignore。 @@ -88,6 +92,7 @@ export function registerWindowHandlers(ctx: IpcContext): void { // Windows 上动态更新 overlay 颜色以匹配主题 if (process.platform === 'win32' && win) { + resetCurrentTitleBarOverlayColor() applyCurrentTitleBarOverlay(win, nativeTheme.shouldUseDarkColors) } }) diff --git a/apps/desktop/main/window-titlebar.test.ts b/apps/desktop/main/window-titlebar.test.ts index 4f873fab..32f8989f 100644 --- a/apps/desktop/main/window-titlebar.test.ts +++ b/apps/desktop/main/window-titlebar.test.ts @@ -1,6 +1,13 @@ import assert from 'node:assert/strict' import { describe, it } from 'node:test' -import { getTitleBarOverlayOptionsForColor, getTitleBarOverlayOptions } from './window-titlebar' +import type { BrowserWindow, TitleBarOverlayOptions } from 'electron' +import { + applyCurrentTitleBarOverlay, + applyTitleBarOverlayColor, + getTitleBarOverlayOptionsForColor, + getTitleBarOverlayOptions, + resetCurrentTitleBarOverlayColor, +} from './window-titlebar' describe('Windows title bar overlay options', () => { it('keeps the native overlay background transparent in normal mode', () => { @@ -28,4 +35,23 @@ describe('Windows title bar overlay options', () => { height: 32, }) }) + + it('can drop a sampled color when the effective theme changes', () => { + const calls: TitleBarOverlayOptions[] = [] + const win = { + setTitleBarOverlay: (options: TitleBarOverlayOptions) => { + calls.push(options) + }, + } as Pick as BrowserWindow + + applyTitleBarOverlayColor(win, '#111827') + resetCurrentTitleBarOverlayColor() + applyCurrentTitleBarOverlay(win, false) + + assert.deepEqual(calls.at(-1), { + color: 'rgba(0, 0, 0, 0)', + symbolColor: '#52525b', + height: 32, + }) + }) }) diff --git a/apps/desktop/main/window-titlebar.ts b/apps/desktop/main/window-titlebar.ts index 1c499505..14ec9475 100644 --- a/apps/desktop/main/window-titlebar.ts +++ b/apps/desktop/main/window-titlebar.ts @@ -40,6 +40,10 @@ export function applyTitleBarOverlayColor(win: BrowserWindow | null | undefined, win?.setTitleBarOverlay(getTitleBarOverlayOptionsForColor(color)) } +export function resetCurrentTitleBarOverlayColor(): void { + currentTitleBarOverlayColor = null +} + function getReadableSymbolColor(hexColor: string): string { const match = /^#([0-9a-f]{6})$/i.exec(hexColor) if (!match) return '#52525b'