From 620a18608e01b1b7dc75a61b05d3445cfee3afd8 Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Sun, 8 Nov 2026 13:27:51 -0800 Subject: [PATCH] fix(cockpit): only a ship's double-click remembers where it began The first press's picture of the track is there because a click on a selected ship re-centres the camera. It applied to followed aircraft too, widening their double-click hit area to wherever the aircraft was drawn as the gesture began. Aircraft are back to the hit where they are drawn. --- src/ui/cockpitBridge.test.mjs | 22 ++++++++++++++++++++++ src/ui/cockpitInput.js | 8 +++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ui/cockpitBridge.test.mjs b/src/ui/cockpitBridge.test.mjs index b73ff2a1f..05ece6b89 100644 --- a/src/ui/cockpitBridge.test.mjs +++ b/src/ui/cockpitBridge.test.mjs @@ -1415,6 +1415,28 @@ test('a fix the feed keeps re-serving goes on ageing into a stale feed', async ( assert.match($('#cockpit-aircraft-meta').textContent, /STALE FEED/); }); +test('a followed aircraft keeps its own double-click hit area', async (t) => { + const aircraftInfo = { + icao24: 'abc123', + callsign: 'TEST1', + latitude: 54.5, + longitude: 10.2, + altitudeM: 3000, + velocityMps: 200, + track: 45, + onGround: false, + }; + const { cockpit, viewer, aircraft } = fixture(t, { aircraftInfo }); + viewer.trackedEntity = aircraft; + heightSensitiveProjection(viewer); + // Drawn at (400, -2700) as the press begins, at (600, -2700) by the + // double-click: a click there is not on the aircraft. + cockpit.onScenePointerDown(1000); + heightSensitiveProjection(viewer, { x: 600 }); + assert.equal(cockpit.onSceneDoubleClick({ x: 400, y: -2700 }, 1250), false); + assert.equal(cockpit.active, false); +}); + test("a double-click's second press keeps the first press's picture of the ship", async (t) => { const { cockpit, viewer, store } = fixture(t); heightSensitiveProjection(viewer); diff --git a/src/ui/cockpitInput.js b/src/ui/cockpitInput.js index 227ccb4c7..1dd662007 100644 --- a/src/ui/cockpitInput.js +++ b/src/ui/cockpitInput.js @@ -65,7 +65,7 @@ function subjectCanvasPosition() { } /** - * Note where the followed track is drawn as a press begins, for a + * Note where the selected ship is drawn as a press begins, for a * double-click whose first click moves it. The second press of the gesture * keeps the first one's picture: by then the first click may have moved it. * @param {number} [nowMs] @@ -74,6 +74,12 @@ export function onScenePointerDown(nowMs = performance.now()) { if (this.active || this.destroyed) return; const start = this.doubleClickStart; if (start && nowMs - start.atMs <= DOUBLE_CLICK_MEMORY_MS) return; + // Only a ship moves under its own click (selecting it re-centres the + // camera); a followed aircraft stays put, so its hit area stays its own. + if (this.resolveEntryKind() !== 'vessel') { + this.doubleClickStart = null; + return; + } const at = subjectCanvasPosition.call(this); this.doubleClickStart = at ? { x: at.x, y: at.y, atMs: nowMs } : null; }