mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
fix(macos): drop target after grace period on repeated tracking misses
- registerTrackingMiss was resetting grace state on every miss, so focus was never released; now starts timer on first miss and drops after grace elapses - update two tests to assert focus is dropped (not preserved) once grace expires - add IPC test for setIgnoreMouseEvents → onOverlayMouseInteractionChanged mapping
This commit is contained in:
@@ -311,6 +311,28 @@ test('createIpcDepsRuntime wires AniList handlers', async () => {
|
||||
assert.equal(deps.getPlaybackPaused(), true);
|
||||
});
|
||||
|
||||
test('registerIpcHandlers maps setIgnoreMouseEvents to overlay interaction active state', () => {
|
||||
const { registrar, handlers } = createFakeIpcRegistrar();
|
||||
const calls: string[] = [];
|
||||
|
||||
registerIpcHandlers(
|
||||
createRegisterIpcDeps({
|
||||
onOverlayMouseInteractionChanged: (active) => {
|
||||
calls.push(`overlay-interaction:${active}`);
|
||||
},
|
||||
}),
|
||||
registrar,
|
||||
);
|
||||
|
||||
const handler = handlers.on.get(IPC_CHANNELS.command.setIgnoreMouseEvents);
|
||||
assert.equal(typeof handler, 'function');
|
||||
|
||||
handler?.({}, true, { forward: true });
|
||||
handler?.({}, false, {});
|
||||
|
||||
assert.deepEqual(calls, ['overlay-interaction:false', 'overlay-interaction:true']);
|
||||
});
|
||||
|
||||
test('registerIpcHandlers runs AniList update after manual mark watched succeeds', async () => {
|
||||
const { registrar, handlers } = createFakeIpcRegistrar();
|
||||
const calls: string[] = [];
|
||||
|
||||
@@ -236,7 +236,7 @@ test('MacOSWindowTracker keeps focused fullscreen target through active helper m
|
||||
});
|
||||
});
|
||||
|
||||
test('MacOSWindowTracker keeps previously focused target through repeated not-found misses after grace', async () => {
|
||||
test('MacOSWindowTracker drops previously focused target after repeated not-found misses exceed grace', async () => {
|
||||
let callIndex = 0;
|
||||
let now = 1_000;
|
||||
const focusChanges: boolean[] = [];
|
||||
@@ -244,7 +244,6 @@ test('MacOSWindowTracker keeps previously focused target through repeated not-fo
|
||||
{ stdout: '10,20,1280,720,1', stderr: '' },
|
||||
{ stdout: 'not-found', stderr: '' },
|
||||
{ stdout: 'not-found', stderr: '' },
|
||||
{ stdout: 'not-found', stderr: '' },
|
||||
];
|
||||
|
||||
const tracker = new MacOSWindowTracker('/tmp/mpv.sock', {
|
||||
@@ -269,14 +268,6 @@ test('MacOSWindowTracker keeps previously focused target through repeated not-fo
|
||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
now += 1_000;
|
||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
now += 1_000;
|
||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
assert.equal(tracker.isTracking(), true);
|
||||
assert.equal(tracker.isTargetWindowFocused(), true);
|
||||
assert.deepEqual(tracker.getGeometry(), {
|
||||
@@ -286,9 +277,18 @@ test('MacOSWindowTracker keeps previously focused target through repeated not-fo
|
||||
height: 720,
|
||||
});
|
||||
assert.deepEqual(focusChanges, [true]);
|
||||
|
||||
now += 1_000;
|
||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
assert.equal(tracker.isTracking(), false);
|
||||
assert.equal(tracker.isTargetWindowFocused(), false);
|
||||
assert.equal(tracker.getGeometry(), null);
|
||||
assert.deepEqual(focusChanges, [true, false]);
|
||||
});
|
||||
|
||||
test('MacOSWindowTracker keeps previously focused target through repeated helper execution failures', async () => {
|
||||
test('MacOSWindowTracker drops previously focused target after repeated helper execution failures exceed grace', async () => {
|
||||
let callIndex = 0;
|
||||
let now = 1_000;
|
||||
const focusChanges: boolean[] = [];
|
||||
@@ -323,15 +323,10 @@ test('MacOSWindowTracker keeps previously focused target through repeated helper
|
||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
assert.equal(tracker.isTracking(), true);
|
||||
assert.equal(tracker.isTargetWindowFocused(), true);
|
||||
assert.deepEqual(tracker.getGeometry(), {
|
||||
x: 10,
|
||||
y: 20,
|
||||
width: 1280,
|
||||
height: 720,
|
||||
});
|
||||
assert.deepEqual(focusChanges, [true]);
|
||||
assert.equal(tracker.isTracking(), false);
|
||||
assert.equal(tracker.isTargetWindowFocused(), false);
|
||||
assert.equal(tracker.getGeometry(), null);
|
||||
assert.deepEqual(focusChanges, [true, false]);
|
||||
});
|
||||
|
||||
test('MacOSWindowTracker marks target unfocused on explicit inactive helper signal', async () => {
|
||||
|
||||
@@ -394,8 +394,13 @@ export class MacOSWindowTracker extends BaseWindowTracker {
|
||||
|
||||
private registerTrackingMiss(graceMs = this.trackingLossGraceMs): void {
|
||||
if (this.shouldPreserveFocusedTargetOnMiss()) {
|
||||
this.resetTrackingLossState();
|
||||
return;
|
||||
if (this.trackingLossStartedAtMs === null) {
|
||||
this.trackingLossStartedAtMs = this.now();
|
||||
return;
|
||||
}
|
||||
if (this.now() - this.trackingLossStartedAtMs <= graceMs) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.consecutiveMisses += 1;
|
||||
|
||||
Reference in New Issue
Block a user