fix: prevent macOS desktop unlock freeze after display sleep (#745)
* Restart the GPU process to recover from macOS compositor freezes macOS display sleep can leave Chromium's GPU-process display link stuck on a stale display, so the compositor stops producing frames and the window looks frozen — unresponsive to clicks and keys — even though the renderer stays alive. setupDarwinCompositorWatchdog polls the renderer for frame production and, on a sustained stall while the window is visible and unlocked, restarts the GPU process so Chromium rebuilds the display link. This replaces setupDarwinPaintRefresh, whose invalidate/resize nudges did not address the dead display link. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Give compositor watchdog a module home --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
Mohamed Boudra
parent
5a1c7f266c
commit
aaabadb04b
@@ -229,59 +229,6 @@ export function setupWindowResizeEvents(win: BrowserWindow): void {
|
||||
});
|
||||
}
|
||||
|
||||
function refreshChromiumSurface(win: BrowserWindow): void {
|
||||
if (win.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
win.webContents.invalidate();
|
||||
if (win.isMaximized() || win.isFullScreen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [width, height] = win.getSize();
|
||||
win.setSize(width + 1, height);
|
||||
setTimeout(() => {
|
||||
if (!win.isDestroyed()) {
|
||||
win.setSize(width, height);
|
||||
}
|
||||
}, 32);
|
||||
}
|
||||
|
||||
export function setupDarwinPaintRefresh(win: BrowserWindow): void {
|
||||
if (process.platform !== "darwin") {
|
||||
return;
|
||||
}
|
||||
|
||||
win.webContents.setBackgroundThrottling(false);
|
||||
|
||||
const requestSurfaceRefresh = () => {
|
||||
if (!win.isDestroyed()) {
|
||||
win.webContents.invalidate();
|
||||
}
|
||||
};
|
||||
const handleChildProcessGone = (
|
||||
_event: Electron.Event,
|
||||
details: { type?: string; reason?: string },
|
||||
) => {
|
||||
if (details.type !== "GPU") {
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn("[window] GPU process gone:", details.reason);
|
||||
refreshChromiumSurface(win);
|
||||
};
|
||||
|
||||
win.on("restore", requestSurfaceRefresh);
|
||||
win.on("show", requestSurfaceRefresh);
|
||||
app.on("child-process-gone", handleChildProcessGone);
|
||||
win.once("closed", () => {
|
||||
win.off("restore", requestSurfaceRefresh);
|
||||
win.off("show", requestSurfaceRefresh);
|
||||
app.off("child-process-gone", handleChildProcessGone);
|
||||
});
|
||||
}
|
||||
|
||||
export function buildStandardContextMenuItems(
|
||||
contents: WebContents,
|
||||
params: Electron.ContextMenuParams,
|
||||
|
||||
Reference in New Issue
Block a user