Add back red circle to windows
This commit is contained in:
+22
-10
@@ -1706,20 +1706,32 @@ public static class SFHook {
|
||||
* scaled away from 100% and on secondary monitors.
|
||||
*/
|
||||
osPointToDip(osPoint) {
|
||||
if (this.screen && typeof this.screen.screenToDipPoint === 'function') {
|
||||
try {
|
||||
const dip = this.screen.screenToDipPoint(osPoint);
|
||||
if (dip && Number.isFinite(dip.x) && Number.isFinite(dip.y)) return dip;
|
||||
} catch { /* fall through to manual conversion */ }
|
||||
}
|
||||
let geometryDip = null;
|
||||
try {
|
||||
const displays = this.screen && typeof this.screen.getAllDisplays === 'function'
|
||||
? this.screen.getAllDisplays()
|
||||
: [];
|
||||
const dip = physicalToDip(osPoint, displays);
|
||||
if (dip) return dip;
|
||||
} catch { /* no display geometry available */ }
|
||||
return osPoint;
|
||||
geometryDip = physicalToDip(osPoint, displays);
|
||||
} catch {
|
||||
geometryDip = null;
|
||||
}
|
||||
if (this.screen && typeof this.screen.screenToDipPoint === 'function') {
|
||||
try {
|
||||
const dip = this.screen.screenToDipPoint(osPoint);
|
||||
if (dip && Number.isFinite(dip.x) && Number.isFinite(dip.y)) {
|
||||
if (!geometryDip) return dip;
|
||||
const offByX = Math.abs(dip.x - geometryDip.x);
|
||||
const offByY = Math.abs(dip.y - geometryDip.y);
|
||||
// Some Windows/Electron combinations have been observed to return a
|
||||
// raw physical point here. That keeps the click marker off-screen on
|
||||
// scaled displays, so trust the geometry path when the two disagree
|
||||
// by more than a tiny rounding margin.
|
||||
if (offByX <= 1 && offByY <= 1) return dip;
|
||||
return geometryDip;
|
||||
}
|
||||
} catch { /* fall through to manual conversion */ }
|
||||
}
|
||||
return geometryDip || osPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -736,6 +736,27 @@ test('hook coordinates are converted physical → DIP via screenToDipPoint when
|
||||
assert.deepEqual(seen, [{ x: 640, y: 320 }]);
|
||||
});
|
||||
|
||||
test('bogus Windows screenToDipPoint results fall back to display geometry', () => {
|
||||
const service = makeService({
|
||||
screenApi: {
|
||||
screenToDipPoint: (p) => ({ x: p.x, y: p.y }), // raw physical point: wrong on scaled displays
|
||||
getAllDisplays: () => [
|
||||
{ id: 1, scaleFactor: 2, bounds: { x: 0, y: 0, width: 1440, height: 900 } },
|
||||
],
|
||||
getCursorScreenPoint: () => { throw new Error('must not fall back to a cursor read'); },
|
||||
},
|
||||
});
|
||||
service.session = { guideId: 'guide-dip-fallback', paused: false, count: 0, intervalSec: 0 };
|
||||
const seen = [];
|
||||
service.enqueueClickCapture = (clickPos) => {
|
||||
seen.push(clickPos);
|
||||
};
|
||||
|
||||
service.onOsClick(1770000000000, { x: 1500, y: 900 }, 'left');
|
||||
|
||||
assert.deepEqual(seen, [{ x: 750, y: 450 }]);
|
||||
});
|
||||
|
||||
test('without screenToDipPoint, coordinates convert via display geometry (Linux/X11)', () => {
|
||||
const service = makeService({
|
||||
screenApi: {
|
||||
|
||||
Reference in New Issue
Block a user