From ae44477a695dcd9e0218c75df8bc1b427b5c48dd Mon Sep 17 00:00:00 2001 From: sudacode Date: Wed, 11 Mar 2026 20:08:14 -0700 Subject: [PATCH] Wire Yomitan session into overlay window creation - Pass `yomitanSession` through overlay window factory deps - Set BrowserWindow `webPreferences.session` when session is available - Extend tests to verify session plumbing across runtime/factory layers --- src/core/services/overlay-window-config.test.ts | 7 +++++++ src/core/services/overlay-window.ts | 4 +++- src/main.ts | 9 +++++---- .../runtime/overlay-window-factory-main-deps.test.ts | 3 +++ src/main/runtime/overlay-window-factory-main-deps.ts | 5 +++++ src/main/runtime/overlay-window-factory.test.ts | 3 +++ src/main/runtime/overlay-window-factory.ts | 5 +++++ src/main/runtime/overlay-window-runtime-handlers.test.ts | 9 +++++++-- 8 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/core/services/overlay-window-config.test.ts b/src/core/services/overlay-window-config.test.ts index c6964a2..3bac186 100644 --- a/src/core/services/overlay-window-config.test.ts +++ b/src/core/services/overlay-window-config.test.ts @@ -9,3 +9,10 @@ test('overlay window config explicitly disables renderer sandbox for preload com assert.match(source, /webPreferences:\s*\{[\s\S]*sandbox:\s*false[\s\S]*\}/m); }); + +test('overlay window config uses the provided Yomitan session when available', () => { + const sourcePath = path.join(process.cwd(), 'src/core/services/overlay-window.ts'); + const source = fs.readFileSync(sourcePath, 'utf8'); + + assert.match(source, /session:\s*options\.yomitanSession\s*\?\?\s*undefined/); +}); diff --git a/src/core/services/overlay-window.ts b/src/core/services/overlay-window.ts index b1dd61c..c7700c4 100644 --- a/src/core/services/overlay-window.ts +++ b/src/core/services/overlay-window.ts @@ -1,4 +1,4 @@ -import { BrowserWindow } from 'electron'; +import { BrowserWindow, type Session } from 'electron'; import * as path from 'path'; import { WindowGeometry } from '../../types'; import { createLogger } from '../../logger'; @@ -78,6 +78,7 @@ export function createOverlayWindow( tryHandleOverlayShortcutLocalFallback: (input: Electron.Input) => boolean; forwardTabToMpv: () => void; onWindowClosed: (kind: OverlayWindowKind) => void; + yomitanSession?: Session | null; }, ): BrowserWindow { const showNativeDebugFrame = process.platform === 'win32' && options.isDev; @@ -102,6 +103,7 @@ export function createOverlayWindow( nodeIntegration: false, sandbox: false, webSecurity: true, + session: options.yomitanSession ?? undefined, additionalArguments: [`--overlay-layer=${kind}`], }, }); diff --git a/src/main.ts b/src/main.ts index b967c52..e9541dd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3556,10 +3556,11 @@ const { createMainWindow: createMainWindowHandler, createModalWindow: createModa onRuntimeOptionsChanged: () => broadcastRuntimeOptionsChanged(), setOverlayDebugVisualizationEnabled: (enabled) => setOverlayDebugVisualizationEnabled(enabled), - isOverlayVisible: (windowKind) => - windowKind === 'visible' ? overlayManager.getVisibleOverlayVisible() : false, - tryHandleOverlayShortcutLocalFallback: (input) => - overlayShortcutsRuntime.tryHandleOverlayShortcutLocalFallback(input), + isOverlayVisible: (windowKind) => + windowKind === 'visible' ? overlayManager.getVisibleOverlayVisible() : false, + getYomitanSession: () => appState.yomitanSession, + tryHandleOverlayShortcutLocalFallback: (input) => + overlayShortcutsRuntime.tryHandleOverlayShortcutLocalFallback(input), forwardTabToMpv: () => sendMpvCommandRuntime(appState.mpvClient, ['keypress', 'TAB']), onWindowClosed: (windowKind) => { if (windowKind === 'visible') { diff --git a/src/main/runtime/overlay-window-factory-main-deps.test.ts b/src/main/runtime/overlay-window-factory-main-deps.test.ts index 11d73af..49e48f0 100644 --- a/src/main/runtime/overlay-window-factory-main-deps.test.ts +++ b/src/main/runtime/overlay-window-factory-main-deps.test.ts @@ -8,6 +8,7 @@ import { test('overlay window factory main deps builders return mapped handlers', () => { const calls: string[] = []; + const yomitanSession = { id: 'session' } as never; const buildOverlayDeps = createBuildCreateOverlayWindowMainDepsHandler({ createOverlayWindowCore: (kind) => ({ kind }), isDev: true, @@ -18,11 +19,13 @@ test('overlay window factory main deps builders return mapped handlers', () => { tryHandleOverlayShortcutLocalFallback: () => false, forwardTabToMpv: () => calls.push('forward-tab'), onWindowClosed: (kind) => calls.push(`closed:${kind}`), + getYomitanSession: () => yomitanSession, }); const overlayDeps = buildOverlayDeps(); assert.equal(overlayDeps.isDev, true); assert.equal(overlayDeps.isOverlayVisible('visible'), true); + assert.equal(overlayDeps.getYomitanSession(), yomitanSession); overlayDeps.forwardTabToMpv(); const buildMainDeps = createBuildCreateMainWindowMainDepsHandler({ diff --git a/src/main/runtime/overlay-window-factory-main-deps.ts b/src/main/runtime/overlay-window-factory-main-deps.ts index 8475ce7..881289d 100644 --- a/src/main/runtime/overlay-window-factory-main-deps.ts +++ b/src/main/runtime/overlay-window-factory-main-deps.ts @@ -1,3 +1,5 @@ +import type { Session } from 'electron'; + export function createBuildCreateOverlayWindowMainDepsHandler(deps: { createOverlayWindowCore: ( kind: 'visible' | 'modal', @@ -10,6 +12,7 @@ export function createBuildCreateOverlayWindowMainDepsHandler(deps: { tryHandleOverlayShortcutLocalFallback: (input: Electron.Input) => boolean; forwardTabToMpv: () => void; onWindowClosed: (windowKind: 'visible' | 'modal') => void; + yomitanSession?: Session | null; }, ) => TWindow; isDev: boolean; @@ -20,6 +23,7 @@ export function createBuildCreateOverlayWindowMainDepsHandler(deps: { tryHandleOverlayShortcutLocalFallback: (input: Electron.Input) => boolean; forwardTabToMpv: () => void; onWindowClosed: (windowKind: 'visible' | 'modal') => void; + getYomitanSession?: () => Session | null; }) { return () => ({ createOverlayWindowCore: deps.createOverlayWindowCore, @@ -31,6 +35,7 @@ export function createBuildCreateOverlayWindowMainDepsHandler(deps: { tryHandleOverlayShortcutLocalFallback: deps.tryHandleOverlayShortcutLocalFallback, forwardTabToMpv: deps.forwardTabToMpv, onWindowClosed: deps.onWindowClosed, + getYomitanSession: () => deps.getYomitanSession?.() ?? null, }); } diff --git a/src/main/runtime/overlay-window-factory.test.ts b/src/main/runtime/overlay-window-factory.test.ts index f06a29b..85f98c7 100644 --- a/src/main/runtime/overlay-window-factory.test.ts +++ b/src/main/runtime/overlay-window-factory.test.ts @@ -9,12 +9,14 @@ import { test('create overlay window handler forwards options and kind', () => { const calls: string[] = []; const window = { id: 1 }; + const yomitanSession = { id: 'session' } as never; const createOverlayWindow = createCreateOverlayWindowHandler({ createOverlayWindowCore: (kind, options) => { calls.push(`kind:${kind}`); assert.equal(options.isDev, true); assert.equal(options.isOverlayVisible('visible'), true); assert.equal(options.isOverlayVisible('modal'), false); + assert.equal(options.yomitanSession, yomitanSession); options.forwardTabToMpv(); options.onRuntimeOptionsChanged(); options.setOverlayDebugVisualizationEnabled(true); @@ -29,6 +31,7 @@ test('create overlay window handler forwards options and kind', () => { tryHandleOverlayShortcutLocalFallback: () => false, forwardTabToMpv: () => calls.push('forward-tab'), onWindowClosed: (kind) => calls.push(`closed:${kind}`), + getYomitanSession: () => yomitanSession, }); assert.equal(createOverlayWindow('visible'), window); diff --git a/src/main/runtime/overlay-window-factory.ts b/src/main/runtime/overlay-window-factory.ts index 9428264..9219ad1 100644 --- a/src/main/runtime/overlay-window-factory.ts +++ b/src/main/runtime/overlay-window-factory.ts @@ -1,3 +1,5 @@ +import type { Session } from 'electron'; + type OverlayWindowKind = 'visible' | 'modal'; export function createCreateOverlayWindowHandler(deps: { @@ -12,6 +14,7 @@ export function createCreateOverlayWindowHandler(deps: { tryHandleOverlayShortcutLocalFallback: (input: Electron.Input) => boolean; forwardTabToMpv: () => void; onWindowClosed: (windowKind: OverlayWindowKind) => void; + yomitanSession?: Session | null; }, ) => TWindow; isDev: boolean; @@ -22,6 +25,7 @@ export function createCreateOverlayWindowHandler(deps: { tryHandleOverlayShortcutLocalFallback: (input: Electron.Input) => boolean; forwardTabToMpv: () => void; onWindowClosed: (windowKind: OverlayWindowKind) => void; + getYomitanSession?: () => Session | null; }) { return (kind: OverlayWindowKind): TWindow => { return deps.createOverlayWindowCore(kind, { @@ -33,6 +37,7 @@ export function createCreateOverlayWindowHandler(deps: { tryHandleOverlayShortcutLocalFallback: deps.tryHandleOverlayShortcutLocalFallback, forwardTabToMpv: deps.forwardTabToMpv, onWindowClosed: deps.onWindowClosed, + yomitanSession: deps.getYomitanSession?.() ?? null, }); }; } diff --git a/src/main/runtime/overlay-window-runtime-handlers.test.ts b/src/main/runtime/overlay-window-runtime-handlers.test.ts index d7b43d6..39b4711 100644 --- a/src/main/runtime/overlay-window-runtime-handlers.test.ts +++ b/src/main/runtime/overlay-window-runtime-handlers.test.ts @@ -7,10 +7,14 @@ test('overlay window runtime handlers compose create/main/modal handlers', () => let modalWindow: { kind: string } | null = null; let debugEnabled = false; const calls: string[] = []; + const yomitanSession = { id: 'session' } as never; - const runtime = createOverlayWindowRuntimeHandlers({ + const runtime = createOverlayWindowRuntimeHandlers<{ kind: string }>({ createOverlayWindowDeps: { - createOverlayWindowCore: (kind) => ({ kind }), + createOverlayWindowCore: (kind, options) => { + assert.equal(options.yomitanSession, yomitanSession); + return { kind }; + }, isDev: true, ensureOverlayWindowLevel: () => calls.push('ensure-level'), onRuntimeOptionsChanged: () => calls.push('runtime-options-changed'), @@ -21,6 +25,7 @@ test('overlay window runtime handlers compose create/main/modal handlers', () => tryHandleOverlayShortcutLocalFallback: () => false, forwardTabToMpv: () => calls.push('forward-tab'), onWindowClosed: (kind) => calls.push(`closed:${kind}`), + getYomitanSession: () => yomitanSession, }, setMainWindow: (window) => { mainWindow = window;