fix(hotkeys): name the full combo when its key-up reaches us

The message could only cite the modifiers ("after Ctrl+Shift") because
Windows consumes the KEYDOWN of a combo it routed to another app. Its KEYUP
often still arrives though — when it does, report the exact combo the user
tried: "Ctrl+Shift+T is already used by another app".

Falls back to the modifiers-only wording when the key-up is swallowed too.
Can't misfire: an accepted combo ends the capture on keydown, so a non-modifier
key-up during capture means that key was swallowed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-25 18:40:08 +01:00
parent 6518b59860
commit f45a17d876
+15
View File
@@ -7812,6 +7812,21 @@ async function init() {
// the user staring at "Press combo…".
function onKeyUp(e) {
if (!heldMods) return;
// Windows consumes the KEYDOWN of a combo it routed elsewhere,
// but the KEYUP of the final key often still reaches us. When it
// does we can name the exact combo the user tried; otherwise we
// fall back to the modifiers below. This can only fire on a
// swallowed key — an accepted combo ends the capture on keydown.
const k = e.key || '';
const isMod = /^(Control|Shift|Alt|Meta|OS)$/.test(k);
if (!isMod &&
((k.length === 1 && /[a-z0-9]/i.test(k)) || /^F([1-9]|1[0-2])$/i.test(k))) {
const combo = heldMods + '+' + k.toUpperCase();
finish(true);
toast(combo + ' is already used by another app — the keystroke ' +
'never reaches us. Pick a different combo.', 'warning');
return;
}
if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) return;
const mods = heldMods;
finish(true);