Files
SubMiner/src/main/overlay-visibility-runtime.ts
Kyle 7698258f61 Fix Windows overlay tracking, z-order, and startup visibility
- switch Windows overlay tracking to native win32 polling with native owner and z-order helpers
- keep the visible overlay and stats overlay aligned across focus handoff, transient tracker misses, and minimize/restore cycles
- start the visible overlay click-through and hide the initial opaque startup frame until the tracked transparent state settles
- add a backlog task for the inconsistent mpv y-t overlay toggle after menu toggles
2026-04-10 01:00:53 -07:00

87 lines
3.7 KiB
TypeScript

import type { BrowserWindow } from 'electron';
import type { BaseWindowTracker } from '../window-trackers';
import type { WindowGeometry } from '../types';
import { updateVisibleOverlayVisibility } from '../core/services';
const OVERLAY_LOADING_OSD_COOLDOWN_MS = 30_000;
export interface OverlayVisibilityRuntimeDeps {
getMainWindow: () => BrowserWindow | null;
getModalActive: () => boolean;
getVisibleOverlayVisible: () => boolean;
getForceMousePassthrough: () => boolean;
getWindowTracker: () => BaseWindowTracker | null;
getLastKnownWindowsForegroundProcessName?: () => string | null;
getWindowsOverlayProcessName?: () => string | null;
getWindowsFocusHandoffGraceActive?: () => boolean;
getTrackerNotReadyWarningShown: () => boolean;
setTrackerNotReadyWarningShown: (shown: boolean) => void;
updateVisibleOverlayBounds: (geometry: WindowGeometry) => void;
ensureOverlayWindowLevel: (window: BrowserWindow) => void;
syncWindowsOverlayToMpvZOrder?: (window: BrowserWindow) => void;
syncPrimaryOverlayWindowLayer: (layer: 'visible') => void;
enforceOverlayLayerOrder: () => void;
syncOverlayShortcuts: () => void;
isMacOSPlatform: () => boolean;
isWindowsPlatform: () => boolean;
showOverlayLoadingOsd: (message: string) => void;
resolveFallbackBounds: () => WindowGeometry;
}
export interface OverlayVisibilityRuntimeService {
updateVisibleOverlayVisibility: () => void;
}
export function createOverlayVisibilityRuntimeService(
deps: OverlayVisibilityRuntimeDeps,
): OverlayVisibilityRuntimeService {
let lastOverlayLoadingOsdAtMs: number | null = null;
return {
updateVisibleOverlayVisibility(): void {
const visibleOverlayVisible = deps.getVisibleOverlayVisible();
const forceMousePassthrough = deps.getForceMousePassthrough();
const windowTracker = deps.getWindowTracker();
const mainWindow = deps.getMainWindow();
updateVisibleOverlayVisibility({
visibleOverlayVisible,
modalActive: deps.getModalActive(),
forceMousePassthrough,
mainWindow,
windowTracker,
lastKnownWindowsForegroundProcessName: deps.getLastKnownWindowsForegroundProcessName?.(),
windowsOverlayProcessName: deps.getWindowsOverlayProcessName?.() ?? null,
windowsFocusHandoffGraceActive: deps.getWindowsFocusHandoffGraceActive?.() ?? false,
trackerNotReadyWarningShown: deps.getTrackerNotReadyWarningShown(),
setTrackerNotReadyWarningShown: (shown: boolean) => {
deps.setTrackerNotReadyWarningShown(shown);
},
updateVisibleOverlayBounds: (geometry: WindowGeometry) =>
deps.updateVisibleOverlayBounds(geometry),
ensureOverlayWindowLevel: (window: BrowserWindow) => deps.ensureOverlayWindowLevel(window),
syncWindowsOverlayToMpvZOrder: (window: BrowserWindow) =>
deps.syncWindowsOverlayToMpvZOrder?.(window),
syncPrimaryOverlayWindowLayer: (layer: 'visible') =>
deps.syncPrimaryOverlayWindowLayer(layer),
enforceOverlayLayerOrder: () => deps.enforceOverlayLayerOrder(),
syncOverlayShortcuts: () => deps.syncOverlayShortcuts(),
isMacOSPlatform: deps.isMacOSPlatform(),
isWindowsPlatform: deps.isWindowsPlatform(),
showOverlayLoadingOsd: (message: string) => deps.showOverlayLoadingOsd(message),
shouldShowOverlayLoadingOsd: () =>
lastOverlayLoadingOsdAtMs === null ||
Date.now() - lastOverlayLoadingOsdAtMs >= OVERLAY_LOADING_OSD_COOLDOWN_MS,
markOverlayLoadingOsdShown: () => {
lastOverlayLoadingOsdAtMs = Date.now();
},
resetOverlayLoadingOsdSuppression: () => {
lastOverlayLoadingOsdAtMs = null;
},
resolveFallbackBounds: () => deps.resolveFallbackBounds(),
});
},
};
}