fix(desktop): stop pinning macOS displays at max refresh rate (#1242)

The macOS compositor watchdog called webContents.setBackgroundThrottling(false)
unconditionally for the window's whole lifetime. That disables Chromium's idle
frame-rate throttling, so the GPU process's CADisplayLink never idles — pinning
ProMotion panels at their maximum refresh rate (120Hz) continuously, even while
the app is idle or occluded, which drains the battery.

The call was never needed: the probe already skips non-producing windows via its
screen-lock / isVisible / isMinimized / document.visibilityState guards, and the
freeze it targets happens while the window is visible and focused, where
background throttling never applies. Removing it lets the compositor idle and the
display drop to a low adaptive rate when nothing animates; freeze detection is
unaffected. A comment and a docs note keep it from being re-added.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
fireblue
2026-06-01 11:42:22 +08:00
committed by GitHub
co-authored by Claude Opus 4.8
parent eb7495d231
commit 3095bcb760
2 changed files with 15 additions and 2 deletions
@@ -67,8 +67,15 @@ export function setupDarwinCompositorWatchdog(win: BrowserWindow): void {
return;
}
// Keep producing frames while occluded so the probe is not fooled by throttling.
win.webContents.setBackgroundThrottling(false);
// Deliberately do NOT call win.webContents.setBackgroundThrottling(false) here.
// Disabling background throttling keeps Chromium's compositor producing frames
// continuously, which pins ProMotion displays at their max refresh rate (120Hz)
// forever and drains the battery even while the app sits idle. The probe does
// not need it: the visibility guards below (screen lock / isVisible /
// isMinimized / document.visibilityState) already skip windows that legitimately
// stop producing frames, so throttling cannot fool the probe into a false stall.
// The freeze this watchdog targets happens while the window is visible and
// focused (just after display wake), where background throttling never applies.
let stalledChecks = 0;
let recovering = false;