diff --git a/changes/fix-windows-secondary-hover-titlebar.md b/changes/fix-windows-secondary-hover-titlebar.md new file mode 100644 index 00000000..94890fba --- /dev/null +++ b/changes/fix-windows-secondary-hover-titlebar.md @@ -0,0 +1,4 @@ +type: fixed +area: overlay + +- Fixed Windows secondary subtitle hover mode so the expanded hover hit area no longer blocks the native minimize, maximize, and close buttons. diff --git a/src/renderer/error-recovery.test.ts b/src/renderer/error-recovery.test.ts index eea72bdf..dabd10e0 100644 --- a/src/renderer/error-recovery.test.ts +++ b/src/renderer/error-recovery.test.ts @@ -230,6 +230,42 @@ test('resolvePlatformInfo supports modal layer and disables mouse-ignore toggles } }); +test('resolvePlatformInfo flags Windows platforms', () => { + const previousWindow = (globalThis as { window?: unknown }).window; + const previousNavigator = (globalThis as { navigator?: unknown }).navigator; + + Object.defineProperty(globalThis, 'window', { + configurable: true, + value: { + electronAPI: { + getOverlayLayer: () => 'visible', + }, + location: { search: '' }, + }, + }); + Object.defineProperty(globalThis, 'navigator', { + configurable: true, + value: { + platform: 'Win32', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', + }, + }); + + try { + const info = resolvePlatformInfo(); + assert.equal(info.isWindowsPlatform, true); + assert.equal(info.isMacOSPlatform, false); + assert.equal(info.isLinuxPlatform, false); + assert.equal(info.shouldToggleMouseIgnore, true); + } finally { + Object.defineProperty(globalThis, 'window', { configurable: true, value: previousWindow }); + Object.defineProperty(globalThis, 'navigator', { + configurable: true, + value: previousNavigator, + }); + } +}); + test('isYomitanPopupIframe matches modern popup class and legacy id prefix', () => { const createElement = (options: { tagName: string; diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts index df4744a4..df3d363c 100644 --- a/src/renderer/renderer.ts +++ b/src/renderer/renderer.ts @@ -529,6 +529,9 @@ async function init(): Promise { if (ctx.platform.isMacOSPlatform) { document.body.classList.add('platform-macos'); } + if (ctx.platform.isWindowsPlatform) { + document.body.classList.add('platform-windows'); + } if (ctx.platform.shouldToggleMouseIgnore) { syncOverlayMouseIgnoreState(ctx); } diff --git a/src/renderer/style.css b/src/renderer/style.css index 53c4ce7d..641c2e7e 100644 --- a/src/renderer/style.css +++ b/src/renderer/style.css @@ -1131,6 +1131,11 @@ body.subtitle-sidebar-embedded-open #secondarySubContainer.secondary-sub-hover { justify-content: center; } +body.platform-windows #secondarySubContainer.secondary-sub-hover { + top: 40px; + padding-top: 0; +} + #secondarySubContainer.secondary-sub-hover #secondarySubRoot { background: transparent; backdrop-filter: none; diff --git a/src/renderer/subtitle-render.test.ts b/src/renderer/subtitle-render.test.ts index ef80f024..04fc6262 100644 --- a/src/renderer/subtitle-render.test.ts +++ b/src/renderer/subtitle-render.test.ts @@ -989,6 +989,13 @@ test('JLPT CSS rules use underline-only styling in renderer stylesheet', () => { /transform:\s*translateX\(calc\(var\(--subtitle-sidebar-reserved-width\)\s*\*\s*-0\.5\)\);/, ); + const secondaryHoverWindowsBlock = extractClassBlock( + cssText, + 'body.platform-windows #secondarySubContainer.secondary-sub-hover', + ); + assert.match(secondaryHoverWindowsBlock, /top:\s*40px;/); + assert.match(secondaryHoverWindowsBlock, /padding-top:\s*0;/); + const subtitleSidebarListBlock = extractClassBlock(cssText, '.subtitle-sidebar-list'); assert.doesNotMatch(subtitleSidebarListBlock, /scroll-behavior:\s*smooth;/); diff --git a/src/renderer/utils/platform.ts b/src/renderer/utils/platform.ts index 7134c038..0169ed17 100644 --- a/src/renderer/utils/platform.ts +++ b/src/renderer/utils/platform.ts @@ -5,6 +5,7 @@ export type PlatformInfo = { isModalLayer: boolean; isLinuxPlatform: boolean; isMacOSPlatform: boolean; + isWindowsPlatform: boolean; shouldToggleMouseIgnore: boolean; }; @@ -24,12 +25,15 @@ export function resolvePlatformInfo(): PlatformInfo { const isLinuxPlatform = navigator.platform.toLowerCase().includes('linux'); const isMacOSPlatform = navigator.platform.toLowerCase().includes('mac') || /mac/i.test(navigator.userAgent); + const isWindowsPlatform = + navigator.platform.toLowerCase().includes('win') || /windows/i.test(navigator.userAgent); return { overlayLayer, isModalLayer, isLinuxPlatform, isMacOSPlatform, + isWindowsPlatform, shouldToggleMouseIgnore: !isLinuxPlatform && !isModalLayer, }; }