From 09d9f6bdd19d6da9409c6b736b8cdcdb9ab40a75 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Sat, 6 Jun 2026 22:42:54 +0530 Subject: [PATCH] fix(window): renderer path off-by-one; use 'close' for state save MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related bugs in src/main/window/index.js: 1. Renderer path was ../../dist/renderer/index.html which resolves to src/dist/renderer/index.html (one level too deep). Production builds load from /dist/renderer/index.html. Fix: ../../.. This was never caught because dev mode uses VITE_DEV_SERVER_URL and never touches the file path; only 'electron .' (no Vite) hits it. 2. win.on('closed', state.save) calls win.getBounds() on a destroyed BrowserWindow. The 'closed' event fires AFTER destruction, so getBounds() throws 'Object has been destroyed'. Use 'close' (fires before destruction) and guard with isDestroyed() as a belt-and-suspenders. Both bugs surfaced when the user clicked File → Open. The renderer loaded a missing HTML (blank body); the openFile handler then triggered the closed-event state save which threw. --- src/main/window/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/window/index.js b/src/main/window/index.js index 2dec5dd..a4e55d8 100644 --- a/src/main/window/index.js +++ b/src/main/window/index.js @@ -38,7 +38,7 @@ function createMainWindow() { } else { const rendererIndex = app.isPackaged ? path.join(process.resourcesPath, 'renderer', 'index.html') - : path.join(__dirname, '../../dist/renderer/index.html'); + : path.join(__dirname, '../../../dist/renderer/index.html'); if (app.isPackaged) { try { @@ -63,8 +63,10 @@ function createMainWindow() { menu.register(win); - win.on('closed', () => { - state.save(win); + // Use 'close' (fires before destruction) — 'closed' fires after the + // BrowserWindow object is destroyed, so getBounds() would throw. + win.on('close', () => { + if (!win.isDestroyed()) state.save(win); }); // Spell check context menu