feat: improve shutdown cleanup

This commit is contained in:
Johannes Millan 2025-06-29 17:31:28 +02:00
parent 92b4d5409b
commit fcf5e5fe30
6 changed files with 69 additions and 14 deletions

View file

@ -66,6 +66,14 @@ export const initFullScreenBlocker = (IS_DEV: boolean): void => {
evI.preventDefault();
}
});
win.on('closed', () => {
// Clean up references
isFullScreenWindowOpen = false;
if (closeTimeout) {
clearTimeout(closeTimeout);
}
});
},
);
};

View file

@ -319,6 +319,12 @@ const appCloseHandler = (app: App): void => {
}
});
mainWin.on('closed', () => {
// Dereference the window object
mainWin = null;
mainWinModule.win = null;
});
mainWin.webContents.on('render-process-gone', (event, detailed) => {
log('!crashed, reason: ' + detailed.reason + ', exitCode = ' + detailed.exitCode);
if (detailed.reason == 'crashed') {

View file

@ -66,21 +66,31 @@ export const destroyOverlayWindow = (): void => {
// Remove IPC listeners
ipcMain.removeAllListeners('overlay-show-main-window');
ipcMain.removeAllListeners('overlay-set-ignore-mouse');
if (overlayWindow) {
// Remove ALL event listeners
overlayWindow.removeAllListeners('close');
overlayWindow.removeAllListeners('closed');
overlayWindow.removeAllListeners('ready-to-show');
overlayWindow.removeAllListeners('system-context-menu');
if (overlayWindow && !overlayWindow.isDestroyed()) {
try {
// Remove ALL event listeners
overlayWindow.removeAllListeners();
// Remove webContents listeners
if (overlayWindow.webContents) {
overlayWindow.webContents.removeAllListeners('context-menu');
// Remove webContents listeners
if (overlayWindow.webContents && !overlayWindow.webContents.isDestroyed()) {
overlayWindow.webContents.removeAllListeners();
}
// Hide first to prevent visual issues
overlayWindow.hide();
// Set closable to ensure we can close it
overlayWindow.setClosable(true);
// Force destroy the window
overlayWindow.destroy();
} catch (e) {
// Window might already be destroyed
console.error('Error destroying overlay window:', e);
}
// Force destroy the window
overlayWindow.destroy();
overlayWindow = null;
}
};
@ -106,6 +116,7 @@ const createOverlayWindow = (): void => {
// resizable: false,
minimizable: false,
maximizable: false,
closable: true, // Ensure window is closable
hasShadow: false, // Disable shadow with transparent windows
autoHideMenuBar: true,
roundedCorners: false, // Disable rounded corners for better compatibility
@ -116,6 +127,7 @@ const createOverlayWindow = (): void => {
disableDialogs: true,
webSecurity: true,
allowRunningInsecureContent: false,
backgroundThrottling: false, // Prevent throttling when hidden
},
});

View file

@ -8,6 +8,13 @@ contextBridge.exposeInMainWorld('overlayAPI', {
ipcRenderer.send('overlay-show-main-window');
},
onUpdateContent: (callback: (data: any) => void) => {
ipcRenderer.on('update-content', (event, data) => callback(data));
const listener = (event: Electron.IpcRendererEvent, data: any): void =>
callback(data);
ipcRenderer.on('update-content', listener);
// Return cleanup function
return () => {
ipcRenderer.removeListener('update-content', listener);
};
},
});

View file

@ -192,6 +192,12 @@ class PluginNodeExecutor {
const timer = setTimeout(() => {
killed = true;
child.kill('SIGTERM');
// Force kill after a short delay if process doesn't terminate
setTimeout(() => {
if (!child.killed) {
child.kill('SIGKILL');
}
}, 1000);
reject(new Error(`Script execution timed out after ${timeoutMs}ms`));
}, timeoutMs);

View file

@ -5,6 +5,7 @@ import {
app,
BrowserWindow,
globalShortcut,
ipcMain,
powerMonitor,
protocol,
} from 'electron';
@ -254,15 +255,30 @@ export const startApp = (): void => {
});
appIN.on('before-quit', () => {
log('App before-quit: cleaning up resources');
// Clean up overlay window before quitting
destroyOverlayWindow();
// Remove all IPC listeners to prevent memory leaks
ipcMain.removeAllListeners();
// Clear any pending timeouts/intervals
if (global.gc) {
global.gc();
}
});
appIN.on('window-all-closed', () => {
log('Quit after all windows being closed');
// if (!IS_MAC) {
// Force quit the app
app.quit();
// }
// If app doesn't quit within 2 seconds, force exit
setTimeout(() => {
log('Force exiting app as it did not quit properly');
app.exit(0);
}, 2000);
});
process.on('uncaughtException', (err) => {
console.log(err);