fix(app): restore Alt+letter shortcuts on macOS
The key matcher only consulted event.code when a binding explicitly opted in via codeFallback. macOS rewrites event.key whenever Option is held (Option+T -> "†", Option+[ -> "“", Option+Shift+W -> "„", etc.), so the comparison against combo.key always failed and every Alt-bound letter / bracket shortcut silently stopped firing on Mac: Cmd+Alt+T (cycle theme), Alt+Shift+[/], Alt+[/], Alt+Shift+W. Fall back to event.code when combo.alt is set. Keep the existing key-first behaviour for non-Alt bindings so Dvorak users still get logical-character matching (Cmd+V on physical Period keeps pasting instead of triggering Cmd+. for sidebar toggle).
This commit is contained in:
@@ -1020,6 +1020,24 @@ function parseDigit(event: KeyboardEvent): number | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function matchesKeyOrCode(combo: KeyCombo, event: KeyboardEvent): boolean {
|
||||
if (combo.key === undefined) {
|
||||
return event.code === combo.code;
|
||||
}
|
||||
const eventKey = event.key.toLowerCase();
|
||||
if (eventKey === combo.key) return true;
|
||||
if (combo.shift === true && combo.shiftedKey !== undefined && eventKey === combo.shiftedKey) {
|
||||
return true;
|
||||
}
|
||||
// macOS rewrites event.key when Option is held (Option+T -> "†",
|
||||
// Option+[ -> "“"), so Alt-bound letter / bracket bindings can only
|
||||
// match by event.code. Stay key-first for non-Alt bindings so Dvorak
|
||||
// keeps its logical-character matching (e.g. Cmd+V on physical Period
|
||||
// must paste, not trigger Cmd+.).
|
||||
if (combo.alt === true && event.code === combo.code) return true;
|
||||
return combo.codeFallback === true && event.code === combo.code;
|
||||
}
|
||||
|
||||
function matchesCombo(combo: KeyCombo, event: KeyboardEvent, isMac: boolean): boolean {
|
||||
if (combo.mod) {
|
||||
if (isMac) {
|
||||
@@ -1040,18 +1058,7 @@ function matchesCombo(combo: KeyCombo, event: KeyboardEvent, isMac: boolean): bo
|
||||
if (combo.code === "Digit") {
|
||||
return parseDigit(event) !== null;
|
||||
}
|
||||
|
||||
if (combo.key !== undefined) {
|
||||
const eventKey = event.key.toLowerCase();
|
||||
if (eventKey === combo.key) return true;
|
||||
if (combo.shift === true && combo.shiftedKey !== undefined && eventKey === combo.shiftedKey) {
|
||||
return true;
|
||||
}
|
||||
return combo.codeFallback === true && event.code === combo.code;
|
||||
}
|
||||
|
||||
const codeMatch = event.code === combo.code;
|
||||
return codeMatch;
|
||||
return matchesKeyOrCode(combo, event);
|
||||
}
|
||||
|
||||
function matchesWhen(when: ShortcutWhen | undefined, context: KeyboardShortcutContext): boolean {
|
||||
|
||||
Reference in New Issue
Block a user