Skip to content

Commit b4a2b18

Browse files
Batuhan1999claude
andcommitted
fix(desktop): a menu action during a restart reopens the closed window
A revealing menu action with no window, sent while the backend restarts, returned early without recording the request. mainClosed stayed true, so readiness skipped creating the window and nothing opened. Treat that request like a Dock click: clear mainClosed so the window opens once the backend is back. Non-revealing actions still leave a closed window closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7e9df2b commit b4a2b18

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

‎apps/desktop/src/window/DesktopWindow.test.ts‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,31 @@ describe("DesktopWindow", () => {
615615
}),
616616
);
617617

618+
it.effect.each([
619+
["a revealing menu action", { reveal: true }, 2],
620+
["a non-revealing menu action", { reveal: false }, 1],
621+
] as const)(
622+
"after %s during a restart, a closed main window follows the backend",
623+
([, options, expectedCreates]) =>
624+
Effect.gen(function* () {
625+
const fake = makeFakeBrowserWindow();
626+
const createCount = yield* Ref.make(0);
627+
const mainWindow = yield* Ref.make<Option.Option<Electron.BrowserWindow>>(Option.none());
628+
yield* Effect.gen(function* () {
629+
const windows = yield* DesktopWindow.DesktopWindow;
630+
yield* windows.handleBackendReady(new URL("http://127.0.0.1:3773"));
631+
fake.isDestroyed.mockReturnValue(true);
632+
fake.windowListeners.get("closed")?.();
633+
yield* windows.handleBackendNotReady;
634+
yield* windows.dispatchMenuAction("open-settings", options);
635+
assert.equal(yield* Ref.get(createCount), 1);
636+
fake.isDestroyed.mockReturnValue(false);
637+
yield* windows.handleBackendReady(new URL("http://127.0.0.1:3773"));
638+
assert.equal(yield* Ref.get(createCount), expectedCreates);
639+
}).pipe(Effect.provide(layerTest({ window: fake.window, createCount, mainWindow })));
640+
}),
641+
);
642+
618643
it.effect("reopens a closed main window when a restart recovers from a startup failure", () =>
619644
Effect.gen(function* () {
620645
const fake = makeFakeBrowserWindow();

‎apps/desktop/src/window/DesktopWindow.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,11 @@ export const make = Effect.gen(function* () {
11081108
) {
11091109
if (yield* Ref.get(desktopState.quitting)) return;
11101110
const existingWindow = yield* reveal ? focusedMainWindow : electronWindow.main;
1111-
if (Option.isNone(existingWindow) && (!reveal || (yield* waitingForBackend))) return;
1111+
if (Option.isNone(existingWindow) && (!reveal || (yield* waitingForBackend))) {
1112+
// A revealing request asks for the window, so a closed one opens once the backend is back.
1113+
if (reveal) mainClosed = false;
1114+
return;
1115+
}
11121116
const window = Option.isSome(existingWindow) ? existingWindow : yield* ensureMain;
11131117
if (Option.isNone(window) || window.value.isDestroyed()) return;
11141118
const targetWindow = window.value;

0 commit comments

Comments
 (0)