Skip to content

Commit

Permalink
Add keyboard.dispatch preference
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Foltz <jack@foltz.io>
  • Loading branch information
foltik authored and vince-fugnitto committed Oct 28, 2020
1 parent b3aa18f commit 6fe570d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
12 changes: 11 additions & 1 deletion packages/core/src/browser/core-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,22 @@ export const corePreferenceSchema: PreferenceSchema = {
enum: ['onHover', 'none', 'always'],
default: 'onHover',
description: 'Controls whether the tree should render indent guides.'
}
},
'keyboard.dispatch': {
type: 'string',
enum: [
'code',
'keyCode',
],
default: 'code',
description: 'Whether to interpret keypresses by the `code` of the physical key, or by the `keyCode` provided by the OS.'
},
}
};

export interface CoreConfiguration {
'application.confirmExit': 'never' | 'ifRequired' | 'always';
'keyboard.dispatch': 'code' | 'keyCode';
'workbench.list.openMode': 'singleClick' | 'doubleClick';
'workbench.commandPalette.history': number;
'workbench.editor.highlightModifiedTabs': boolean;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/browser/keybinding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { MockLogger } from '../common/test/mock-logger';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
import { FrontendApplicationStateService } from './frontend-application-state';
import { ContextKeyService } from './context-key-service';
import { CorePreferences } from './core-preferences';
import * as os from '../common/os';
import * as chai from 'chai';
import * as sinon from 'sinon';
Expand Down Expand Up @@ -85,6 +86,7 @@ before(async () => {
bind(LabelParser).toSelf().inSingletonScope();
bind(ContextKeyService).toSelf().inSingletonScope();
bind(FrontendApplicationStateService).toSelf().inSingletonScope();
bind(CorePreferences).toConstantValue(<CorePreferences>{});
});

testContainer.load(module);
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/browser/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ContributionProvider } from '../common/contribution-provider';
import { ILogger } from '../common/logger';
import { StatusBarAlignment, StatusBar } from './status-bar/status-bar';
import { ContextKeyService } from './context-key-service';
import { CorePreferences } from './core-preferences';
import * as common from '../common/keybinding';

export enum KeybindingScope {
Expand Down Expand Up @@ -101,6 +102,9 @@ export class KeybindingRegistry {
protected readonly contexts: { [id: string]: KeybindingContext } = {};
protected readonly keymaps: ScopedKeybinding[][] = [...Array(KeybindingScope.length)].map(() => []);

@inject(CorePreferences)
protected readonly corePreferences: CorePreferences;

@inject(KeyboardLayoutService)
protected readonly keyboardLayoutService: KeyboardLayoutService;

Expand Down Expand Up @@ -513,7 +517,8 @@ export class KeybindingRegistry {
return;
}

const keyCode = KeyCode.createKeyCode(event);
const eventDispatch = this.corePreferences['keyboard.dispatch'];
const keyCode = KeyCode.createKeyCode(event, eventDispatch);
/* Keycode is only a modifier, next keycode will be modifier + key.
Ignore this one. */
if (keyCode.isModifierOnly()) {
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/browser/keyboard/keys.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ describe('keys api', () => {
stub.restore();
});

it('should properly handle eventDispatch', () => {
const event = new KeyboardEvent('keydown', {
code: Key.CAPS_LOCK.code,
});
Object.defineProperty(event, 'keyCode', { get: () => Key.ESCAPE.keyCode });
expect(KeyCode.createKeyCode(event, 'code').toString()).to.be.equal(Key.CAPS_LOCK.easyString);
expect(KeyCode.createKeyCode(event, 'keyCode').toString()).to.be.equal(Key.ESCAPE.easyString);
});

it('should serialize a keycode properly with a + M4', () => {
const stub = sinon.stub(os, 'isOSX').value(true);
const keyCode = KeyCode.createKeyCode({ first: Key.KEY_A, modifiers: [KeyModifier.MacCtrl] });
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/browser/keyboard/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class KeyCode {
/**
* Create a KeyCode from one of several input types.
*/
public static createKeyCode(input: KeyboardEvent | Keystroke | KeyCodeSchema | string): KeyCode {
public static createKeyCode(input: KeyboardEvent | Keystroke | KeyCodeSchema | string, eventDispatch: 'code' | 'keyCode' = 'code'): KeyCode {
if (typeof input === 'string') {
const parts = input.split('+');
if (!KeyCode.isModifierString(parts[0])) {
Expand All @@ -188,7 +188,7 @@ export class KeyCode {
}
return KeyCode.createKeyCode({ modifiers: parts as KeyModifier[] });
} else if (KeyCode.isKeyboardEvent(input)) {
const key = KeyCode.toKey(input);
const key = KeyCode.toKey(input, eventDispatch);
return new KeyCode({
key: Key.isModifier(key.code) ? undefined : key,
meta: isOSX && input.metaKey,
Expand Down Expand Up @@ -344,9 +344,9 @@ export namespace KeyCode {
* `keyIdentifier` is used to access this deprecated field:
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyIdentifier
*/
export function toKey(event: KeyboardEvent): Key {
export function toKey(event: KeyboardEvent, dispatch: 'code' | 'keyCode' = 'code'): Key {
const code = event.code;
if (code) {
if (code && dispatch === 'code') {
if (isOSX) {
// https://github.com/eclipse-theia/theia/issues/4986
const char = event.key;
Expand Down

0 comments on commit 6fe570d

Please sign in to comment.