From 54dbf09d41a5bc861f50945af0689881bbbae265 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 18 Mar 2017 12:23:31 +0100 Subject: [PATCH] Remove PrintableKeypress --- .../keybinding/common/keybindingLabels.ts | 103 +++++------- .../common/usLayoutResolvedKeybinding.ts | 102 ++++++----- .../keybinding/common/keyboardMapper.ts | 56 ++---- .../electron-browser/keybindingService.ts | 159 ++++++++++++------ .../electron-browser/nativeKeymap.ts | 48 +----- .../keybinding/test/keyboardMapper.test.ts | 18 +- 6 files changed, 207 insertions(+), 279 deletions(-) diff --git a/src/vs/platform/keybinding/common/keybindingLabels.ts b/src/vs/platform/keybinding/common/keybindingLabels.ts index 0fdca41021d..13517be75ec 100644 --- a/src/vs/platform/keybinding/common/keybindingLabels.ts +++ b/src/vs/platform/keybinding/common/keybindingLabels.ts @@ -8,44 +8,6 @@ import * as nls from 'vs/nls'; import { OperatingSystem } from 'vs/base/common/platform'; import { IHTMLContentElement } from 'vs/base/common/htmlContent'; -import { KeyCode, Keybinding, KeybindingType, SimpleKeybinding } from 'vs/base/common/keyCodes'; - -export interface IKeyCodeLabelProvider { - (keyCode: KeyCode, OS: OperatingSystem): string; -} - -export class PrintableKeypress { - - private static _fromSimpleKeybinding(k: SimpleKeybinding, labelProvider: IKeyCodeLabelProvider, OS: OperatingSystem): PrintableKeypress { - const keyLabel = labelProvider(k.keyCode, OS) || ''; - return new PrintableKeypress(k.ctrlKey, k.shiftKey, k.altKey, k.metaKey, keyLabel); - } - - public static fromKeybinding(keybinding: Keybinding, labelProvider: IKeyCodeLabelProvider, OS: OperatingSystem): [PrintableKeypress, PrintableKeypress] { - if (keybinding.type === KeybindingType.Chord) { - const firstPart = PrintableKeypress._fromSimpleKeybinding(keybinding.firstPart, labelProvider, OS); - const chordPart = PrintableKeypress._fromSimpleKeybinding(keybinding.chordPart, labelProvider, OS); - return [firstPart, chordPart]; - } else { - const printableKeypress = PrintableKeypress._fromSimpleKeybinding(keybinding, labelProvider, OS); - return [printableKeypress, null]; - } - } - - readonly ctrlKey: boolean; - readonly shiftKey: boolean; - readonly altKey: boolean; - readonly metaKey: boolean; - readonly key: string; - - constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, key: string) { - this.ctrlKey = ctrlKey; - this.shiftKey = shiftKey; - this.altKey = altKey; - this.metaKey = metaKey; - this.key = key; - } -} export interface ModifierLabels { readonly ctrlKey: string; @@ -55,6 +17,13 @@ export interface ModifierLabels { readonly separator: string; } +export interface Modifiers { + readonly ctrlKey: boolean; + readonly shiftKey: boolean; + readonly altKey: boolean; + readonly metaKey: boolean; +} + export class ModifierLabelProvider { private readonly _labels: ModifierLabels[]; @@ -66,12 +35,18 @@ export class ModifierLabelProvider { this._labels[OperatingSystem.Linux] = linux; } - public toLabel2(firstPart: PrintableKeypress, chordPart: PrintableKeypress, OS: OperatingSystem): string { - return _asString(firstPart, chordPart, this._labels[OS]); + public toLabel(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, OS: OperatingSystem): string { + if (!firstPartKey && !chordPartKey) { + return null; + } + return _asString(firstPartMod, firstPartKey, chordPartMod, chordPartKey, this._labels[OS]); } - public toHTMLLabel2(firstPart: PrintableKeypress, chordPart: PrintableKeypress, OS: OperatingSystem): IHTMLContentElement[] { - return _asHTML(firstPart, chordPart, this._labels[OS]); + public toHTMLLabel(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, OS: OperatingSystem): IHTMLContentElement[] { + if (!firstPartKey && !chordPartKey) { + return null; + } + return _asHTML(firstPartMod, firstPartKey, chordPartMod, chordPartKey, this._labels[OS]); } } @@ -163,42 +138,42 @@ export const UserSettingsLabelProvider = new ModifierLabelProvider( } ); -function _simpleAsString(keypress: PrintableKeypress, labels: ModifierLabels): string { - if (!keypress.key) { +function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabels): string { + if (!key) { return ''; } let result: string[] = []; // translate modifier keys: Ctrl-Shift-Alt-Meta - if (keypress.ctrlKey) { + if (modifiers.ctrlKey) { result.push(labels.ctrlKey); } - if (keypress.shiftKey) { + if (modifiers.shiftKey) { result.push(labels.shiftKey); } - if (keypress.altKey) { + if (modifiers.altKey) { result.push(labels.altKey); } - if (keypress.metaKey) { + if (modifiers.metaKey) { result.push(labels.metaKey); } // the actual key - result.push(keypress.key); + result.push(key); return result.join(labels.separator); } -function _asString(firstPart: PrintableKeypress, chordPart: PrintableKeypress, labels: ModifierLabels): string { - let result = _simpleAsString(firstPart, labels); +function _asString(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, labels: ModifierLabels): string { + let result = _simpleAsString(firstPartMod, firstPartKey, labels); - if (chordPart !== null) { + if (chordPartKey) { result += ' '; - result += _simpleAsString(chordPart, labels); + result += _simpleAsString(chordPartMod, chordPartKey, labels); } return result; @@ -218,42 +193,42 @@ function _pushKey(result: IHTMLContentElement[], str: string, append: string): v } } -function _simpleAsHTML(result: IHTMLContentElement[], keypress: PrintableKeypress, labels: ModifierLabels): void { - if (!keypress.key) { +function _simpleAsHTML(result: IHTMLContentElement[], modifiers: Modifiers, key: string, labels: ModifierLabels): void { + if (!key) { return; } // translate modifier keys: Ctrl-Shift-Alt-Meta - if (keypress.ctrlKey) { + if (modifiers.ctrlKey) { _pushKey(result, labels.ctrlKey, labels.separator); } - if (keypress.shiftKey) { + if (modifiers.shiftKey) { _pushKey(result, labels.shiftKey, labels.separator); } - if (keypress.altKey) { + if (modifiers.altKey) { _pushKey(result, labels.altKey, labels.separator); } - if (keypress.metaKey) { + if (modifiers.metaKey) { _pushKey(result, labels.metaKey, labels.separator); } // the actual key - _pushKey(result, keypress.key, null); + _pushKey(result, key, null); } -function _asHTML(firstPart: PrintableKeypress, chordPart: PrintableKeypress, labels: ModifierLabels): IHTMLContentElement[] { +function _asHTML(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, labels: ModifierLabels): IHTMLContentElement[] { let result: IHTMLContentElement[] = []; - _simpleAsHTML(result, firstPart, labels); + _simpleAsHTML(result, firstPartMod, firstPartKey, labels); - if (chordPart !== null) { + if (chordPartKey) { result.push({ tagName: 'span', text: ' ' }); - _simpleAsHTML(result, chordPart, labels); + _simpleAsHTML(result, chordPartMod, chordPartKey, labels); } return [{ diff --git a/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts b/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts index 123ddaf6b41..b329601b107 100644 --- a/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts +++ b/src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts @@ -6,7 +6,7 @@ import { IHTMLContentElement } from 'vs/base/common/htmlContent'; import { ResolvedKeybinding, KeyCode, KeyCodeUtils, USER_SETTINGS, Keybinding, KeybindingType, SimpleKeybinding } from 'vs/base/common/keyCodes'; -import { PrintableKeypress, UILabelProvider, AriaLabelProvider, ElectronAcceleratorLabelProvider, UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; +import { UILabelProvider, AriaLabelProvider, ElectronAcceleratorLabelProvider, UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; import { OperatingSystem } from 'vs/base/common/platform'; /** @@ -14,17 +14,27 @@ import { OperatingSystem } from 'vs/base/common/platform'; */ export class USLayoutResolvedKeybinding extends ResolvedKeybinding { - private readonly _actual: Keybinding; private readonly _os: OperatingSystem; + private readonly _firstPart: SimpleKeybinding; + private readonly _chordPart: SimpleKeybinding; constructor(actual: Keybinding, OS: OperatingSystem) { super(); - this._actual = actual; this._os = OS; + if (actual === null) { + this._firstPart = null; + this._chordPart = null; + } else if (actual.type === KeybindingType.Chord) { + this._firstPart = actual.firstPart; + this._chordPart = actual.chordPart; + } else { + this._firstPart = actual; + this._chordPart = null; + } } - private static _usKeyCodeToUILabel(keyCode: KeyCode, OS: OperatingSystem): string { - if (OS === OperatingSystem.Macintosh) { + private _keyCodeToUILabel(keyCode: KeyCode): string { + if (this._os === OperatingSystem.Macintosh) { switch (keyCode) { case KeyCode.LeftArrow: return '←'; @@ -39,26 +49,30 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding { return KeyCodeUtils.toString(keyCode); } - private static _usKeyCodeToAriaLabel(keyCode: KeyCode, OS: OperatingSystem): string { - return KeyCodeUtils.toString(keyCode); - } - public getLabel(): string { - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, USLayoutResolvedKeybinding._usKeyCodeToUILabel, this._os); - return UILabelProvider.toLabel2(firstPart, chordPart, this._os); + let firstPart = this._firstPart ? this._keyCodeToUILabel(this._firstPart.keyCode) : null; + let chordPart = this._chordPart ? this._keyCodeToUILabel(this._chordPart.keyCode) : null; + return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os); } public getAriaLabel(): string { - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, USLayoutResolvedKeybinding._usKeyCodeToAriaLabel, this._os); - return AriaLabelProvider.toLabel2(firstPart, chordPart, this._os); + let firstPart = this._firstPart ? KeyCodeUtils.toString(this._firstPart.keyCode) : null; + let chordPart = this._chordPart ? KeyCodeUtils.toString(this._chordPart.keyCode) : null; + return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os); } public getHTMLLabel(): IHTMLContentElement[] { - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, USLayoutResolvedKeybinding._usKeyCodeToUILabel, this._os); - return UILabelProvider.toHTMLLabel2(firstPart, chordPart, this._os); + let firstPart = this._firstPart ? this._keyCodeToUILabel(this._firstPart.keyCode) : null; + let chordPart = this._chordPart ? this._keyCodeToUILabel(this._chordPart.keyCode) : null; + return UILabelProvider.toHTMLLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os); } - private static _usKeyCodeToElectronAccelerator(keyCode: KeyCode, OS: OperatingSystem): string { + private _keyCodeToElectronAccelerator(keyCode: KeyCode): string { + if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) { + // Electron cannot handle numpad keys + return null; + } + switch (keyCode) { case KeyCode.UpArrow: return 'Up'; @@ -74,78 +88,58 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding { } public getElectronAccelerator(): string { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart !== null) { // Electron cannot handle chords return null; } - let keyCode = this._actual.keyCode; - if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) { - // Electron cannot handle numpad keys - return null; - } - - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, USLayoutResolvedKeybinding._usKeyCodeToElectronAccelerator, this._os); - return ElectronAcceleratorLabelProvider.toLabel2(firstPart, chordPart, this._os); - } - - private static _usKeyCodeToUserSettings(keyCode: KeyCode, OS: OperatingSystem): string { - return USER_SETTINGS.fromKeyCode(keyCode); + let firstPart = this._firstPart ? this._keyCodeToElectronAccelerator(this._firstPart.keyCode) : null; + return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, this._os); } public getUserSettingsLabel(): string { - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, USLayoutResolvedKeybinding._usKeyCodeToUserSettings, this._os); - - let result = UserSettingsLabelProvider.toLabel2(firstPart, chordPart, this._os); + let firstPart = this._firstPart ? USER_SETTINGS.fromKeyCode(this._firstPart.keyCode) : null; + let chordPart = this._chordPart ? USER_SETTINGS.fromKeyCode(this._chordPart.keyCode) : null; + let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os); return result.toLowerCase(); } public isChord(): boolean { - return (this._actual.type === KeybindingType.Chord); + return (this._chordPart ? true : false); } public hasCtrlModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.ctrlKey; + return this._firstPart.ctrlKey; } public hasShiftModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.shiftKey; + return this._firstPart.shiftKey; } public hasAltModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.altKey; + return this._firstPart.altKey; } public hasMetaModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.metaKey; + return this._firstPart.metaKey; } public getDispatchParts(): [string, string] { - let keypressFirstPart: string; - let keypressChordPart: string; - if (this._actual === null) { - keypressFirstPart = null; - keypressChordPart = null; - } else if (this._actual.type === KeybindingType.Chord) { - keypressFirstPart = USLayoutResolvedKeybinding.getDispatchStr(this._actual.firstPart); - keypressChordPart = USLayoutResolvedKeybinding.getDispatchStr(this._actual.chordPart); - } else { - keypressFirstPart = USLayoutResolvedKeybinding.getDispatchStr(this._actual); - keypressChordPart = null; - } - return [keypressFirstPart, keypressChordPart]; + let firstPart = this._firstPart ? USLayoutResolvedKeybinding.getDispatchStr(this._firstPart) : null; + let chordPart = this._chordPart ? USLayoutResolvedKeybinding.getDispatchStr(this._chordPart) : null; + return [firstPart, chordPart]; } public static getDispatchStr(keybinding: SimpleKeybinding): string { diff --git a/src/vs/workbench/services/keybinding/common/keyboardMapper.ts b/src/vs/workbench/services/keybinding/common/keyboardMapper.ts index 4a4f61c6935..c65b7239ae5 100644 --- a/src/vs/workbench/services/keybinding/common/keyboardMapper.ts +++ b/src/vs/workbench/services/keybinding/common/keyboardMapper.ts @@ -10,7 +10,7 @@ import { KeyCode, ResolvedKeybinding, KeyCodeUtils, SimpleKeybinding, Keybinding import { KeyboardEventCode, KeyboardEventCodeUtils, IMMUTABLE_CODE_TO_KEY_CODE } from 'vs/workbench/services/keybinding/common/keyboardEventCode'; import { CharCode } from 'vs/base/common/charCode'; import { IHTMLContentElement } from 'vs/base/common/htmlContent'; -import { PrintableKeypress, UILabelProvider, AriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; +import { UILabelProvider, AriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; export interface IKeyMapping { value: string; @@ -51,10 +51,6 @@ export class HardwareKeypress { this.metaKey = metaKey; this.code = code; } - - public toPrintableKeypress(key: string): PrintableKeypress { - return new PrintableKeypress(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key); - } } export class NativeResolvedKeybinding extends ResolvedKeybinding { @@ -73,24 +69,21 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding { } public getLabel(): string { - let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._firstPart.code)); - let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._chordPart.code)) : null; - - return UILabelProvider.toLabel2(firstPart, chordPart, this._OS); + let firstPart = this._firstPart ? this._mapper.getUILabelForHardwareCode(this._firstPart.code) : null; + let chordPart = this._chordPart ? this._mapper.getUILabelForHardwareCode(this._chordPart.code) : null; + return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS); } public getAriaLabel(): string { - let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getAriaLabelForHardwareCode(this._firstPart.code)); - let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getAriaLabelForHardwareCode(this._chordPart.code)) : null; - - return AriaLabelProvider.toLabel2(firstPart, chordPart, this._OS); + let firstPart = this._firstPart ? this._mapper.getAriaLabelForHardwareCode(this._firstPart.code) : null; + let chordPart = this._chordPart ? this._mapper.getAriaLabelForHardwareCode(this._chordPart.code) : null; + return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS); } public getHTMLLabel(): IHTMLContentElement[] { - let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._firstPart.code)); - let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._chordPart.code)) : null; - - return UILabelProvider.toHTMLLabel2(firstPart, chordPart, this._OS); + let firstPart = this._firstPart ? this._mapper.getUILabelForHardwareCode(this._firstPart.code) : null; + let chordPart = this._chordPart ? this._mapper.getUILabelForHardwareCode(this._chordPart.code) : null; + return UILabelProvider.toHTMLLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS); } public getElectronAccelerator(): string { @@ -385,7 +378,7 @@ export class KeyboardMapper { } } - private _registerAllCombos( + private _registerAllCombos2( hwCtrlKey: boolean, hwShiftKey: boolean, hwAltKey: boolean, code: KeyboardEventCode, kbShiftKey: boolean, keyCode: KeyCode, ): void { @@ -438,7 +431,7 @@ export class KeyboardMapper { return; } - this._registerAllCombos( + this._registerAllCombos2( ctrlKey, shiftKey, altKey, code, kb.shiftKey, kb.keyCode ); @@ -457,16 +450,6 @@ export class KeyboardMapper { return result; } - public hardwareKeypressToSimpleKeybinding(keypress: HardwareKeypress): SimpleKeybinding { - const hwEncoded = this._encode(keypress.ctrlKey, keypress.shiftKey, keypress.altKey, keypress.code); - const kbEncoded = this._hwToKb[hwEncoded]; - if (!kbEncoded) { - return null; - } - - return this._decodeKb(kbEncoded, keypress.metaKey); - } - public getUILabelForHardwareCode(code: KeyboardEventCode): string { if (this._OS === OperatingSystem.Macintosh) { switch (code) { @@ -566,21 +549,6 @@ export class KeyboardMapper { return new HardwareKeypress(ctrlKey, shiftKey, altKey, metaKey, code); } - - private _decodeKb(kbEncoded: number, metaKey: boolean): SimpleKeybinding { - const ctrlKey = (kbEncoded & 0b001) ? true : false; - const shiftKey = (kbEncoded & 0b010) ? true : false; - const altKey = (kbEncoded & 0b100) ? true : false; - const keyCode = (kbEncoded >>> 3); - - return new SimpleKeybinding( - ctrlKey, - shiftKey, - altKey, - metaKey, - keyCode - ); - } } (function () { diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index bacaf2172b8..3768c28c8ae 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -8,13 +8,12 @@ import * as nls from 'vs/nls'; import { IHTMLContentElement } from 'vs/base/common/htmlContent'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { ResolvedKeybinding, KeyCode, USER_SETTINGS, Keybinding, KeybindingType, SimpleKeybinding, KeyCodeUtils } from 'vs/base/common/keyCodes'; -import { PrintableKeypress, UILabelProvider, AriaLabelProvider, UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; +import { UILabelProvider, AriaLabelProvider, UserSettingsLabelProvider, ElectronAcceleratorLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; import { OS, OperatingSystem } from 'vs/base/common/platform'; import { toDisposable } from 'vs/base/common/lifecycle'; import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry'; import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService'; -import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -24,7 +23,7 @@ import { IKeybindingRule, IKeybindingItem, KeybindingsRegistry } from 'vs/platfo import { Registry } from 'vs/platform/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { keybindingsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; -import { getCurrentKeyboardLayout, getNativeUIKeyCodeLabelProvider, getNativeAriaKeyCodeLabelProvider } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymap'; +import { getCurrentKeyboardLayout, getNativeLabelProviderRemaps } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymap'; import { IMessageService } from 'vs/platform/message/common/message'; import { ConfigWatcher } from 'vs/base/node/config'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -122,113 +121,163 @@ let keybindingsExtPoint = ExtensionsRegistry.registerExtensionPoint= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) { + // Electron cannot handle numpad keys + return null; + } - if (OS === OperatingSystem.Windows) { - // electron menus always do the correct rendering on Windows - return usResolvedKeybinding.getElectronAccelerator(); + switch (keyCode) { + case KeyCode.UpArrow: + return 'Up'; + case KeyCode.DownArrow: + return 'Down'; + case KeyCode.LeftArrow: + return 'Left'; + case KeyCode.RightArrow: + return 'Right'; } - let usLabel = usResolvedKeybinding.getLabel(); - let label = this.getLabel(); - if (usLabel !== label) { + let remaps = getNativeLabelProviderRemaps(); + + if (remaps[keyCode] === null) { + return KeyCodeUtils.toString(keyCode); + } + + let remapped = remaps[keyCode].render(); + if (OS === OperatingSystem.Windows) { + // electron menus always do the correct rendering on Windows + return remapped; + } else { // electron menus are incorrect in rendering (linux) and in rendering and interpreting (mac) // for non US standard keyboard layouts - return null; + if (remapped !== KeyCodeUtils.toString(keyCode)) { + return null; + } + return remapped; } - - return usResolvedKeybinding.getElectronAccelerator(); } - private static _usKeyCodeToUserSettings(keyCode: KeyCode, OS: OperatingSystem): string { - return USER_SETTINGS.fromKeyCode(keyCode); + public getElectronAccelerator(): string { + if (this._chordPart !== null) { + // Electron cannot handle chords + return null; + } + + let firstPart = this._firstPart ? this._keyCodeToElectronAccelerator(this._firstPart.keyCode) : null; + return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, OS); } public getUserSettingsLabel(): string { - const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, FancyResolvedKeybinding._usKeyCodeToUserSettings, OS); - - let result = UserSettingsLabelProvider.toLabel2(firstPart, chordPart, OS); + let firstPart = this._firstPart ? USER_SETTINGS.fromKeyCode(this._firstPart.keyCode) : null; + let chordPart = this._chordPart ? USER_SETTINGS.fromKeyCode(this._chordPart.keyCode) : null; + let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OS); return result.toLowerCase(); } public isChord(): boolean { - return (this._actual.type === KeybindingType.Chord); + return (this._chordPart ? true : false); } public hasCtrlModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.ctrlKey; + return this._firstPart.ctrlKey; } public hasShiftModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.shiftKey; + return this._firstPart.shiftKey; } public hasAltModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.altKey; + return this._firstPart.altKey; } public hasMetaModifier(): boolean { - if (this._actual.type === KeybindingType.Chord) { + if (this._chordPart) { return false; } - return this._actual.metaKey; + return this._firstPart.metaKey; } public getDispatchParts(): [string, string] { - let keypressFirstPart: string; - let keypressChordPart: string; - if (this._actual === null) { - keypressFirstPart = null; - keypressChordPart = null; - } else if (this._actual.type === KeybindingType.Chord) { - keypressFirstPart = this._getDispatchPart(this._actual.firstPart); - keypressChordPart = this._getDispatchPart(this._actual.chordPart); - } else { - keypressFirstPart = this._getDispatchPart(this._actual); - keypressChordPart = null; - } - return [keypressFirstPart, keypressChordPart]; + let firstPart = this._firstPart ? this._getDispatchStr(this._firstPart) : null; + let chordPart = this._chordPart ? this._getDispatchStr(this._chordPart) : null; + return [firstPart, chordPart]; } - private _getDispatchPart(keybinding: SimpleKeybinding): string { + private _getDispatchStr(keybinding: SimpleKeybinding): string { if (keybinding.isModifierKey()) { return null; } diff --git a/src/vs/workbench/services/keybinding/electron-browser/nativeKeymap.ts b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymap.ts index da40ef09ddb..e6c5ae15587 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/nativeKeymap.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymap.ts @@ -7,7 +7,6 @@ import * as nativeKeymap from 'native-keymap'; import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes'; import { CharCode } from 'vs/base/common/charCode'; -import { IKeyCodeLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; import { lookupKeyCode, setExtractKeyCode } from 'vs/base/browser/keyboardEvent'; import Platform = require('vs/base/common/platform'); @@ -332,50 +331,7 @@ setExtractKeyCode((e: KeyboardEvent) => { return lookupKeyCode(e); }); -let nativeUIKeyCodeLabelProvider: IKeyCodeLabelProvider = null; -export function getNativeUIKeyCodeLabelProvider(): IKeyCodeLabelProvider { - if (!nativeUIKeyCodeLabelProvider) { - let remaps = getNativeLabelProviderRemaps(); - nativeUIKeyCodeLabelProvider = (keyCode: KeyCode, OS: Platform.OperatingSystem): string => { - if (remaps[keyCode] !== null) { - return remaps[keyCode].render(); - } - - if (OS === Platform.OperatingSystem.Macintosh) { - switch (keyCode) { - case KeyCode.LeftArrow: - return '←'; - case KeyCode.UpArrow: - return '↑'; - case KeyCode.RightArrow: - return '→'; - case KeyCode.DownArrow: - return '↓'; - } - } - - return KeyCodeUtils.toString(keyCode); - }; - } - return nativeUIKeyCodeLabelProvider; -} - -let nativeAriaKeyCodeLabelProvider: IKeyCodeLabelProvider = null; -export function getNativeAriaKeyCodeLabelProvider(): IKeyCodeLabelProvider { - if (!nativeAriaKeyCodeLabelProvider) { - let remaps = getNativeLabelProviderRemaps(); - nativeAriaKeyCodeLabelProvider = (keyCode: KeyCode, OS: Platform.OperatingSystem): string => { - if (remaps[keyCode] !== null) { - return remaps[keyCode].render(); - } - - return KeyCodeUtils.toString(keyCode); - }; - } - return nativeAriaKeyCodeLabelProvider; -} - -class NativeLabel { +export class NativeLabel { public static Empty = new NativeLabel('', '', '', ''); @@ -429,7 +385,7 @@ class NativeLabel { } let nativeLabelRemaps: NativeLabel[] = null; -function getNativeLabelProviderRemaps(): NativeLabel[] { +export function getNativeLabelProviderRemaps(): NativeLabel[] { if (!nativeLabelRemaps) { // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx // See https://github.com/Microsoft/node-native-keymap/blob/master/deps/chromium/keyboard_codes_win.h diff --git a/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts index 1518abf9978..19784e334f3 100644 --- a/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts @@ -9,7 +9,7 @@ import * as assert from 'assert'; import { KeyMod, KeyCode, createKeybinding, SimpleKeybinding, Keybinding } from 'vs/base/common/keyCodes'; import { KeyboardMapper, IKeyboardMapping } from 'vs/workbench/services/keybinding/common/keyboardMapper'; import { OperatingSystem } from 'vs/base/common/platform'; -import { UserSettingsLabelProvider, PrintableKeypress } from 'vs/platform/keybinding/common/keybindingLabels'; +import { UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { KeyboardEventCodeUtils } from 'vs/workbench/services/keybinding/common/keyboardEventCode'; import { IHTMLContentElement } from 'vs/base/common/htmlContent'; @@ -190,20 +190,6 @@ function _assertKeybindingTranslation(mapper: KeyboardMapper, OS: OperatingSyste } const actual = actualHardwareKeypresses - .map(k => new PrintableKeypress(k.ctrlKey, k.shiftKey, k.altKey, k.metaKey, KeyboardEventCodeUtils.toString(k.code))) - .map(kp => UserSettingsLabelProvider.toLabel2(kp, null, OS)); + .map(k => UserSettingsLabelProvider.toLabel(k, KeyboardEventCodeUtils.toString(k.code), null, null, OS)); assert.deepEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`); - - // Now also check the reverse map ... - actualHardwareKeypresses.forEach(k => { - const hardwareKeypressLabel = `${k.ctrlKey ? 'ctrl+' : ''}${k.shiftKey ? 'shift+' : ''}${k.altKey ? 'alt+' : ''}${k.metaKey ? 'meta+' : ''}${KeyboardEventCodeUtils.toString(k.code)}`; - const reversed = mapper.hardwareKeypressToSimpleKeybinding(k); - if (!reversed) { - assert.fail(`${keybindingLabel} -> ${hardwareKeypressLabel} -> null`); - return; - } - - const reversedLabel = new USLayoutResolvedKeybinding(reversed, OS).getUserSettingsLabel(); - assert.equal(reversedLabel, keybindingLabel, `${keybindingLabel} -> ${hardwareKeypressLabel} -> ${reversedLabel}`); - }); } -- GitLab