From f793587ebc401c36a66dac1df96a6f8eeb62bfb7 Mon Sep 17 00:00:00 2001 From: Arya Sadeghi Date: Sun, 10 May 2026 11:58:41 +0200 Subject: [PATCH] fix(app): keep Snapora alive when all BrowserWindows close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Electron's default `window-all-closed` behavior quits the app — even on macOS — when the last BrowserWindow goes away. `LSUIElement: true` only applies to packaged builds, so in `npm run dev` (and likely in any code path that spawns Electron without the packaged Info.plist) the app would silently quit between captures. Reproduction (before this fix): 1. Fresh `npm run dev`. 2. First action: take an area capture (Cmd+Shift+2). 3. Selection overlay creates BrowserWindows; user commits the rect; overlays `close()`. 4. `window-all-closed` fires → default → `app.quit()` → exit code 0. 5. The pending screencapture promise dies with the process; main.log ends at "spawning screencapture" with no follow-up. The window-mode flow happened to work because screencapture's UI is a separate process — Snapora itself never opened or closed a window, so the event never fired. Doing window-then-area also worked because the HUD window stays in the BrowserWindow registry (it `hide()`s, not `close()`s) and keeps the count positive. Fix: subscribe to `window-all-closed` and refuse to quit on macOS. Snapora is a menu-bar app — the tray keeps it running. The packaged build's `LSUIElement` was already doing this for production users; this hooks it for the dev build (and as a belt-and-suspenders production guard). Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main/index.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index a1717c5..857fe0b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -22,8 +22,23 @@ if (process.platform === 'darwin') { app.dock?.hide(); } -// Menu-bar app stays running even when no windows are open. On macOS, that's -// the default behavior already — we only need to handle this for Windows/Linux later. +/* + * Keep Snapora alive when all BrowserWindows are gone. + * + * Electron's default behavior — even on macOS — is to quit when the last + * window closes. The `LSUIElement: true` Info.plist key only applies to + * packaged builds, not `npm run dev`. Without this handler, the app silently + * quits whenever the selection overlay closes before the HUD opens (the + * "first capture is area" crash). Snapora is a menu-bar app — the tray + * keeps it running; BrowserWindow count is allowed to drop to zero. + */ +app.on('window-all-closed', () => { + // No-op on macOS — keep running. Future Windows/Linux ports will likely + // want `app.quit()` here. + if (process.platform !== 'darwin') { + app.quit(); + } +}); app.on('will-quit', (event) => { unregisterGlobalShortcuts();