fix(window): stop burning macOS GPU on an invisible blur effect (#8482)

macOS Window Blur set `vibrancy: 'under-window'` and `transparent: true`,
taking the window off the opaque fast path so WindowServer alpha-composited
every frame. The effect was never visible: an opaque backgroundColor is always
set and the renderer paints an opaque root, so it sat fully occluded.

Reporter's A/B measured 5,365 mW with blur on vs 804 mW off at the same
workload. Windows acrylic and Linux are untouched.

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Neil
2026-07-25 22:04:01 -07:00
co-authored by Orca
parent c06bf64b48
commit 24614e4e8b
2 changed files with 57 additions and 8 deletions
+53
View File
@@ -311,6 +311,59 @@ describe('createMainWindow', () => {
}
})
it('never requests macOS vibrancy or transparency when window blur is enabled (#8482)', () => {
for (const [platform, expected] of [
['darwin', { backgroundMaterial: undefined }],
['win32', { backgroundMaterial: 'acrylic' }],
['linux', { backgroundMaterial: undefined }]
] satisfies [NodeJS.Platform, { backgroundMaterial: string | undefined }][]) {
browserWindowMock.mockReset()
const webContents = {
on: vi.fn(),
setZoomLevel: vi.fn(),
setBackgroundThrottling: vi.fn(),
invalidate: vi.fn(),
setWindowOpenHandler: vi.fn(),
send: vi.fn(),
isDevToolsOpened: vi.fn(),
openDevTools: vi.fn(),
closeDevTools: vi.fn()
}
const browserWindowInstance = {
webContents,
on: vi.fn(),
isDestroyed: vi.fn(() => false),
isMaximized: vi.fn(() => false),
isFullScreen: vi.fn(() => false),
getSize: vi.fn(() => [1200, 800]),
getBounds: vi.fn(() => ({ x: 10, y: 20, width: 1000, height: 700 })),
setSize: vi.fn(),
setWindowButtonPosition: vi.fn(),
maximize: vi.fn(),
show: vi.fn(),
loadFile: vi.fn(),
loadURL: vi.fn()
}
browserWindowMock.mockImplementation(function () {
return browserWindowInstance
})
withPlatform(platform, () =>
createMainWindow({
getUI: () => ({}),
getSettings: () => ({ windowBackgroundBlur: true }),
updateUI: vi.fn()
} as never)
)
const browserWindowOptions = browserWindowMock.mock.calls[0]?.[0]
expect(browserWindowOptions.vibrancy).toBeUndefined()
expect(browserWindowOptions.transparent).toBeUndefined()
expect(browserWindowOptions.backgroundMaterial).toBe(expected.backgroundMaterial)
expect(browserWindowOptions.backgroundColor).toBe('#ffffff')
}
})
it('keeps main-window background throttling enabled while repainting macOS visibility transitions', () => {
vi.useFakeTimers()
const windowHandlers = new Map<string, ((...args: any[]) => void)[]>()
+4 -8
View File
@@ -253,14 +253,10 @@ export function createMainWindow(
return false
})
const blur = settings?.windowBackgroundBlur ?? false
// Why: blur uses platform APIs (macOS vibrancy+transparent, Windows backgroundMaterial, Linux none) and only applies at creation, needs restart.
const platformBlurOptions = blur
? process.platform === 'darwin'
? { vibrancy: 'under-window' as const, transparent: true }
: process.platform === 'win32'
? { backgroundMaterial: 'acrylic' as const }
: {}
: {}
// Why: only Windows acrylic is ever visible; macOS vibrancy+transparent sat behind our opaque background yet
// forced per-frame WindowServer alpha compositing (#8482). Applies at creation only, so it needs a restart.
const platformBlurOptions =
blur && process.platform === 'win32' ? { backgroundMaterial: 'acrylic' as const } : {}
const mainWindow = new BrowserWindow({
width: savedBounds?.width ?? defaultBounds.width,