Skip to content

Commit 871a6fe

Browse files
authored
Merge pull request microsoft#65826 from toumorokoshi/feature/keychords
Modifying ChordKeybinding to support multiple chords
2 parents 37efd5c + 555739f commit 871a6fe

22 files changed

Lines changed: 367 additions & 389 deletions

src/vs/base/common/keyCodes.ts

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { OperatingSystem } from 'vs/base/common/platform';
7+
import { illegalArgument } from 'vs/base/common/errors';
78

89
/**
910
* Virtual Key Codes, the value does not hold any inherent meaning.
@@ -417,12 +418,12 @@ export function createKeybinding(keybinding: number, OS: OperatingSystem): Keybi
417418
const firstPart = (keybinding & 0x0000FFFF) >>> 0;
418419
const chordPart = (keybinding & 0xFFFF0000) >>> 16;
419420
if (chordPart !== 0) {
420-
return new ChordKeybinding(
421+
return new ChordKeybinding([
421422
createSimpleKeybinding(firstPart, OS),
422-
createSimpleKeybinding(chordPart, OS),
423-
);
423+
createSimpleKeybinding(chordPart, OS)
424+
]);
424425
}
425-
return createSimpleKeybinding(firstPart, OS);
426+
return new ChordKeybinding([createSimpleKeybinding(firstPart, OS)]);
426427
}
427428

428429
export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem): SimpleKeybinding {
@@ -439,14 +440,7 @@ export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem):
439440
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, keyCode);
440441
}
441442

442-
export const enum KeybindingType {
443-
Simple = 1,
444-
Chord = 2
445-
}
446-
447443
export class SimpleKeybinding {
448-
public readonly type = KeybindingType.Simple;
449-
450444
public readonly ctrlKey: boolean;
451445
public readonly shiftKey: boolean;
452446
public readonly altKey: boolean;
@@ -461,10 +455,7 @@ export class SimpleKeybinding {
461455
this.keyCode = keyCode;
462456
}
463457

464-
public equals(other: Keybinding): boolean {
465-
if (other.type !== KeybindingType.Simple) {
466-
return false;
467-
}
458+
public equals(other: SimpleKeybinding): boolean {
468459
return (
469460
this.ctrlKey === other.ctrlKey
470461
&& this.shiftKey === other.shiftKey
@@ -492,6 +483,10 @@ export class SimpleKeybinding {
492483
);
493484
}
494485

486+
public toChord(): ChordKeybinding {
487+
return new ChordKeybinding([this]);
488+
}
489+
495490
/**
496491
* Does this keybinding refer to the key code of a modifier and it also has the modifier flag?
497492
*/
@@ -506,22 +501,43 @@ export class SimpleKeybinding {
506501
}
507502

508503
export class ChordKeybinding {
509-
public readonly type = KeybindingType.Chord;
510-
511-
public readonly firstPart: SimpleKeybinding;
512-
public readonly chordPart: SimpleKeybinding;
504+
public readonly parts: SimpleKeybinding[];
513505

514-
constructor(firstPart: SimpleKeybinding, chordPart: SimpleKeybinding) {
515-
this.firstPart = firstPart;
516-
this.chordPart = chordPart;
506+
constructor(parts: SimpleKeybinding[]) {
507+
if (parts.length === 0) {
508+
throw illegalArgument(`parts`);
509+
}
510+
this.parts = parts;
517511
}
518512

519513
public getHashCode(): string {
520-
return `${this.firstPart.getHashCode()};${this.chordPart.getHashCode()}`;
514+
let result = '';
515+
for (let i = 0, len = this.parts.length; i < len; i++) {
516+
if (i !== 0) {
517+
result += ';';
518+
}
519+
result += this.parts[i].getHashCode();
520+
}
521+
return result;
522+
}
523+
524+
public equals(other: ChordKeybinding | null): boolean {
525+
if (other === null) {
526+
return false;
527+
}
528+
if (this.parts.length !== other.parts.length) {
529+
return false;
530+
}
531+
for (let i = 0; i < this.parts.length; i++) {
532+
if (!this.parts[i].equals(other.parts[i])) {
533+
return false;
534+
}
535+
}
536+
return true;
521537
}
522538
}
523539

524-
export type Keybinding = SimpleKeybinding | ChordKeybinding;
540+
export type Keybinding = ChordKeybinding;
525541

526542
export class ResolvedKeybindingPart {
527543
readonly ctrlKey: boolean;
@@ -574,12 +590,12 @@ export abstract class ResolvedKeybinding {
574590
public abstract isChord(): boolean;
575591

576592
/**
577-
* Returns the firstPart, chordPart that should be used for dispatching.
593+
* Returns the parts that should be used for dispatching.
578594
*/
579-
public abstract getDispatchParts(): [string | null, string | null];
595+
public abstract getDispatchParts(): (string | null)[];
580596
/**
581-
* Returns the firstPart, chordPart of the keybinding.
582-
* For simple keybindings, the second element will be null.
597+
* Returns the parts that comprise of the keybinding.
598+
* Simple keybindings return one element.
583599
*/
584-
public abstract getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null];
600+
public abstract getParts(): ResolvedKeybindingPart[];
585601
}

src/vs/base/common/keybindingLabels.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ export interface Modifiers {
2121
readonly metaKey: boolean;
2222
}
2323

24+
export interface KeyLabelProvider<T extends Modifiers> {
25+
(keybinding: T): string | null;
26+
}
27+
2428
export class ModifierLabelProvider {
2529

2630
public readonly modifierLabels: ModifierLabels[];
@@ -32,11 +36,22 @@ export class ModifierLabelProvider {
3236
this.modifierLabels[OperatingSystem.Linux] = linux;
3337
}
3438

35-
public toLabel(firstPartMod: Modifiers | null, firstPartKey: string | null, chordPartMod: Modifiers | null, chordPartKey: string | null, OS: OperatingSystem): string | null {
36-
if (firstPartMod === null || firstPartKey === null) {
39+
public toLabel<T extends Modifiers>(OS: OperatingSystem, parts: T[], keyLabelProvider: KeyLabelProvider<T>): string | null {
40+
if (parts.length === 0) {
3741
return null;
3842
}
39-
return _asString(firstPartMod, firstPartKey, chordPartMod, chordPartKey, this.modifierLabels[OS]);
43+
44+
let result: string[] = [];
45+
for (let i = 0, len = parts.length; i < len; i++) {
46+
const part = parts[i];
47+
const keyLabel = keyLabelProvider(part);
48+
if (keyLabel === null) {
49+
// this keybinding cannot be expressed...
50+
return null;
51+
}
52+
result[i] = _simpleAsString(part, keyLabel, this.modifierLabels[OS]);
53+
}
54+
return result.join(' ');
4055
}
4156
}
4257

@@ -171,14 +186,3 @@ function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabe
171186

172187
return result.join(labels.separator);
173188
}
174-
175-
function _asString(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers | null, chordPartKey: string | null, labels: ModifierLabels): string {
176-
let result = _simpleAsString(firstPartMod, firstPartKey, labels);
177-
178-
if (chordPartMod !== null && chordPartKey !== null) {
179-
result += ' ';
180-
result += _simpleAsString(chordPartMod, chordPartKey, labels);
181-
}
182-
183-
return result;
184-
}

src/vs/base/common/keybindingParser.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,14 @@ export class KeybindingParser {
8585
return null;
8686
}
8787

88-
let [firstPart, remains] = this.parseSimpleKeybinding(input);
89-
let chordPart: SimpleKeybinding | null = null;
90-
if (remains.length > 0) {
91-
[chordPart] = this.parseSimpleKeybinding(remains);
92-
}
88+
let parts: SimpleKeybinding[] = [];
89+
let part: SimpleKeybinding;
9390

94-
if (chordPart) {
95-
return new ChordKeybinding(firstPart, chordPart);
96-
}
97-
return firstPart;
91+
do {
92+
[part, input] = this.parseSimpleKeybinding(input);
93+
parts.push(part);
94+
} while (input.length > 0);
95+
return new ChordKeybinding(parts);
9896
}
9997

10098
private static parseSimpleUserBinding(input: string): [SimpleKeybinding | ScanCodeBinding, string] {
@@ -110,6 +108,7 @@ export class KeybindingParser {
110108
}
111109

112110
static parseUserBinding(input: string): [SimpleKeybinding | ScanCodeBinding | null, SimpleKeybinding | ScanCodeBinding | null] {
111+
// TODO@chords: allow users to define N chords
113112
if (!input) {
114113
return [null, null];
115114
}

src/vs/base/parts/tree/browser/treeDefaults.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import * as mouse from 'vs/base/browser/mouseEvent';
1313
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
1414
import * as _ from 'vs/base/parts/tree/browser/tree';
1515
import { IDragAndDropData } from 'vs/base/browser/dnd';
16-
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
16+
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
1717

1818
export interface IKeyBindingCallback {
1919
(tree: _.ITree, event: IKeyboardEvent): void;
@@ -49,7 +49,7 @@ export interface IControllerOptions {
4949
}
5050

5151
interface IKeybindingDispatcherItem {
52-
keybinding: Keybinding;
52+
keybinding: Keybinding | null;
5353
callback: IKeyBindingCallback;
5454
}
5555

@@ -62,18 +62,20 @@ export class KeybindingDispatcher {
6262
}
6363

6464
public has(keybinding: KeyCode): boolean {
65-
let target = createSimpleKeybinding(keybinding, platform.OS);
66-
for (const a of this._arr) {
67-
if (target.equals(a.keybinding)) {
68-
return true;
65+
let target = createKeybinding(keybinding, platform.OS);
66+
if (target !== null) {
67+
for (const a of this._arr) {
68+
if (target.equals(a.keybinding)) {
69+
return true;
70+
}
6971
}
7072
}
7173
return false;
7274
}
7375

7476
public set(keybinding: number, callback: IKeyBindingCallback) {
7577
this._arr.push({
76-
keybinding: createSimpleKeybinding(keybinding, platform.OS),
78+
keybinding: createKeybinding(keybinding, platform.OS),
7779
callback: callback
7880
});
7981
}
@@ -82,7 +84,7 @@ export class KeybindingDispatcher {
8284
// Loop from the last to the first to handle overwrites
8385
for (let i = this._arr.length - 1; i >= 0; i--) {
8486
let item = this._arr[i];
85-
if (keybinding.equals(item.keybinding)) {
87+
if (keybinding.toChord().equals(item.keybinding)) {
8688
return item.callback;
8789
}
8890
}

src/vs/base/test/common/keyCodes.test.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,35 @@ suite('keyCodes', () => {
2020
}
2121

2222
test(null, 0);
23-
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
24-
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
25-
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
26-
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
27-
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
28-
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
29-
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
30-
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
31-
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
32-
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
33-
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
34-
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
35-
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
36-
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
37-
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
38-
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
23+
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter).toChord(), KeyCode.Enter);
24+
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter).toChord(), KeyMod.WinCtrl | KeyCode.Enter);
25+
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyCode.Enter);
26+
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
27+
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyCode.Enter);
28+
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
29+
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
30+
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
31+
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyCode.Enter);
32+
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
33+
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
34+
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
35+
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
36+
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
37+
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
38+
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
3939

4040
test(
41-
new ChordKeybinding(
41+
new ChordKeybinding([
4242
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
4343
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
44-
),
44+
]),
4545
KeyChord(KeyCode.Enter, KeyCode.Tab)
4646
);
4747
test(
48-
new ChordKeybinding(
48+
new ChordKeybinding([
4949
new SimpleKeybinding(false, false, false, true, KeyCode.KEY_Y),
5050
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
51-
),
51+
]),
5252
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
5353
);
5454
});
@@ -62,35 +62,35 @@ suite('keyCodes', () => {
6262
}
6363

6464
test(null, 0);
65-
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
66-
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
67-
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
68-
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
69-
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
70-
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
71-
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
72-
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
73-
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
74-
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
75-
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
76-
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
77-
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
78-
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
79-
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
80-
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
65+
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter).toChord(), KeyCode.Enter);
66+
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter).toChord(), KeyMod.WinCtrl | KeyCode.Enter);
67+
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyCode.Enter);
68+
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter).toChord(), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
69+
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyCode.Enter);
70+
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
71+
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
72+
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
73+
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyCode.Enter);
74+
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
75+
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
76+
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
77+
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
78+
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
79+
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
80+
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
8181

8282
test(
83-
new ChordKeybinding(
83+
new ChordKeybinding([
8484
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
8585
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
86-
),
86+
]),
8787
KeyChord(KeyCode.Enter, KeyCode.Tab)
8888
);
8989
test(
90-
new ChordKeybinding(
90+
new ChordKeybinding([
9191
new SimpleKeybinding(true, false, false, false, KeyCode.KEY_Y),
9292
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
93-
),
93+
]),
9494
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
9595
);
9696

src/vs/editor/standalone/browser/simpleServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
369369
keyboardEvent.altKey,
370370
keyboardEvent.metaKey,
371371
keyboardEvent.keyCode
372-
);
372+
).toChord();
373373
return new USLayoutResolvedKeybinding(keybinding, OS);
374374
}
375375

0 commit comments

Comments
 (0)