Skip to content

Commit 53e3e9e

Browse files
committed
Fixes microsoft#28237: Identify keyboard layouts where A-Z are missing or unusual and assume the standard mapping for KeyA - KeyZ
1 parent bf5b1db commit 53e3e9e

3 files changed

Lines changed: 105 additions & 111 deletions

File tree

src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts

Lines changed: 79 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ class ScanCodeCombo {
198198
);
199199
}
200200

201-
private getProducedCharCode(mapping: IScanCodeMapping): number {
201+
private getProducedCharCode(mapping: IMacLinuxKeyMapping): string {
202202
if (!mapping) {
203-
return 0;
203+
return '';
204204
}
205205
if (this.ctrlKey && this.shiftKey && this.altKey) {
206206
return mapping.withShiftAltGr;
@@ -214,8 +214,8 @@ class ScanCodeCombo {
214214
return mapping.value;
215215
}
216216

217-
public getProducedChar(mapping: IScanCodeMapping): string {
218-
const charCode = this.getProducedCharCode(mapping);
217+
public getProducedChar(mapping: IMacLinuxKeyMapping): string {
218+
const charCode = MacLinuxKeyboardMapper.getCharCode(this.getProducedCharCode(mapping));
219219
if (charCode === 0) {
220220
return ' --- ';
221221
}
@@ -444,7 +444,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
444444
/**
445445
* used only for debug purposes.
446446
*/
447-
private readonly _codeInfo: IScanCodeMapping[];
447+
private readonly _codeInfo: IMacLinuxKeyMapping[];
448448
/**
449449
* Maps ScanCode combos <-> KeyCode combos.
450450
*/
@@ -490,15 +490,6 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
490490
}
491491
};
492492

493-
let producesLetter: boolean[] = [];
494-
const _registerLetterIfMissing = (charCode: CharCode, scanCode: ScanCode, keyCode: KeyCode): void => {
495-
if (!producesLetter[charCode]) {
496-
_registerAllCombos(0, 0, 0, scanCode, keyCode);
497-
this._scanCodeToLabel[scanCode] = String.fromCharCode(charCode);
498-
}
499-
};
500-
501-
502493
// Initialize `_scanCodeToLabel`
503494
for (let scanCode = ScanCode.None; scanCode < ScanCode.MAX_VALUE; scanCode++) {
504495
this._scanCodeToLabel[scanCode] = null;
@@ -524,6 +515,72 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
524515
}
525516
}
526517

518+
// Try to identify keyboard layouts where characters A-Z are missing
519+
// and forcefully map them to their corresponding scan codes if that is the case
520+
const missingLatinLettersOverride: { [scanCode: string]: IMacLinuxKeyMapping; } = {};
521+
522+
{
523+
let producesLatinLetter: boolean[] = [];
524+
for (let strScanCode in rawMappings) {
525+
if (rawMappings.hasOwnProperty(strScanCode)) {
526+
const scanCode = ScanCodeUtils.toEnum(strScanCode);
527+
if (scanCode === ScanCode.None) {
528+
continue;
529+
}
530+
if (IMMUTABLE_CODE_TO_KEY_CODE[scanCode] !== -1) {
531+
continue;
532+
}
533+
534+
const rawMapping = rawMappings[strScanCode];
535+
const value = MacLinuxKeyboardMapper.getCharCode(rawMapping.value);
536+
537+
if (value >= CharCode.a && value <= CharCode.z) {
538+
const upperCaseValue = CharCode.A + (value - CharCode.a);
539+
producesLatinLetter[upperCaseValue] = true;
540+
}
541+
}
542+
}
543+
544+
const _registerLetterIfMissing = (charCode: CharCode, scanCode: ScanCode, value: string, withShift: string): void => {
545+
if (!producesLatinLetter[charCode]) {
546+
missingLatinLettersOverride[ScanCodeUtils.toString(scanCode)] = {
547+
value: value,
548+
withShift: withShift,
549+
withAltGr: '',
550+
withShiftAltGr: ''
551+
};
552+
}
553+
};
554+
555+
// Ensure letters are mapped
556+
_registerLetterIfMissing(CharCode.A, ScanCode.KeyA, 'a', 'A');
557+
_registerLetterIfMissing(CharCode.B, ScanCode.KeyB, 'b', 'B');
558+
_registerLetterIfMissing(CharCode.C, ScanCode.KeyC, 'c', 'C');
559+
_registerLetterIfMissing(CharCode.D, ScanCode.KeyD, 'd', 'D');
560+
_registerLetterIfMissing(CharCode.E, ScanCode.KeyE, 'e', 'E');
561+
_registerLetterIfMissing(CharCode.F, ScanCode.KeyF, 'f', 'F');
562+
_registerLetterIfMissing(CharCode.G, ScanCode.KeyG, 'g', 'G');
563+
_registerLetterIfMissing(CharCode.H, ScanCode.KeyH, 'h', 'H');
564+
_registerLetterIfMissing(CharCode.I, ScanCode.KeyI, 'i', 'I');
565+
_registerLetterIfMissing(CharCode.J, ScanCode.KeyJ, 'j', 'J');
566+
_registerLetterIfMissing(CharCode.K, ScanCode.KeyK, 'k', 'K');
567+
_registerLetterIfMissing(CharCode.L, ScanCode.KeyL, 'l', 'L');
568+
_registerLetterIfMissing(CharCode.M, ScanCode.KeyM, 'm', 'M');
569+
_registerLetterIfMissing(CharCode.N, ScanCode.KeyN, 'n', 'N');
570+
_registerLetterIfMissing(CharCode.O, ScanCode.KeyO, 'o', 'O');
571+
_registerLetterIfMissing(CharCode.P, ScanCode.KeyP, 'p', 'P');
572+
_registerLetterIfMissing(CharCode.Q, ScanCode.KeyQ, 'q', 'Q');
573+
_registerLetterIfMissing(CharCode.R, ScanCode.KeyR, 'r', 'R');
574+
_registerLetterIfMissing(CharCode.S, ScanCode.KeyS, 's', 'S');
575+
_registerLetterIfMissing(CharCode.T, ScanCode.KeyT, 't', 'T');
576+
_registerLetterIfMissing(CharCode.U, ScanCode.KeyU, 'u', 'U');
577+
_registerLetterIfMissing(CharCode.V, ScanCode.KeyV, 'v', 'V');
578+
_registerLetterIfMissing(CharCode.W, ScanCode.KeyW, 'w', 'W');
579+
_registerLetterIfMissing(CharCode.X, ScanCode.KeyX, 'x', 'X');
580+
_registerLetterIfMissing(CharCode.Y, ScanCode.KeyY, 'y', 'Y');
581+
_registerLetterIfMissing(CharCode.Z, ScanCode.KeyZ, 'z', 'Z');
582+
}
583+
527584
let mappings: IScanCodeMapping[] = [], mappingsLen = 0;
528585
for (let strScanCode in rawMappings) {
529586
if (rawMappings.hasOwnProperty(strScanCode)) {
@@ -535,11 +592,13 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
535592
continue;
536593
}
537594

538-
const rawMapping = rawMappings[strScanCode];
539-
const value = MacLinuxKeyboardMapper._getCharCode(rawMapping.value);
540-
const withShift = MacLinuxKeyboardMapper._getCharCode(rawMapping.withShift);
541-
const withAltGr = MacLinuxKeyboardMapper._getCharCode(rawMapping.withAltGr);
542-
const withShiftAltGr = MacLinuxKeyboardMapper._getCharCode(rawMapping.withShiftAltGr);
595+
this._codeInfo[scanCode] = rawMappings[strScanCode];
596+
597+
const rawMapping = missingLatinLettersOverride[strScanCode] || rawMappings[strScanCode];
598+
const value = MacLinuxKeyboardMapper.getCharCode(rawMapping.value);
599+
const withShift = MacLinuxKeyboardMapper.getCharCode(rawMapping.withShift);
600+
const withAltGr = MacLinuxKeyboardMapper.getCharCode(rawMapping.withAltGr);
601+
const withShiftAltGr = MacLinuxKeyboardMapper.getCharCode(rawMapping.withShiftAltGr);
543602

544603
const mapping: IScanCodeMapping = {
545604
scanCode: scanCode,
@@ -549,16 +608,13 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
549608
withShiftAltGr: withShiftAltGr,
550609
};
551610
mappings[mappingsLen++] = mapping;
552-
this._codeInfo[scanCode] = mapping;
553611

554612
this._scanCodeToDispatch[scanCode] = `[${ScanCodeUtils.toString(scanCode)}]`;
555613

556614
if (value >= CharCode.a && value <= CharCode.z) {
557615
const upperCaseValue = CharCode.A + (value - CharCode.a);
558-
producesLetter[upperCaseValue] = true;
559616
this._scanCodeToLabel[scanCode] = String.fromCharCode(upperCaseValue);
560617
} else if (value >= CharCode.A && value <= CharCode.Z) {
561-
producesLetter[value] = true;
562618
this._scanCodeToLabel[scanCode] = String.fromCharCode(value);
563619
} else if (value) {
564620
this._scanCodeToLabel[scanCode] = String.fromCharCode(value);
@@ -691,34 +747,6 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
691747
_registerAllCombos(0, 0, 0, ScanCode.Digit9, KeyCode.KEY_9);
692748
_registerAllCombos(0, 0, 0, ScanCode.Digit0, KeyCode.KEY_0);
693749

694-
// Ensure letters are mapped
695-
_registerLetterIfMissing(CharCode.A, ScanCode.KeyA, KeyCode.KEY_A);
696-
_registerLetterIfMissing(CharCode.B, ScanCode.KeyB, KeyCode.KEY_B);
697-
_registerLetterIfMissing(CharCode.C, ScanCode.KeyC, KeyCode.KEY_C);
698-
_registerLetterIfMissing(CharCode.D, ScanCode.KeyD, KeyCode.KEY_D);
699-
_registerLetterIfMissing(CharCode.E, ScanCode.KeyE, KeyCode.KEY_E);
700-
_registerLetterIfMissing(CharCode.F, ScanCode.KeyF, KeyCode.KEY_F);
701-
_registerLetterIfMissing(CharCode.G, ScanCode.KeyG, KeyCode.KEY_G);
702-
_registerLetterIfMissing(CharCode.H, ScanCode.KeyH, KeyCode.KEY_H);
703-
_registerLetterIfMissing(CharCode.I, ScanCode.KeyI, KeyCode.KEY_I);
704-
_registerLetterIfMissing(CharCode.J, ScanCode.KeyJ, KeyCode.KEY_J);
705-
_registerLetterIfMissing(CharCode.K, ScanCode.KeyK, KeyCode.KEY_K);
706-
_registerLetterIfMissing(CharCode.L, ScanCode.KeyL, KeyCode.KEY_L);
707-
_registerLetterIfMissing(CharCode.M, ScanCode.KeyM, KeyCode.KEY_M);
708-
_registerLetterIfMissing(CharCode.N, ScanCode.KeyN, KeyCode.KEY_N);
709-
_registerLetterIfMissing(CharCode.O, ScanCode.KeyO, KeyCode.KEY_O);
710-
_registerLetterIfMissing(CharCode.P, ScanCode.KeyP, KeyCode.KEY_P);
711-
_registerLetterIfMissing(CharCode.Q, ScanCode.KeyQ, KeyCode.KEY_Q);
712-
_registerLetterIfMissing(CharCode.R, ScanCode.KeyR, KeyCode.KEY_R);
713-
_registerLetterIfMissing(CharCode.S, ScanCode.KeyS, KeyCode.KEY_S);
714-
_registerLetterIfMissing(CharCode.T, ScanCode.KeyT, KeyCode.KEY_T);
715-
_registerLetterIfMissing(CharCode.U, ScanCode.KeyU, KeyCode.KEY_U);
716-
_registerLetterIfMissing(CharCode.V, ScanCode.KeyV, KeyCode.KEY_V);
717-
_registerLetterIfMissing(CharCode.W, ScanCode.KeyW, KeyCode.KEY_W);
718-
_registerLetterIfMissing(CharCode.X, ScanCode.KeyX, KeyCode.KEY_X);
719-
_registerLetterIfMissing(CharCode.Y, ScanCode.KeyY, KeyCode.KEY_Y);
720-
_registerLetterIfMissing(CharCode.Z, ScanCode.KeyZ, KeyCode.KEY_Z);
721-
722750
this._scanCodeKeyCodeMapper.registrationComplete();
723751
}
724752

@@ -1135,7 +1163,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
11351163
* To the brave person following me: Good Luck!
11361164
* https://www.compart.com/en/unicode/bidiclass/NSM
11371165
*/
1138-
private static _getCharCode(char: string): number {
1166+
public static getCharCode(char: string): number {
11391167
if (char.length === 0) {
11401168
return 0;
11411169
}

src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,14 +1488,6 @@ suite('keyboardMapper - MAC zh_hant', () => {
14881488
isWYSIWYG: true,
14891489
isChord: false,
14901490
dispatchParts: ['meta+[KeyC]', null],
1491-
}, {
1492-
label: '⌃⌥⌘C',
1493-
ariaLabel: 'Control+Alt+Command+C',
1494-
electronAccelerator: 'Ctrl+Alt+Cmd+C',
1495-
userSettingsLabel: 'ctrl+alt+cmd+c',
1496-
isWYSIWYG: true,
1497-
isChord: false,
1498-
dispatchParts: ['ctrl+alt+meta+[KeyC]', null],
14991491
}]
15001492
);
15011493
});

0 commit comments

Comments
 (0)