From 6da2caabf795f88baa5cd53f00723052d5dc929c Mon Sep 17 00:00:00 2001 From: sudacode Date: Fri, 27 Feb 2026 21:31:04 -0800 Subject: [PATCH] fix: re-enable modal input capture on active overlay window --- src/main/overlay-runtime.test.ts | 35 ++++++++++++++++++++++++++++++++ src/main/overlay-runtime.ts | 16 ++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/main/overlay-runtime.test.ts b/src/main/overlay-runtime.test.ts index 2e94652..04b1768 100644 --- a/src/main/overlay-runtime.test.ts +++ b/src/main/overlay-runtime.test.ts @@ -281,6 +281,41 @@ test('modal runtime notifies callers when modal input state becomes active/inact assert.deepEqual(state, [true, false]); }); +test('notifyOverlayModalOpened enables input on visible main overlay window when no modal window exists', () => { + const mainWindow = createMockWindow(); + mainWindow.visible = true; + mainWindow.ignoreMouseEvents = true; + const state: boolean[] = []; + + const runtime = createOverlayModalRuntimeService( + { + getMainWindow: () => mainWindow as never, + getModalWindow: () => null, + createModalWindow: () => { + throw new Error('modal window should not be created when main overlay is visible'); + }, + getModalGeometry: () => ({ x: 0, y: 0, width: 400, height: 300 }), + setModalWindowBounds: () => {}, + }, + { + onModalStateChange: (active: boolean): void => { + state.push(active); + }, + }, + ); + + const sent = runtime.sendToActiveOverlayWindow('runtime-options:open', undefined, { + restoreOnModalClose: 'runtime-options', + }); + runtime.notifyOverlayModalOpened('runtime-options'); + + assert.equal(sent, true); + assert.equal(state, [true]); + assert.equal(mainWindow.ignoreMouseEvents, false); + assert.equal(mainWindow.isFocused(), true); + assert.equal(mainWindow.webContentsFocused, true); +}); + test('handleOverlayModalClosed resets modal state even when modal window does not exist', () => { const state: boolean[] = []; const runtime = createOverlayModalRuntimeService( diff --git a/src/main/overlay-runtime.ts b/src/main/overlay-runtime.ts index 9cf1c8c..8e6e78c 100644 --- a/src/main/overlay-runtime.ts +++ b/src/main/overlay-runtime.ts @@ -65,6 +65,20 @@ export function createOverlayModalRuntimeService( return null; }; + const getActiveOverlayWindowForModalInput = (): BrowserWindow | null => { + const modalWindow = deps.getModalWindow(); + if (modalWindow && !modalWindow.isDestroyed()) { + return modalWindow; + } + + const visibleMainWindow = deps.getMainWindow(); + if (visibleMainWindow && !visibleMainWindow.isDestroyed()) { + return visibleMainWindow; + } + + return null; + }; + const isWindowReadyForIpc = (window: BrowserWindow): boolean => { if (window.webContents.isLoading()) { return false; @@ -245,7 +259,7 @@ export function createOverlayModalRuntimeService( const notifyOverlayModalOpened = (modal: OverlayHostedModal): void => { if (!restoreVisibleOverlayOnModalClose.has(modal)) return; notifyModalStateChange(true); - const targetWindow = deps.getModalWindow(); + const targetWindow = getActiveOverlayWindowForModalInput(); clearPendingModalWindowReveal(); if (!targetWindow || targetWindow.isDestroyed()) { return;