From 1d476c87eeaf40c499b07ca03d6f48055aace242 Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Thu, 12 Nov 2026 18:02:41 -0800 Subject: [PATCH] fix(location): a POI key held with Cmd, Ctrl or Alt runs no POI The points-of-interest keys (Q/W/E/R/T while a city is expanded) are a second bare-key document listener, and it did not look at modifiers either: Alt+R or a delivered Ctrl+R picked the fourth POI and flew the camera there. It now leaves Cmd, Ctrl and Alt chords to the browser like the application shortcuts; Shift still counts as the key. The docs and the changelog entry say so. --- changelog.d/1691-shortcuts-ignore-modifier-chords.md | 3 ++- docs/CURRENT-STATE.md | 2 ++ src/ui/locationControls.js | 3 +++ src/ui/locationControls.test.mjs | 10 ++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/changelog.d/1691-shortcuts-ignore-modifier-chords.md b/changelog.d/1691-shortcuts-ignore-modifier-chords.md index 4a850507e..6bc84f8f8 100644 --- a/changelog.d/1691-shortcuts-ignore-modifier-chords.md +++ b/changelog.d/1691-shortcuts-ignore-modifier-chords.md @@ -1,4 +1,5 @@ - Leave browser and system chords alone: a shortcut key held with Cmd, Ctrl or Alt no longer runs its single-key shortcut. Copying with Cmd+C or Ctrl+C used to turn the CCTV layer on and open the nearest camera, Cmd+F opened the layers - panel and Cmd+1 to 6 changed the visual style (asturksever, #1691). + panel and Cmd+1 to 6 changed the visual style. The Q/W/E/R/T keys of an + expanded city's points of interest follow the same rule (asturksever, #1691). diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 0e4b03194..6b9628030 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -2329,6 +2329,8 @@ typing and Escape behavior retain their existing mappings. A shortcut key held with Cmd, Ctrl or Alt runs no shortcut, so the browser's own chord (Cmd+C to copy, Cmd+F to find, Cmd+1 to switch tab) does not also toggle CCTV, the layers panel or a style; Shift does not count, and Escape dismisses search either way. +The Q/W/E/R/T keys of an expanded city's points of interest follow the same +rule. Capture-phase surfaces continue to arbitrate their own keyboard events first. The UI facade retains shader values, share-restore authority, render requests, diff --git a/src/ui/locationControls.js b/src/ui/locationControls.js index 6fd827788..388fb51e1 100644 --- a/src/ui/locationControls.js +++ b/src/ui/locationControls.js @@ -88,6 +88,9 @@ export class LocationControls { event.target === elements.search ) return; + // As for the application shortcuts: Cmd+R, Ctrl+W, Alt+E and the like + // belong to the browser and the system. Shift is not a chord. + if (event.metaKey || event.ctrlKey || event.altKey) return; const index = POI_KEYS.indexOf(event.key.toUpperCase()); if (index !== -1 && index < (cities[cityId]?.pois.length || 0)) onPoi(cityId, index); diff --git a/src/ui/locationControls.test.mjs b/src/ui/locationControls.test.mjs index ccae6454b..2863564c8 100644 --- a/src/ui/locationControls.test.mjs +++ b/src/ui/locationControls.test.mjs @@ -191,6 +191,16 @@ test('location and POI keys route once while form controls retain typing', () => f.controls.reset(); assert.deepEqual(f.calls, [['poi', 'a', 1], ['reset']]); }); +test('POI keys held with Cmd, Ctrl or Alt run no POI; Shift still does', () => { + const f = fixture(); + const target = { matches: () => false }; + for (const modifier of ['metaKey', 'ctrlKey', 'altKey']) + for (const key of ['q', 'w', 'r', 'R']) + f.doc.fire('keydown', { key, target, [modifier]: true }); + assert.deepEqual(f.calls, []); + f.doc.fire('keydown', { key: 'W', target, shiftKey: true }); + assert.deepEqual(f.calls, [['poi', 'a', 1]]); +}); test('typing clears a failed search error and closing the emptied field drops it too', () => { const f = fixture(); f.elements.search.value = 'Pariss';