Skip to content

Commit 705ffa9

Browse files
author
Steven Silvester
authored
Merge pull request #245 from ph-ph/dzmitry-ignore-modifier-key-presses
Ignore `keydown` events for modifier keys when accumulating key sequence
2 parents 3cb4859 + 7c38271 commit 705ffa9

File tree

4 files changed

+270
-100
lines changed

4 files changed

+270
-100
lines changed

packages/commands/src/index.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ export class CommandRegistry {
497497
*/
498498
processKeydownEvent(event: KeyboardEvent): void {
499499
// Bail immediately if playing back keystrokes.
500-
if (this._replaying) {
500+
if (this._replaying || CommandRegistry.isModifierKeyPressed(event)) {
501501
return;
502502
}
503503

@@ -1201,6 +1201,19 @@ export namespace CommandRegistry {
12011201
return mods + parts.key;
12021202
}
12031203

1204+
/**
1205+
* Check if `'keydown'` event is caused by pressing a modifier key that should be ignored.
1206+
*
1207+
* @param event - The event object for a `'keydown'` event.
1208+
*
1209+
* @returns `true` if modifier key was pressed, `false` otherwise.
1210+
*/
1211+
export function isModifierKeyPressed(event: KeyboardEvent): boolean {
1212+
let layout = getKeyboardLayout();
1213+
let key = layout.keyForKeydownEvent(event);
1214+
return layout.isModifierKey(key);
1215+
}
1216+
12041217
/**
12051218
* Create a normalized keystroke for a `'keydown'` event.
12061219
*
@@ -1210,8 +1223,9 @@ export namespace CommandRegistry {
12101223
* does not represent a valid keystroke for the given layout.
12111224
*/
12121225
export function keystrokeForKeydownEvent(event: KeyboardEvent): string {
1213-
let key = getKeyboardLayout().keyForKeydownEvent(event);
1214-
if (!key) {
1226+
let layout = getKeyboardLayout();
1227+
let key = layout.keyForKeydownEvent(event);
1228+
if (!key || layout.isModifierKey(key)) {
12151229
return '';
12161230
}
12171231
let mods = '';

packages/commands/tests/src/index.spec.ts

+57
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,55 @@ describe('@lumino/commands', () => {
10071007
expect(called).to.equal(false);
10081008
document.body.removeEventListener('keydown', keydown);
10091009
});
1010+
1011+
it('should ignore modifier keys pressed in the middle of key sequence', () => {
1012+
let count = 0;
1013+
registry.addCommand('test', {
1014+
execute: () => {
1015+
count++;
1016+
}
1017+
});
1018+
registry.addKeyBinding({
1019+
keys: ['Ctrl K', 'Ctrl L'],
1020+
selector: `#${elem.id}`,
1021+
command: 'test'
1022+
});
1023+
let eventK = generate('keydown', { keyCode: 75, ctrlKey: true });
1024+
let eventCtrl = generate('keydown', { keyCode: 17, ctrlKey: true });
1025+
let eventL = generate('keydown', { keyCode: 76, ctrlKey: true });
1026+
elem.dispatchEvent(eventK);
1027+
expect(count).to.equal(0);
1028+
elem.dispatchEvent(eventCtrl); // user presses Ctrl again - this should not break the sequence
1029+
expect(count).to.equal(0);
1030+
elem.dispatchEvent(eventL);
1031+
expect(count).to.equal(1);
1032+
});
1033+
1034+
it('should process key sequences that use different modifier keys', () => {
1035+
let count = 0;
1036+
registry.addCommand('test', {
1037+
execute: () => {
1038+
count++;
1039+
}
1040+
});
1041+
registry.addKeyBinding({
1042+
keys: ['Shift K', 'Ctrl L'],
1043+
selector: `#${elem.id}`,
1044+
command: 'test'
1045+
});
1046+
let eventShift = generate('keydown', { keyCode: 16, shiftlKey: true });
1047+
let eventK = generate('keydown', { keyCode: 75, shiftKey: true });
1048+
let eventCtrl = generate('keydown', { keyCode: 17, ctrlKey: true });
1049+
let eventL = generate('keydown', { keyCode: 76, ctrlKey: true });
1050+
elem.dispatchEvent(eventShift);
1051+
expect(count).to.equal(0);
1052+
elem.dispatchEvent(eventK);
1053+
expect(count).to.equal(0);
1054+
elem.dispatchEvent(eventCtrl);
1055+
expect(count).to.equal(0);
1056+
elem.dispatchEvent(eventL);
1057+
expect(count).to.equal(1);
1058+
});
10101059
});
10111060

10121061
describe('.parseKeystroke()', () => {
@@ -1085,6 +1134,14 @@ describe('@lumino/commands', () => {
10851134
);
10861135
expect(keystroke).to.equal('');
10871136
});
1137+
1138+
it('should return nothing for keys that are marked as modifier in keyboard layout', () => {
1139+
let event = generate('keydown', { keyCode: 17, ctrlKey: true });
1140+
let keystroke = CommandRegistry.keystrokeForKeydownEvent(
1141+
event as KeyboardEvent
1142+
);
1143+
expect(keystroke).to.equal('');
1144+
});
10881145
});
10891146
});
10901147
});

0 commit comments

Comments
 (0)