mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
small fixes
This commit is contained in:
@@ -117,7 +117,7 @@ export function createOverlayWindow(
|
||||
|
||||
window.webContents.on('before-input-event', (event, input) => {
|
||||
if (kind === 'modal') return;
|
||||
if (!options.isOverlayVisible(kind)) return;
|
||||
if (!window.isVisible()) return;
|
||||
if (!options.tryHandleOverlayShortcutLocalFallback(input)) return;
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
@@ -225,6 +225,27 @@ test('handleOverlayModalClosed hides modal window only after all pending modals
|
||||
assert.equal(window.getHideCount(), 1);
|
||||
});
|
||||
|
||||
test('sendToActiveOverlayWindow prefers visible main overlay window for modal open', () => {
|
||||
const mainWindow = createMockWindow();
|
||||
mainWindow.visible = true;
|
||||
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: () => {},
|
||||
});
|
||||
|
||||
const sent = runtime.sendToActiveOverlayWindow('runtime-options:open', undefined, {
|
||||
restoreOnModalClose: 'runtime-options',
|
||||
});
|
||||
|
||||
assert.equal(sent, true);
|
||||
assert.deepEqual(mainWindow.sent, [['runtime-options:open']]);
|
||||
});
|
||||
|
||||
test('modal runtime notifies callers when modal input state becomes active/inactive', () => {
|
||||
const window = createMockWindow();
|
||||
const state: boolean[] = [];
|
||||
@@ -249,6 +270,8 @@ test('modal runtime notifies callers when modal input state becomes active/inact
|
||||
runtime.sendToActiveOverlayWindow('subsync:open-manual', { sourceTracks: [] }, {
|
||||
restoreOnModalClose: 'subsync',
|
||||
});
|
||||
assert.deepEqual(state, []);
|
||||
runtime.notifyOverlayModalOpened('runtime-options');
|
||||
assert.deepEqual(state, [true]);
|
||||
|
||||
runtime.handleOverlayModalClosed('runtime-options');
|
||||
@@ -258,6 +281,32 @@ test('modal runtime notifies callers when modal input state becomes active/inact
|
||||
assert.deepEqual(state, [true, false]);
|
||||
});
|
||||
|
||||
test('handleOverlayModalClosed resets modal state even when modal window does not exist', () => {
|
||||
const state: boolean[] = [];
|
||||
const runtime = createOverlayModalRuntimeService(
|
||||
{
|
||||
getMainWindow: () => null,
|
||||
getModalWindow: () => null,
|
||||
createModalWindow: () => null,
|
||||
getModalGeometry: () => ({ x: 0, y: 0, width: 400, height: 300 }),
|
||||
setModalWindowBounds: () => {},
|
||||
},
|
||||
{
|
||||
onModalStateChange: (active: boolean): void => {
|
||||
state.push(active);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
runtime.sendToActiveOverlayWindow('runtime-options:open', undefined, {
|
||||
restoreOnModalClose: 'runtime-options',
|
||||
});
|
||||
runtime.notifyOverlayModalOpened('runtime-options');
|
||||
runtime.handleOverlayModalClosed('runtime-options');
|
||||
|
||||
assert.deepEqual(state, [true, false]);
|
||||
});
|
||||
|
||||
test('handleOverlayModalClosed hides modal window for single kiku modal', () => {
|
||||
const window = createMockWindow();
|
||||
const runtime = createOverlayModalRuntimeService({
|
||||
|
||||
@@ -65,13 +65,19 @@ export function createOverlayModalRuntimeService(
|
||||
return null;
|
||||
};
|
||||
|
||||
const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
if (window.webContents.isLoading()) {
|
||||
return false;
|
||||
}
|
||||
const currentURL = window.webContents.getURL();
|
||||
return currentURL !== '' && currentURL !== 'about:blank';
|
||||
};
|
||||
};
|
||||
|
||||
const elevateModalWindow = (window: BrowserWindow): void => {
|
||||
if (window.isDestroyed()) return;
|
||||
window.setAlwaysOnTop(true, 'screen-saver', 1);
|
||||
window.moveTop();
|
||||
};
|
||||
|
||||
const sendOrQueueForWindow = (
|
||||
window: BrowserWindow,
|
||||
@@ -95,7 +101,10 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
passThroughMouseEvents: boolean;
|
||||
} = { passThroughMouseEvents: false },
|
||||
): void => {
|
||||
if (!window.isVisible()) {
|
||||
window.show();
|
||||
}
|
||||
elevateModalWindow(window);
|
||||
if (options.passThroughMouseEvents) {
|
||||
window.setIgnoreMouseEvents(true, { forward: true });
|
||||
} else {
|
||||
@@ -107,6 +116,22 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
}
|
||||
};
|
||||
|
||||
const ensureModalWindowInteractive = (window: BrowserWindow): void => {
|
||||
if (window.isVisible()) {
|
||||
window.setIgnoreMouseEvents(false);
|
||||
if (!window.isFocused()) {
|
||||
window.focus();
|
||||
}
|
||||
if (!window.webContents.isFocused()) {
|
||||
window.webContents.focus();
|
||||
}
|
||||
elevateModalWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
showModalWindow(window);
|
||||
};
|
||||
|
||||
const showOverlayWindowForModal = (window: BrowserWindow): void => {
|
||||
window.show();
|
||||
if (!window.isFocused()) {
|
||||
@@ -137,7 +162,7 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
if (!targetWindow || targetWindow.isDestroyed() || targetWindow.isVisible()) {
|
||||
return;
|
||||
}
|
||||
showModalWindow(targetWindow, { passThroughMouseEvents: true });
|
||||
showModalWindow(targetWindow, { passThroughMouseEvents: false });
|
||||
}, MODAL_REVEAL_FALLBACK_DELAY_MS);
|
||||
};
|
||||
|
||||
@@ -149,6 +174,7 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
const restoreOnModalClose = runtimeOptions?.restoreOnModalClose;
|
||||
|
||||
const sendNow = (window: BrowserWindow): void => {
|
||||
ensureModalWindowInteractive(window);
|
||||
if (payload === undefined) {
|
||||
window.webContents.send(channel);
|
||||
} else {
|
||||
@@ -157,17 +183,24 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
};
|
||||
|
||||
if (restoreOnModalClose) {
|
||||
restoreVisibleOverlayOnModalClose.add(restoreOnModalClose);
|
||||
const mainWindow = getTargetOverlayWindow();
|
||||
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isVisible()) {
|
||||
sendOrQueueForWindow(mainWindow, (window) => {
|
||||
if (payload === undefined) {
|
||||
window.webContents.send(channel);
|
||||
} else {
|
||||
window.webContents.send(channel, payload);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
const modalWindow = resolveModalWindow();
|
||||
if (!modalWindow) return false;
|
||||
|
||||
deps.setModalWindowBounds(deps.getModalGeometry());
|
||||
const wasVisible = modalWindow.isVisible();
|
||||
const wasModalActive = restoreVisibleOverlayOnModalClose.size > 0;
|
||||
restoreVisibleOverlayOnModalClose.add(restoreOnModalClose);
|
||||
if (!wasModalActive) {
|
||||
notifyModalStateChange(true);
|
||||
}
|
||||
|
||||
if (!wasVisible) {
|
||||
scheduleModalWindowReveal(modalWindow);
|
||||
} else if (!modalWindow.isFocused()) {
|
||||
@@ -199,17 +232,21 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
const handleOverlayModalClosed = (modal: OverlayHostedModal): void => {
|
||||
if (!restoreVisibleOverlayOnModalClose.has(modal)) return;
|
||||
restoreVisibleOverlayOnModalClose.delete(modal);
|
||||
const modalWindow = deps.getModalWindow();
|
||||
if (!modalWindow || modalWindow.isDestroyed()) return;
|
||||
if (restoreVisibleOverlayOnModalClose.size === 0) {
|
||||
clearPendingModalWindowReveal();
|
||||
notifyModalStateChange(false);
|
||||
}
|
||||
|
||||
const modalWindow = deps.getModalWindow();
|
||||
if (!modalWindow || modalWindow.isDestroyed()) return;
|
||||
if (restoreVisibleOverlayOnModalClose.size === 0) {
|
||||
modalWindow.hide();
|
||||
}
|
||||
};
|
||||
|
||||
const notifyOverlayModalOpened = (modal: OverlayHostedModal): void => {
|
||||
if (!restoreVisibleOverlayOnModalClose.has(modal)) return;
|
||||
notifyModalStateChange(true);
|
||||
const targetWindow = deps.getModalWindow();
|
||||
clearPendingModalWindowReveal();
|
||||
if (!targetWindow || targetWindow.isDestroyed()) {
|
||||
@@ -218,6 +255,7 @@ const isWindowReadyForIpc = (window: BrowserWindow): boolean => {
|
||||
|
||||
if (targetWindow.isVisible()) {
|
||||
targetWindow.setIgnoreMouseEvents(false);
|
||||
elevateModalWindow(targetWindow);
|
||||
if (!targetWindow.isFocused()) {
|
||||
targetWindow.focus();
|
||||
}
|
||||
|
||||
@@ -41,5 +41,5 @@ test('overlay runtime bootstrap runs core init and applies post-init state', ()
|
||||
|
||||
initialize();
|
||||
assert.equal(initialized, true);
|
||||
assert.deepEqual(calls, ['options', 'core', 'initialized:yes', 'warmups']);
|
||||
assert.deepEqual(calls, ['options', 'initialized:yes', 'core', 'warmups']);
|
||||
});
|
||||
|
||||
@@ -41,8 +41,14 @@ export function createInitializeOverlayRuntimeHandler(deps: {
|
||||
}) {
|
||||
return (): void => {
|
||||
if (deps.isOverlayRuntimeInitialized()) return;
|
||||
deps.initializeOverlayRuntimeCore(deps.buildOptions());
|
||||
const options = deps.buildOptions();
|
||||
deps.setOverlayRuntimeInitialized(true);
|
||||
try {
|
||||
deps.initializeOverlayRuntimeCore(options);
|
||||
} catch (error) {
|
||||
deps.setOverlayRuntimeInitialized(false);
|
||||
throw error;
|
||||
}
|
||||
deps.startBackgroundWarmups();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user