Skip to content

fix(desktop): finish the macOS Cmd+Q quit after shutdown - #59144

Merged
opencode-agent[bot] merged 2 commits into
devfrom
desktop-macos-quit-hang
Oct 26, 2026
Merged

opencode-agent[bot] merged 2 commits into
devfrom
desktop-macos-quit-hang

Conversation

@opencode-agent

@opencode-agent opencode-agent Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #56394
Supersedes #58949 (builds on @anmol0b's diagnosis and deferred re-quit there).

Type of change

  • Bug fix

What does this PR do?

On macOS, keyboard Cmd+Q closes the window but leaves the main process running. Reopening from the Dock then builds a window on a process whose shutdown has already run, and it stays on the loading splash.

Electron's Browser::Quit() runs is_quitting_ = HandleBeforeQuit(), so it records our preventDefault() only after before-quit returns. When no extension host has loaded, shutdown.run finishes in a microtask, and the re-issued app.quit() runs while the first emit is still on the stack. The nested quit starts closing windows, then the outer call writes is_quitting_ = false over it. When the last window closes, Electron emits window-all-closed instead of will-quit, which is a no-op on macOS.

Changes in lifecycle/index.ts:

  • Defer the re-quit with setImmediate so the cancelled quit has finished unwinding before the new one starts. app.exit isn't used because it skips will-quit/quit, which electron-updater's install-on-quit depends on.
  • Backstop in window-all-closed: once before-quit has fired, quit on macOS too. A quit that Electron drops for any reason still finishes instead of leaving a windowless process. The flag is set in before-quit, so autoUpdater.quitAndInstall (which closes windows before emitting before-quit) is unaffected.
  • Don't restore windows in activate after a quit was requested, so the Dock never opens a window on torn-down services.
  • Cap prepareToRestart at 10s, so a hung shutdown step can't leave every quit waiting forever.

Also renames makeMainWindows, makeWindowRecovery and makeUnresponsiveSampler to mainWindows, windowRecovery and unresponsiveSampler. lint:changed checks whole touched files, and no-service-constructor-imports flags any relative make[A-Z] import, so each of these fails the check once its importing file is edited.

How did you verify your code works?

  • bun typecheck and bun run typecheck:tsc in packages/desktop.
  • bun run lint:changed: clean.
  • Not run on macOS from this branch. The deferred re-quit is the change that fix(desktop): finish the macOS Cmd+Q quit after shutdown #58949 verified with keyboard Cmd+Q (3/3 exits); the backstop and activate guard only take effect when a quit is dropped.

Requested by: @Brendonovich (Brendan via Slack)

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks sound. I couldn't run it: the bug needs keyboard Cmd+Q and the Dock in the macOS desktop app, and this sandbox is Linux with no display. I read the change against Electron's quit flow and effect's Effect.cached. tsc -b and the lifecycle tests pass.

The deferred re-quit still goes through will-quit/quit, so install-on-quit for updates keeps working. The window-all-closed backstop only matters when a quit was dropped, because Electron doesn't send that event while it's quitting. The 10s timeout does stop a hung dispose(): the cached run is stopped and the stop isn't stored. As a result, will-quit starts shutdown.run again from scratch, which is harmless as the app exits.

Public API: unchanged.

A quick Cmd+Q, then Dock click, on a Mac build before merging would confirm the fix end to end.

Related: #54296

@opencode-agent
opencode-agent Bot merged commit ec09e45 into dev Oct 26, 2026
14 checks passed
@opencode-agent
opencode-agent Bot deleted the desktop-macos-quit-hang branch October 26, 2026 03:37
@amrkmn amrkmn mentioned this pull request Oct 27, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: macOS desktop: Cmd+Q leaves a half-dead instance, and the next Dock click stalls the renderer

1 participant