fix(electron): align Windows title bar hover

Use native Window Controls Overlay geometry and sampled background colors so caption hover and drag regions track the system title bar.

Forward original Windows close-handler errors to the shared logger so failures retain their stack traces.
This commit is contained in:
digua authored and digua committed 2026-08-07 22:37:04 +08:00
1 parent 3db40375b6
commit d734389f29
6 files changed
+77 -20

No files matched your search

+2 -2
View File
@@ -25,9 +25,9 @@ export const logger = {
ensureInit()
appLogger.warn('app', message)
},
error: (message: string) => {
error: (message: string, data?: unknown) => {
ensureInit()
appLogger.error('app', message)
appLogger.error('app', message, data)
},
debug: (message: string) => {
ensureInit()
+1 -1
View File
@@ -93,7 +93,7 @@ function handleWindowsClose(win: BrowserWindow): void {
},
quit: requestAppQuit,
onError: (error) => {
logger.error(`Failed to handle Windows close request: ${error instanceof Error ? error.message : String(error)}`)
logger.error('Failed to handle Windows close request', error)
},
})
}
+10 -8
View File
@@ -1,28 +1,26 @@
import type { BrowserWindow, TitleBarOverlayOptions } from 'electron'
const TITLE_BAR_OVERLAY_HEIGHT = 32
const TITLE_BAR_OVERLAY_COLOR = 'rgba(0, 0, 0, 0)'
let currentTitleBarOverlayColor: string | null = null
const TITLE_BAR_OVERLAY_PALETTE = {
light: { symbolColor: '#52525b' },
dark: { symbolColor: '#d4d4d8' },
light: { backgroundColor: '#f9fafb', symbolColor: '#52525b' },
dark: { backgroundColor: '#111827', symbolColor: '#d4d4d8' },
} as const
export function getTitleBarOverlayOptions(isDark: boolean): TitleBarOverlayOptions {
const mode = isDark ? 'dark' : 'light'
return {
color: TITLE_BAR_OVERLAY_COLOR,
color: getTransparentOverlayColor(TITLE_BAR_OVERLAY_PALETTE[mode].backgroundColor),
symbolColor: TITLE_BAR_OVERLAY_PALETTE[mode].symbolColor,
height: TITLE_BAR_OVERLAY_HEIGHT,
}
}
export function getTitleBarOverlayOptionsForColor(color: string): TitleBarOverlayOptions {
return {
color: TITLE_BAR_OVERLAY_COLOR,
// Electron derives the minimize/maximize hover color from the overlay RGB.
// Preserve the sampled background channels while keeping the overlay transparent.
color: getTransparentOverlayColor(color),
symbolColor: getReadableSymbolColor(color),
height: TITLE_BAR_OVERLAY_HEIGHT,
}
}
@@ -44,6 +42,10 @@ export function resetCurrentTitleBarOverlayColor(): void {
currentTitleBarOverlayColor = null
}
function getTransparentOverlayColor(color: string): string {
return /^#[0-9a-f]{6}$/i.test(color) ? `${color}00` : 'rgba(0, 0, 0, 0)'
}
function getReadableSymbolColor(hexColor: string): string {
const match = /^#([0-9a-f]{6})$/i.exec(hexColor)
if (!match) return '#52525b'