From 968da131589845b43c0d00141b41b2bb366a84e8 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 21 Mar 2017 15:11:20 +0100 Subject: [PATCH] Improve the ScanCode -> KeyCode guessing strategy --- .../common/macLinuxKeyboardMapper.ts | 83 ++++++++----------- .../services/keybinding/test/linux_de_ch.txt | 32 +++---- .../test/macLinuxKeyboardMapper.test.ts | 27 ++++++ .../services/keybinding/test/mac_de_ch.txt | 16 ++-- 4 files changed, 87 insertions(+), 71 deletions(-) diff --git a/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts b/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts index 4c1dfcc35a3..0d13fae754a 100644 --- a/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts +++ b/src/vs/workbench/services/keybinding/common/macLinuxKeyboardMapper.ts @@ -333,6 +333,40 @@ class ScanCodeKeyCodeMapper { return result; } + public guessStableKeyCode(scanCode: ScanCode): KeyCode { + if (scanCode >= ScanCode.Digit1 && scanCode <= ScanCode.Digit0) { + // digits are ok + switch (scanCode) { + case ScanCode.Digit1: return KeyCode.KEY_1; + case ScanCode.Digit2: return KeyCode.KEY_2; + case ScanCode.Digit3: return KeyCode.KEY_3; + case ScanCode.Digit4: return KeyCode.KEY_4; + case ScanCode.Digit5: return KeyCode.KEY_5; + case ScanCode.Digit6: return KeyCode.KEY_6; + case ScanCode.Digit7: return KeyCode.KEY_7; + case ScanCode.Digit8: return KeyCode.KEY_8; + case ScanCode.Digit9: return KeyCode.KEY_9; + case ScanCode.Digit0: return KeyCode.KEY_0; + } + } + + // Lookup the scanCode with and without shift and see if the keyCode is stable + const keyCodeCombos1 = this.lookupScanCodeCombo(new ScanCodeCombo(false, false, false, scanCode)); + const keyCodeCombos2 = this.lookupScanCodeCombo(new ScanCodeCombo(false, true, false, scanCode)); + if (keyCodeCombos1.length === 1 && keyCodeCombos2.length === 1) { + const shiftKey1 = keyCodeCombos1[0].shiftKey; + const keyCode1 = keyCodeCombos1[0].keyCode; + const shiftKey2 = keyCodeCombos2[0].shiftKey; + const keyCode2 = keyCodeCombos2[0].keyCode; + if (keyCode1 === keyCode2 && shiftKey1 !== shiftKey2) { + // This looks like a stable mapping + return keyCode1; + } + } + + return -1; + } + private _encodeScanCodeCombo(scanCodeCombo: ScanCodeCombo): number { return this._encode(scanCodeCombo.ctrlKey, scanCodeCombo.shiftKey, scanCodeCombo.altKey, scanCodeCombo.scanCode); } @@ -720,7 +754,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper { } // Check if this scanCode always maps to the same keyCode and back - let constantKeyCode: KeyCode = this._getStableKeyCodeForHWCode(scanCode); + let constantKeyCode: KeyCode = this._scanCodeKeyCodeMapper.guessStableKeyCode(scanCode); if (constantKeyCode !== -1) { return USER_SETTINGS.fromKeyCode(constantKeyCode).toLowerCase(); } @@ -756,7 +790,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper { } // Check if this scanCode always maps to the same keyCode and back - let constantKeyCode: KeyCode = this._getStableKeyCodeForHWCode(scanCode); + let constantKeyCode: KeyCode = this._scanCodeKeyCodeMapper.guessStableKeyCode(scanCode); if (constantKeyCode !== -1) { return this._getElectronLabelForKeyCode(constantKeyCode); } @@ -764,51 +798,6 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper { return null; } - private _getStableKeyCodeForHWCode(scanCode: ScanCode): KeyCode { - if (scanCode >= ScanCode.Digit1 && scanCode <= ScanCode.Digit0) { - // digits are ok - switch (scanCode) { - case ScanCode.Digit1: return KeyCode.KEY_1; - case ScanCode.Digit2: return KeyCode.KEY_2; - case ScanCode.Digit3: return KeyCode.KEY_3; - case ScanCode.Digit4: return KeyCode.KEY_4; - case ScanCode.Digit5: return KeyCode.KEY_5; - case ScanCode.Digit6: return KeyCode.KEY_6; - case ScanCode.Digit7: return KeyCode.KEY_7; - case ScanCode.Digit8: return KeyCode.KEY_8; - case ScanCode.Digit9: return KeyCode.KEY_9; - case ScanCode.Digit0: return KeyCode.KEY_0; - } - } - - // Check if this scanCode always maps to the same keyCode and back - let constantKeyCode: KeyCode = -1; - for (let mod = 0; mod < 8; mod++) { - const hwCtrlKey = (mod & 0b001) ? true : false; - const hwShiftKey = (mod & 0b010) ? true : false; - const hwAltKey = (mod & 0b100) ? true : false; - const hwCombo = new ScanCodeCombo(hwCtrlKey, hwShiftKey, hwAltKey, scanCode); - - const kbCombos = this._scanCodeKeyCodeMapper.lookupScanCodeCombo(hwCombo); - if (kbCombos.length === 0) { - // maps to unknown keyCode - return -1; - } - for (let i = 0, len = kbCombos.length; i < len; i++) { - const kbCombo = kbCombos[i]; - - if (constantKeyCode === -1) { - constantKeyCode = kbCombo.keyCode; - } else if (constantKeyCode !== kbCombo.keyCode) { - // maps to different keyCode - return -1; - } - } - } - - return constantKeyCode; - } - public resolveKeybinding(keybinding: Keybinding): NativeResolvedKeybinding[] { let result: NativeResolvedKeybinding[] = [], resultLen = 0; diff --git a/src/vs/workbench/services/keybinding/test/linux_de_ch.txt b/src/vs/workbench/services/keybinding/test/linux_de_ch.txt index 7ef9d7527e4..1ec63d43a4e 100644 --- a/src/vs/workbench/services/keybinding/test/linux_de_ch.txt +++ b/src/vs/workbench/services/keybinding/test/linux_de_ch.txt @@ -218,14 +218,14 @@ | Shift+Alt+KeyW | W | Shift+Alt+W | Shift+Alt+W | shift+alt+w | Shift+Alt+W | shift+alt+[KeyW] | | Ctrl+Shift+Alt+KeyW | Ł | Ctrl+Shift+Alt+W | Ctrl+Shift+Alt+W | ctrl+shift+alt+w | Ctrl+Shift+Alt+W | ctrl+shift+alt+[KeyW] | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -| KeyX | x | X | X | [KeyX] | null | [KeyX] | -| Ctrl+KeyX | x | Ctrl+X | Ctrl+X | ctrl+[KeyX] | null | ctrl+[KeyX] | -| Shift+KeyX | X | Shift+X | Shift+X | shift+[KeyX] | null | shift+[KeyX] | -| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | Ctrl+Shift+X | ctrl+shift+[KeyX] | null | ctrl+shift+[KeyX] | -| Alt+KeyX | x | Alt+X | Alt+X | alt+[KeyX] | null | alt+[KeyX] | -| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+[KeyX] | null | ctrl+alt+[KeyX] | -| Shift+Alt+KeyX | X | Shift+Alt+X | Shift+Alt+X | shift+alt+[KeyX] | null | shift+alt+[KeyX] | -| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | null | ctrl+shift+alt+[KeyX] | +| KeyX | x | X | X | x | X | [KeyX] | +| Ctrl+KeyX | x | Ctrl+X | Ctrl+X | ctrl+x | Ctrl+X | ctrl+[KeyX] | +| Shift+KeyX | X | Shift+X | Shift+X | shift+x | Shift+X | shift+[KeyX] | +| Ctrl+Shift+KeyX | X | Ctrl+Shift+X | Ctrl+Shift+X | ctrl+shift+x | Ctrl+Shift+X | ctrl+shift+[KeyX] | +| Alt+KeyX | x | Alt+X | Alt+X | alt+x | Alt+X | alt+[KeyX] | +| Ctrl+Alt+KeyX | » | Ctrl+Alt+X | Ctrl+Alt+X | ctrl+alt+x | Ctrl+Alt+X | ctrl+alt+[KeyX] | +| Shift+Alt+KeyX | X | Shift+Alt+X | Shift+Alt+X | shift+alt+x | Shift+Alt+X | shift+alt+[KeyX] | +| Ctrl+Shift+Alt+KeyX | > | Ctrl+Shift+Alt+X | Ctrl+Shift+Alt+X | ctrl+shift+alt+x | Ctrl+Shift+Alt+X | ctrl+shift+alt+[KeyX] | | | | Shift+. | | | | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | HW Code combination | Key | KeyCode combination | UI label | User settings | Electron accelerator | Dispatching string | @@ -239,14 +239,14 @@ | Shift+Alt+KeyY | Z | Shift+Alt+Z | Shift+Alt+Z | shift+alt+z | Shift+Alt+Z | shift+alt+[KeyY] | | Ctrl+Shift+Alt+KeyY | ¥ | Ctrl+Shift+Alt+Z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+z | Ctrl+Shift+Alt+Z | ctrl+shift+alt+[KeyY] | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -| KeyZ | y | Y | Y | [KeyZ] | null | [KeyZ] | -| Ctrl+KeyZ | y | Ctrl+Y | Ctrl+Y | ctrl+[KeyZ] | null | ctrl+[KeyZ] | -| Shift+KeyZ | Y | Shift+Y | Shift+Y | shift+[KeyZ] | null | shift+[KeyZ] | -| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | null | ctrl+shift+[KeyZ] | -| Alt+KeyZ | y | Alt+Y | Alt+Y | alt+[KeyZ] | null | alt+[KeyZ] | -| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | null | ctrl+alt+[KeyZ] | -| Shift+Alt+KeyZ | Y | Shift+Alt+Y | Shift+Alt+Y | shift+alt+[KeyZ] | null | shift+alt+[KeyZ] | -| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | null | ctrl+shift+alt+[KeyZ] | +| KeyZ | y | Y | Y | y | Y | [KeyZ] | +| Ctrl+KeyZ | y | Ctrl+Y | Ctrl+Y | ctrl+y | Ctrl+Y | ctrl+[KeyZ] | +| Shift+KeyZ | Y | Shift+Y | Shift+Y | shift+y | Shift+Y | shift+[KeyZ] | +| Ctrl+Shift+KeyZ | Y | Ctrl+Shift+Y | Ctrl+Shift+Y | ctrl+shift+y | Ctrl+Shift+Y | ctrl+shift+[KeyZ] | +| Alt+KeyZ | y | Alt+Y | Alt+Y | alt+y | Alt+Y | alt+[KeyZ] | +| Ctrl+Alt+KeyZ | « | Ctrl+Alt+Y | Ctrl+Alt+Y | ctrl+alt+y | Ctrl+Alt+Y | ctrl+alt+[KeyZ] | +| Shift+Alt+KeyZ | Y | Shift+Alt+Y | Shift+Alt+Y | shift+alt+y | Shift+Alt+Y | shift+alt+[KeyZ] | +| Ctrl+Shift+Alt+KeyZ | < | Ctrl+Shift+Alt+Y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+y | Ctrl+Shift+Alt+Y | ctrl+shift+alt+[KeyZ] | | | | Shift+, | | | | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | Digit1 | 1 | 1 | 1 | 1 | 1 | [Digit1] | diff --git a/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts index 7c4f1cc2b97..97bee1e267d 100644 --- a/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/macLinuxKeyboardMapper.test.ts @@ -703,6 +703,33 @@ suite('keyboardMapper - LINUX de_ch', () => { } ); }); + + test('resolveKeyboardEvent Ctrl+[KeyX]', () => { + assertResolveKeyboardEvent( + mapper, + { + ctrlKey: true, + shiftKey: false, + altKey: false, + metaKey: false, + keyCode: -1, + code: 'KeyX' + }, + { + label: 'Ctrl+X', + ariaLabel: 'Control+X', + HTMLLabel: [_simpleHTMLLabel(['Ctrl', 'X'])], + electronAccelerator: 'Ctrl+X', + userSettingsLabel: 'ctrl+x', + isChord: false, + hasCtrlModifier: true, + hasShiftModifier: false, + hasAltModifier: false, + hasMetaModifier: false, + dispatchParts: ['ctrl+[KeyX]', null], + } + ); + }); }); suite('keyboardMapper - LINUX en_us', () => { diff --git a/src/vs/workbench/services/keybinding/test/mac_de_ch.txt b/src/vs/workbench/services/keybinding/test/mac_de_ch.txt index 88f06fd2010..3477b41b31f 100644 --- a/src/vs/workbench/services/keybinding/test/mac_de_ch.txt +++ b/src/vs/workbench/services/keybinding/test/mac_de_ch.txt @@ -124,15 +124,15 @@ | Shift+Alt+KeyM | M | Shift+Alt+M | Shift+Alt+M | shift+alt+m | Shift+Alt+M | shift+alt+[KeyM] | | Ctrl+Shift+Alt+KeyM | ˚ | Ctrl+Shift+Alt+M | Ctrl+Shift+Alt+M | ctrl+shift+alt+m | Ctrl+Shift+Alt+M | ctrl+shift+alt+[KeyM] | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -| KeyN | n | N | N | [KeyN] | null | [KeyN] | -| Ctrl+KeyN | n | Ctrl+N | Ctrl+N | ctrl+[KeyN] | null | ctrl+[KeyN] | -| Shift+KeyN | N | Shift+N | Shift+N | shift+[KeyN] | null | shift+[KeyN] | -| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | Ctrl+Shift+N | ctrl+shift+[KeyN] | null | ctrl+shift+[KeyN] | -| Alt+KeyN | n | Alt+N | Alt+N | alt+[KeyN] | null | alt+[KeyN] | -| Ctrl+Alt+KeyN | ~ | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+[KeyN] | null | ctrl+alt+[KeyN] | +| KeyN | n | N | N | n | N | [KeyN] | +| Ctrl+KeyN | n | Ctrl+N | Ctrl+N | ctrl+n | Ctrl+N | ctrl+[KeyN] | +| Shift+KeyN | N | Shift+N | Shift+N | shift+n | Shift+N | shift+[KeyN] | +| Ctrl+Shift+KeyN | N | Ctrl+Shift+N | Ctrl+Shift+N | ctrl+shift+n | Ctrl+Shift+N | ctrl+shift+[KeyN] | +| Alt+KeyN | n | Alt+N | Alt+N | alt+n | Alt+N | alt+[KeyN] | +| Ctrl+Alt+KeyN | ~ | Ctrl+Alt+N | Ctrl+Alt+N | ctrl+alt+n | Ctrl+Alt+N | ctrl+alt+[KeyN] | | | | Shift+` | | | | | -| Shift+Alt+KeyN | N | Shift+Alt+N | Shift+Alt+N | shift+alt+[KeyN] | null | shift+alt+[KeyN] | -| Ctrl+Shift+Alt+KeyN | ˙ | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | null | ctrl+shift+alt+[KeyN] | +| Shift+Alt+KeyN | N | Shift+Alt+N | Shift+Alt+N | shift+alt+n | Shift+Alt+N | shift+alt+[KeyN] | +| Ctrl+Shift+Alt+KeyN | ˙ | Ctrl+Shift+Alt+N | Ctrl+Shift+Alt+N | ctrl+shift+alt+n | Ctrl+Shift+Alt+N | ctrl+shift+alt+[KeyN] | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | KeyO | o | O | O | o | O | [KeyO] | | Ctrl+KeyO | o | Ctrl+O | Ctrl+O | ctrl+o | Ctrl+O | ctrl+[KeyO] | -- GitLab