mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-15 20:12:59 -07:00
fix(macos): default overlay to click-through before subtitle hover
- Set shouldUseMacOSMousePassthrough so overlay starts in forward passthrough mode - Renderer hover tracking re-enables interaction only over subtitle/popup areas - Update tests to expect mouse-ignore:true:forward instead of mouse-ignore:false:plain - Add test covering click-through behavior when overlay already had focus
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
type: fixed
|
||||||
|
area: overlay
|
||||||
|
|
||||||
|
- Fixed macOS overlay passthrough so mpv controls remain clickable before hovering subtitle bars.
|
||||||
@@ -883,7 +883,7 @@ test('visible overlay stays hidden while a modal window is active', () => {
|
|||||||
assert.ok(!calls.includes('update-bounds'));
|
assert.ok(!calls.includes('update-bounds'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('macOS tracked visible overlay stays interactive without passively stealing focus', () => {
|
test('macOS tracked visible overlay starts click-through without passively stealing focus', () => {
|
||||||
const { window, calls } = createMainWindowRecorder();
|
const { window, calls } = createMainWindowRecorder();
|
||||||
const tracker: WindowTrackerStub = {
|
const tracker: WindowTrackerStub = {
|
||||||
isTracking: () => true,
|
isTracking: () => true,
|
||||||
@@ -915,12 +915,52 @@ test('macOS tracked visible overlay stays interactive without passively stealing
|
|||||||
isWindowsPlatform: false,
|
isWindowsPlatform: false,
|
||||||
} as never);
|
} as never);
|
||||||
|
|
||||||
assert.ok(calls.includes('mouse-ignore:false:plain'));
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
assert.ok(calls.includes('show'));
|
assert.ok(calls.includes('show'));
|
||||||
assert.ok(!calls.includes('focus'));
|
assert.ok(!calls.includes('focus'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('macOS keeps active mpv overlay visible and interactive during tracker refresh', () => {
|
test('macOS tracked visible overlay remains click-through even if the overlay had focus', () => {
|
||||||
|
const { window, calls, setFocused } = createMainWindowRecorder();
|
||||||
|
const tracker: WindowTrackerStub = {
|
||||||
|
isTracking: () => true,
|
||||||
|
getGeometry: () => ({ x: 0, y: 0, width: 1280, height: 720 }),
|
||||||
|
isTargetWindowFocused: () => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
setFocused(true);
|
||||||
|
|
||||||
|
updateVisibleOverlayVisibility({
|
||||||
|
visibleOverlayVisible: true,
|
||||||
|
mainWindow: window as never,
|
||||||
|
windowTracker: tracker as never,
|
||||||
|
trackerNotReadyWarningShown: false,
|
||||||
|
setTrackerNotReadyWarningShown: () => {},
|
||||||
|
updateVisibleOverlayBounds: () => {
|
||||||
|
calls.push('update-bounds');
|
||||||
|
},
|
||||||
|
ensureOverlayWindowLevel: () => {
|
||||||
|
calls.push('ensure-level');
|
||||||
|
},
|
||||||
|
syncPrimaryOverlayWindowLayer: () => {
|
||||||
|
calls.push('sync-layer');
|
||||||
|
},
|
||||||
|
enforceOverlayLayerOrder: () => {
|
||||||
|
calls.push('enforce-order');
|
||||||
|
},
|
||||||
|
syncOverlayShortcuts: () => {
|
||||||
|
calls.push('sync-shortcuts');
|
||||||
|
},
|
||||||
|
isMacOSPlatform: true,
|
||||||
|
isWindowsPlatform: false,
|
||||||
|
} as never);
|
||||||
|
|
||||||
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
|
assert.ok(calls.includes('ensure-level'));
|
||||||
|
assert.ok(!calls.includes('focus'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('macOS keeps active mpv overlay visible and click-through during tracker refresh', () => {
|
||||||
const { window, calls } = createMainWindowRecorder();
|
const { window, calls } = createMainWindowRecorder();
|
||||||
const osdMessages: string[] = [];
|
const osdMessages: string[] = [];
|
||||||
const tracker: WindowTrackerStub = {
|
const tracker: WindowTrackerStub = {
|
||||||
@@ -961,7 +1001,7 @@ test('macOS keeps active mpv overlay visible and interactive during tracker refr
|
|||||||
|
|
||||||
assert.ok(calls.includes('update-bounds'));
|
assert.ok(calls.includes('update-bounds'));
|
||||||
assert.ok(calls.includes('sync-layer'));
|
assert.ok(calls.includes('sync-layer'));
|
||||||
assert.ok(calls.includes('mouse-ignore:false:plain'));
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
assert.ok(calls.includes('ensure-level'));
|
assert.ok(calls.includes('ensure-level'));
|
||||||
assert.ok(calls.includes('enforce-order'));
|
assert.ok(calls.includes('enforce-order'));
|
||||||
assert.ok(calls.includes('sync-shortcuts'));
|
assert.ok(calls.includes('sync-shortcuts'));
|
||||||
@@ -1060,7 +1100,7 @@ test('macOS preserves an already visible active mpv overlay while tracker is tem
|
|||||||
|
|
||||||
assert.equal(trackerWarning, false);
|
assert.equal(trackerWarning, false);
|
||||||
assert.ok(calls.includes('sync-layer'));
|
assert.ok(calls.includes('sync-layer'));
|
||||||
assert.ok(calls.includes('mouse-ignore:false:plain'));
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
assert.ok(calls.includes('ensure-level'));
|
assert.ok(calls.includes('ensure-level'));
|
||||||
assert.ok(calls.includes('sync-shortcuts'));
|
assert.ok(calls.includes('sync-shortcuts'));
|
||||||
assert.ok(!calls.includes('hide'));
|
assert.ok(!calls.includes('hide'));
|
||||||
@@ -1390,7 +1430,7 @@ test('macOS preserves visible overlay during transient tracker loss with retaine
|
|||||||
assert.deepEqual(osdMessages, []);
|
assert.deepEqual(osdMessages, []);
|
||||||
assert.ok(calls.includes('update-bounds'));
|
assert.ok(calls.includes('update-bounds'));
|
||||||
assert.ok(calls.includes('sync-layer'));
|
assert.ok(calls.includes('sync-layer'));
|
||||||
assert.ok(calls.includes('mouse-ignore:false:plain'));
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
assert.ok(calls.includes('ensure-level'));
|
assert.ok(calls.includes('ensure-level'));
|
||||||
assert.ok(calls.includes('enforce-order'));
|
assert.ok(calls.includes('enforce-order'));
|
||||||
assert.ok(calls.includes('sync-shortcuts'));
|
assert.ok(calls.includes('sync-shortcuts'));
|
||||||
@@ -1438,7 +1478,7 @@ test('macOS preserves visible overlay level during non-minimized tracker loss',
|
|||||||
} as never);
|
} as never);
|
||||||
|
|
||||||
assert.ok(calls.includes('sync-layer'));
|
assert.ok(calls.includes('sync-layer'));
|
||||||
assert.ok(calls.includes('mouse-ignore:false:plain'));
|
assert.ok(calls.includes('mouse-ignore:true:forward'));
|
||||||
assert.ok(calls.includes('ensure-level'));
|
assert.ok(calls.includes('ensure-level'));
|
||||||
assert.ok(calls.includes('enforce-order'));
|
assert.ok(calls.includes('enforce-order'));
|
||||||
assert.ok(calls.includes('sync-shortcuts'));
|
assert.ok(calls.includes('sync-shortcuts'));
|
||||||
|
|||||||
@@ -98,8 +98,7 @@ export function updateVisibleOverlayVisibility(args: {
|
|||||||
const canReportMacOSTargetMinimized =
|
const canReportMacOSTargetMinimized =
|
||||||
args.isMacOSPlatform && typeof windowTracker?.isTargetWindowMinimized === 'function';
|
args.isMacOSPlatform && typeof windowTracker?.isTargetWindowMinimized === 'function';
|
||||||
const isTrackedMacOSTargetMinimized =
|
const isTrackedMacOSTargetMinimized =
|
||||||
canReportMacOSTargetMinimized &&
|
canReportMacOSTargetMinimized && windowTracker?.isTargetWindowMinimized() === true;
|
||||||
windowTracker?.isTargetWindowMinimized() === true;
|
|
||||||
const hasTransientMacOSTrackerLoss =
|
const hasTransientMacOSTrackerLoss =
|
||||||
args.isMacOSPlatform &&
|
args.isMacOSPlatform &&
|
||||||
canReportMacOSTargetMinimized &&
|
canReportMacOSTargetMinimized &&
|
||||||
@@ -117,6 +116,8 @@ export function updateVisibleOverlayVisibility(args: {
|
|||||||
!hasTransientMacOSTrackerLoss &&
|
!hasTransientMacOSTrackerLoss &&
|
||||||
!isVisibleOverlayFocused &&
|
!isVisibleOverlayFocused &&
|
||||||
!isTrackedMacOSTargetFocused;
|
!isTrackedMacOSTargetFocused;
|
||||||
|
// Renderer hover tracking temporarily disables this for subtitle and popup interaction.
|
||||||
|
const shouldUseMacOSMousePassthrough = args.isMacOSPlatform;
|
||||||
const shouldDefaultToPassthrough =
|
const shouldDefaultToPassthrough =
|
||||||
args.isWindowsPlatform || forceMousePassthrough || shouldReleaseMacOSOverlayLevel;
|
args.isWindowsPlatform || forceMousePassthrough || shouldReleaseMacOSOverlayLevel;
|
||||||
const windowsForegroundProcessName =
|
const windowsForegroundProcessName =
|
||||||
@@ -141,6 +142,7 @@ export function updateVisibleOverlayVisibility(args: {
|
|||||||
(args.windowTracker.isTracking() || args.windowTracker.getGeometry() !== null);
|
(args.windowTracker.isTracking() || args.windowTracker.getGeometry() !== null);
|
||||||
const shouldForcePassiveReshow = args.isWindowsPlatform && !wasVisible;
|
const shouldForcePassiveReshow = args.isWindowsPlatform && !wasVisible;
|
||||||
const shouldIgnoreMouseEvents =
|
const shouldIgnoreMouseEvents =
|
||||||
|
shouldUseMacOSMousePassthrough ||
|
||||||
forceMousePassthrough ||
|
forceMousePassthrough ||
|
||||||
(shouldDefaultToPassthrough && (!isVisibleOverlayFocused || shouldForcePassiveReshow));
|
(shouldDefaultToPassthrough && (!isVisibleOverlayFocused || shouldForcePassiveReshow));
|
||||||
const shouldBindTrackedWindowsOverlay = args.isWindowsPlatform && !!args.windowTracker;
|
const shouldBindTrackedWindowsOverlay = args.isWindowsPlatform && !!args.windowTracker;
|
||||||
@@ -291,8 +293,7 @@ export function updateVisibleOverlayVisibility(args: {
|
|||||||
const canReportMacOSTargetMinimized =
|
const canReportMacOSTargetMinimized =
|
||||||
args.isMacOSPlatform && typeof args.windowTracker.isTargetWindowMinimized === 'function';
|
args.isMacOSPlatform && typeof args.windowTracker.isTargetWindowMinimized === 'function';
|
||||||
const isTrackedMacOSTargetMinimized =
|
const isTrackedMacOSTargetMinimized =
|
||||||
canReportMacOSTargetMinimized &&
|
canReportMacOSTargetMinimized && args.windowTracker.isTargetWindowMinimized();
|
||||||
args.windowTracker.isTargetWindowMinimized();
|
|
||||||
const shouldPreserveTransientTrackedOverlay =
|
const shouldPreserveTransientTrackedOverlay =
|
||||||
(args.isMacOSPlatform &&
|
(args.isMacOSPlatform &&
|
||||||
!isTrackedMacOSTargetMinimized &&
|
!isTrackedMacOSTargetMinimized &&
|
||||||
|
|||||||
@@ -822,6 +822,7 @@ test('default keybindings dispatch through overlay keyboard handling', async ()
|
|||||||
testGlobals.sessionActions.map((action) => action.actionId).sort(),
|
testGlobals.sessionActions.map((action) => action.actionId).sort(),
|
||||||
expectedSessionActions.sort(),
|
expectedSessionActions.sort(),
|
||||||
);
|
);
|
||||||
|
testGlobals.dispatchKeydown({ key: 'Escape', code: 'Escape' });
|
||||||
} finally {
|
} finally {
|
||||||
testGlobals.restore();
|
testGlobals.restore();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user