mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-27 11:22:03 +00:00
fix(desktop): transparent WCO titlebar chrome on Windows/WSLg
Use a transparent native overlay so renderer chrome shows through the min/max/close band. Sync window pre-paint bg to the computed chrome mix.
This commit is contained in:
parent
3b1344c18c
commit
76074b2145
3 changed files with 30 additions and 19 deletions
|
|
@ -527,34 +527,30 @@ function getWindowBackgroundColor() {
|
|||
return nativeTheme.shouldUseDarkColors ? '#111111' : '#f7f7f7'
|
||||
}
|
||||
|
||||
// Transparent WCO — renderer chrome shows through. rgba(0,0,0,0) can fall back
|
||||
// to GetFrameColor() on some Electron builds; rgba(1,0,0,0) is the escape hatch.
|
||||
const TITLEBAR_OVERLAY_COLOR = 'rgba(1, 0, 0, 0)'
|
||||
|
||||
function getTitleBarOverlayOptions() {
|
||||
if (IS_MAC) {
|
||||
return { height: TITLEBAR_HEIGHT }
|
||||
}
|
||||
|
||||
// Window Controls Overlay: Windows paints it natively, and WSLg honors it too
|
||||
// (it renders through a real compositor), so keep it enabled there — disabling
|
||||
// it removes the min/max/close buttons entirely. Only plain (non-WSL) Linux,
|
||||
// where some WMs/builds don't support WCO, falls through to no overlay; the
|
||||
// frameless titleBarStyle 'hidden' still applies.
|
||||
// Windows + WSLg paint WCO natively; plain Linux disables it (frameless hidden
|
||||
// titlebar still applies).
|
||||
if (!IS_WINDOWS && !IS_WSL) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (rendererTitleBarTheme) {
|
||||
return {
|
||||
color: rendererTitleBarTheme.background,
|
||||
height: TITLEBAR_HEIGHT,
|
||||
symbolColor: rendererTitleBarTheme.foreground
|
||||
}
|
||||
}
|
||||
|
||||
const useDarkColors = nativeTheme.shouldUseDarkColors
|
||||
|
||||
return {
|
||||
color: useDarkColors ? '#111111' : '#f7f7f7',
|
||||
color: TITLEBAR_OVERLAY_COLOR,
|
||||
height: TITLEBAR_HEIGHT,
|
||||
symbolColor: useDarkColors ? '#f7f7f7' : '#242424'
|
||||
symbolColor:
|
||||
rendererTitleBarTheme && isHexColor(rendererTitleBarTheme.foreground)
|
||||
? rendererTitleBarTheme.foreground
|
||||
: nativeTheme.shouldUseDarkColors
|
||||
? '#f7f7f7'
|
||||
: '#242424'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,13 @@ export function AppShell({
|
|||
<TitlebarControls leftTools={leftTitlebarTools} onOpenSettings={onOpenSettings} tools={titlebarTools} />
|
||||
)}
|
||||
|
||||
{nativeOverlayWidth > 0 && (
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none fixed inset-x-0 top-0 z-[4] h-(--titlebar-height) border-b border-(--ui-stroke-tertiary) bg-(--ui-chat-surface-background)"
|
||||
/>
|
||||
)}
|
||||
|
||||
<main className="relative z-3 flex min-h-0 w-full flex-1 flex-col overflow-hidden transition-none">
|
||||
<PaneShell className="min-h-0 flex-1">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -157,6 +157,12 @@ function renderedModeFor(colors: DesktopThemeColors, mode: 'light' | 'dark'): 'l
|
|||
// Per-mode mix knobs. Light/dark fallbacks live in styles.css `:root` /
|
||||
// `:root.dark`; setting them inline keeps active-skin overrides surviving
|
||||
// the boot-time paint.
|
||||
// styles.css --theme-neutral-chrome — keep in sync.
|
||||
const NEUTRAL_CHROME = { light: '#f3f3f3', dark: '#0d0d0e' } as const
|
||||
|
||||
const chromeBackground = (background: string, isDark: boolean) =>
|
||||
mix(background, NEUTRAL_CHROME[isDark ? 'dark' : 'light'], isDark ? 0.26 : 0.08)
|
||||
|
||||
const mixesFor = (isDark: boolean): Record<string, string> => ({
|
||||
'--theme-mix-chrome': isDark ? '74%' : '92%',
|
||||
'--theme-mix-sidebar': '100%',
|
||||
|
|
@ -222,8 +228,10 @@ function applyTheme(theme: DesktopTheme, mode: 'light' | 'dark') {
|
|||
root.style.setProperty(k, v)
|
||||
}
|
||||
|
||||
const chromeBg = chromeBackground(c.background, isDark)
|
||||
|
||||
window.hermesDesktop?.setTitleBarTheme?.({
|
||||
background: c.background,
|
||||
background: chromeBg,
|
||||
foreground: c.foreground
|
||||
})
|
||||
|
||||
|
|
@ -231,7 +239,7 @@ function applyTheme(theme: DesktopTheme, mode: 'light' | 'dark') {
|
|||
// they let a brand-new window paint the themed background on its very first
|
||||
// frame, before this module has even loaded.
|
||||
try {
|
||||
window.localStorage.setItem('hermes-boot-background', c.background)
|
||||
window.localStorage.setItem('hermes-boot-background', chromeBg)
|
||||
window.localStorage.setItem('hermes-boot-color-scheme', rendered)
|
||||
} catch {
|
||||
// Storage may be unavailable (private mode / quota); the inline script
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue