Repository navigation
Conversation
There was a problem hiding this comment.
The change looks sound to me. I couldn't verify it: this sandbox is Linux without a display, and the bug only shows up with keyboard Cmd+Q in the macOS desktop app.
From reading the code: prepareToRestart sets shutdownReady before the deferred app.quit() is scheduled, so the second before-quit returns early and continues to will-quit without looping. Shutdown.run is cached, so running it again in will-quit costs nothing. The relaunch and signal paths don't cancel a quit first, so leaving them as they are makes sense. tsc reports no errors in src/main/lifecycle.
Public API: unchanged.
This doesn't add a timeout if a shutdown step never finishes, which was the other possible cause raised in #56394. A separate change could guard against that if it still happens after this one.
Related: #54296
Issue for this PR
Closes #56394
Type of change
What does this PR do?
On macOS, pressing Cmd+Q closes the window but leaves the main process running. The app never reaches
will-quit; Electron fireswindow-all-closedinstead, and on macOS that handler does nothing. Reopening from the Dock then builds a window on a process that is half-quit, which is where the renderer stall comes from.beforeQuitinlifecycle/index.tscancels the first quit, runsprepareToRestart, then callsapp.quit()again. With keyboard Cmd+Q, that second call runs from a microtask before Electron has finished handling the cancelled quit. Electron then clears its "quitting" flag, so nothing is left to finish the quit once the window closes. kcharlan's lldb trace in the issue shows exactly this. A quit started from JS, or by the quit Apple event, doesn't hit it.The fix defers the second call to the next timer tick with
setTimeout(() => app.quit(), 0). I didn't useapp.exit(0)because it skipswill-quit, so the storage close, the IPC cleanup and electron-updater'squithook would no longer run. The relaunch and signal paths don't cancel a quit first, so they are unchanged.Out of scope: skipping window restore in
activatewhile a quit is in progress (suggested in the issue thread).How did you verify your code works?
window-all-closed, nowill-quit). With thesetTimeoutre-issue, all 3 runs reachedwill-quitand exited.bun run dev) ondev, macOS 27, Apple Silicon: after keyboard Cmd+Q the process was still running with 0 windows 10s later. With this change it exited in 3 of 3 fresh launches.bun typecheckinpackages/desktopandbun run checkpass.bun testcan't drive. Cmd+Q was sent through System Events, not pressed by hand.Screenshots / recordings
Before: after Cmd+Q the process stays alive with no window. Reopening activates that same process, and the window stays on the loading splash.
After: Cmd+Q ends the process, and the next launch loads normally.
Checklist
Added by the opencode bot (AI-generated).
Related: #54296