Fix Cmd+Q on macOS leaving the desktop app alive

The before-quit handler preventDefaulted on every quit and re-fired
app.quit() from .finally. That re-entered Electron through the
window-all-closed gate, which on macOS is a no-op listener that
vetoes the quit — so the window closed but the process stayed up.

Use app.exit(0) to bypass the close → window-all-closed → will-quit
chain entirely. Also drop the daemon-stop NSAlert: with no parent
window it ran app-modal and stalled the child-process pipes for
'paseo daemon stop', so daemon shutdown waited on the user dismissing
the dialog. Replace it with an in-app overlay rendered in the renderer
via a paseo:event:quitting IPC event. Stop opening DevTools on dev boot.
This commit is contained in:
Mohamed Boudra
2026-04-27 15:22:16 +07:00
parent 2ba523ce05
commit 88f382cad3
5 changed files with 88 additions and 29 deletions
@@ -75,9 +75,9 @@ describe("quit-lifecycle", () => {
);
});
it("gates quit until the stop decision completes, then lets the next quit pass through", async () => {
it("preventDefaults the first quit, runs the async stop decision, then exits hard", async () => {
let resolveStopDecision: (() => void) | null = null;
const app = { quit: vi.fn() };
const app = { exit: vi.fn() };
const closeTransportSessions = vi.fn();
const onStopError = vi.fn();
const preventDefault = vi.fn();
@@ -99,20 +99,20 @@ describe("quit-lifecycle", () => {
expect(preventDefault).toHaveBeenCalledTimes(1);
expect(closeTransportSessions).toHaveBeenCalledTimes(1);
expect(app.quit).not.toHaveBeenCalled();
expect(app.exit).not.toHaveBeenCalled();
expect(resolveStopDecision).not.toBeNull();
resolveStopDecision?.();
await Promise.resolve();
await Promise.resolve();
expect(app.quit).toHaveBeenCalledTimes(1);
expect(app.exit).toHaveBeenCalledWith(0);
expect(onStopError).not.toHaveBeenCalled();
handleBeforeQuit({ preventDefault: secondPreventDefault });
expect(secondPreventDefault).not.toHaveBeenCalled();
expect(closeTransportSessions).toHaveBeenCalledTimes(2);
expect(app.quit).toHaveBeenCalledTimes(1);
expect(app.exit).toHaveBeenCalledTimes(1);
});
});