mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 12: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);
|
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 () => {
|
test('registerIpcHandlers runs AniList update after manual mark watched succeeds', async () => {
|
||||||
const { registrar, handlers } = createFakeIpcRegistrar();
|
const { registrar, handlers } = createFakeIpcRegistrar();
|
||||||
const calls: string[] = [];
|
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 callIndex = 0;
|
||||||
let now = 1_000;
|
let now = 1_000;
|
||||||
const focusChanges: boolean[] = [];
|
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: '10,20,1280,720,1', stderr: '' },
|
||||||
{ stdout: 'not-found', stderr: '' },
|
{ stdout: 'not-found', stderr: '' },
|
||||||
{ stdout: 'not-found', stderr: '' },
|
{ stdout: 'not-found', stderr: '' },
|
||||||
{ stdout: 'not-found', stderr: '' },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const tracker = new MacOSWindowTracker('/tmp/mpv.sock', {
|
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();
|
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
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.isTracking(), true);
|
||||||
assert.equal(tracker.isTargetWindowFocused(), true);
|
assert.equal(tracker.isTargetWindowFocused(), true);
|
||||||
assert.deepEqual(tracker.getGeometry(), {
|
assert.deepEqual(tracker.getGeometry(), {
|
||||||
@@ -286,9 +277,18 @@ test('MacOSWindowTracker keeps previously focused target through repeated not-fo
|
|||||||
height: 720,
|
height: 720,
|
||||||
});
|
});
|
||||||
assert.deepEqual(focusChanges, [true]);
|
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 callIndex = 0;
|
||||||
let now = 1_000;
|
let now = 1_000;
|
||||||
const focusChanges: boolean[] = [];
|
const focusChanges: boolean[] = [];
|
||||||
@@ -323,15 +323,10 @@ test('MacOSWindowTracker keeps previously focused target through repeated helper
|
|||||||
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
(tracker as unknown as { pollGeometry: () => void }).pollGeometry();
|
||||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
|
||||||
assert.equal(tracker.isTracking(), true);
|
assert.equal(tracker.isTracking(), false);
|
||||||
assert.equal(tracker.isTargetWindowFocused(), true);
|
assert.equal(tracker.isTargetWindowFocused(), false);
|
||||||
assert.deepEqual(tracker.getGeometry(), {
|
assert.equal(tracker.getGeometry(), null);
|
||||||
x: 10,
|
assert.deepEqual(focusChanges, [true, false]);
|
||||||
y: 20,
|
|
||||||
width: 1280,
|
|
||||||
height: 720,
|
|
||||||
});
|
|
||||||
assert.deepEqual(focusChanges, [true]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('MacOSWindowTracker marks target unfocused on explicit inactive helper signal', async () => {
|
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 {
|
private registerTrackingMiss(graceMs = this.trackingLossGraceMs): void {
|
||||||
if (this.shouldPreserveFocusedTargetOnMiss()) {
|
if (this.shouldPreserveFocusedTargetOnMiss()) {
|
||||||
this.resetTrackingLossState();
|
if (this.trackingLossStartedAtMs === null) {
|
||||||
return;
|
this.trackingLossStartedAtMs = this.now();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.now() - this.trackingLossStartedAtMs <= graceMs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.consecutiveMisses += 1;
|
this.consecutiveMisses += 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user