提交 2865949f 编写于 作者: A Alex Dima

Fixes #24153: ISO Keyboards: Backslash and IntlBackslash "swapped"

上级 830b94b2
......@@ -293,9 +293,9 @@
"resolved": "https://registry.npmjs.org/nan/-/nan-2.4.0.tgz"
},
"native-keymap": {
"version": "1.2.2",
"from": "native-keymap@1.2.2",
"resolved": "https://registry.npmjs.org/native-keymap/-/native-keymap-1.2.2.tgz"
"version": "1.2.3",
"from": "native-keymap@1.2.3",
"resolved": "https://registry.npmjs.org/native-keymap/-/native-keymap-1.2.3.tgz"
},
"normalize-path": {
"version": "2.0.1",
......
......@@ -66,4 +66,6 @@ declare module 'native-keymap' {
export function getCurrentKeyboardLayout(): IKeyboardLayoutInfo;
export function onDidChangeKeyboardLayout(callback: () => void);
export function isISOKeyboard(): boolean;
}
\ No newline at end of file
......@@ -253,9 +253,9 @@ export class WindowsManager implements IWindowsMainService {
this.lifecycleService.onBeforeWindowClose(win => this.onBeforeWindowClose(win));
this.lifecycleService.onBeforeQuit(() => this.onBeforeQuit());
KeyboardLayoutMonitor.INSTANCE.onDidChangeKeyboardLayout(() => {
KeyboardLayoutMonitor.INSTANCE.onDidChangeKeyboardLayout((isISOKeyboard: boolean) => {
WindowsManager.WINDOWS.forEach((window) => {
window.sendWhenReady('vscode:keyboardLayoutChanged');
window.sendWhenReady('vscode:keyboardLayoutChanged', isISOKeyboard);
});
});
}
......@@ -1329,21 +1329,52 @@ class KeyboardLayoutMonitor {
public static INSTANCE = new KeyboardLayoutMonitor();
private _emitter: Emitter<void>;
private _emitter: Emitter<boolean>;
private _registered: boolean;
private constructor() {
this._emitter = new Emitter<void>();
this._emitter = new Emitter<boolean>();
this._registered = false;
}
public onDidChangeKeyboardLayout(callback: () => void): IDisposable {
public onDidChangeKeyboardLayout(callback: (isISOKeyboard: boolean) => void): IDisposable {
if (!this._registered) {
this._registered = true;
nativeKeymap.onDidChangeKeyboardLayout(() => {
this._emitter.fire();
this._emitter.fire(this._isISOKeyboard());
});
if (platform.isMacintosh) {
// See https://github.com/Microsoft/vscode/issues/24153
// On OSX, on ISO keyboards, Chromium swaps the scan codes
// of IntlBackslash and Backquote.
//
// The C++ methods can give the current keyboard type (ISO or not)
// only after a NSEvent was handled.
//
// We therefore poll.
let prevValue: boolean = null;
setInterval(() => {
let newValue = this._isISOKeyboard();
if (prevValue === newValue) {
// no change
return;
}
prevValue = newValue;
this._emitter.fire(this._isISOKeyboard());
}, 3000);
}
}
return this._emitter.event(callback);
}
private _isISOKeyboard(): boolean {
if (platform.isMacintosh) {
return nativeKeymap.isISOKeyboard();
}
return false;
}
}
......@@ -297,8 +297,8 @@ export class ElectronWindow extends Themable {
});
// keyboard layout changed event
ipc.on('vscode:keyboardLayoutChanged', () => {
KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged();
ipc.on('vscode:keyboardLayoutChanged', (event, isISOKeyboard: boolean) => {
KeyboardMapperFactory.INSTANCE._onKeyboardLayoutChanged(isISOKeyboard);
});
// Configuration changes
......
......@@ -510,7 +510,11 @@ class ScanCodeKeyCodeMapper {
export class MacLinuxKeyboardMapper implements IKeyboardMapper {
/**
* OS (can be Linux or Macintosh)
* Is the keyboard type ISO (on Mac)
*/
private readonly _isISOKeyboard: boolean;
/**
* Is this the standard US keyboard layout?
*/
private readonly _isUSStandard: boolean;
/**
......@@ -534,7 +538,8 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
*/
private readonly _scanCodeToDispatch: string[] = [];
constructor(isUSStandard: boolean, rawMappings: IMacLinuxKeyboardMapping, OS: OperatingSystem) {
constructor(isISOKeyboard: boolean, isUSStandard: boolean, rawMappings: IMacLinuxKeyboardMapping, OS: OperatingSystem) {
this._isISOKeyboard = isISOKeyboard;
this._isUSStandard = isUSStandard;
this._OS = OS;
this._codeInfo = [];
......@@ -1051,11 +1056,27 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): NativeResolvedKeybinding {
let code = ScanCodeUtils.toEnum(keyboardEvent.code);
// Treat NumpadEnter as Enter
if (code === ScanCode.NumpadEnter) {
code = ScanCode.Enter;
}
if (this._OS === OperatingSystem.Macintosh && this._isISOKeyboard) {
// See https://github.com/Microsoft/vscode/issues/24153
// On OSX, on ISO keyboards, Chromium swaps the scan codes
// of IntlBackslash and Backquote.
switch (code) {
case ScanCode.IntlBackslash:
code = ScanCode.Backquote;
break;
case ScanCode.Backquote:
code = ScanCode.IntlBackslash;
break;
}
}
const keyCode = keyboardEvent.keyCode;
if (
......
......@@ -44,6 +44,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
export class KeyboardMapperFactory {
public static INSTANCE = new KeyboardMapperFactory();
private _isISOKeyboard: boolean;
private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo;
private _rawMapping: nativeKeymap.IKeyboardMapping;
private _keyboardMapper: IKeyboardMapper;
......@@ -53,13 +54,15 @@ export class KeyboardMapperFactory {
public onDidChangeKeyboardMapper: Event<void> = this._onDidChangeKeyboardMapper.event;
private constructor() {
this._isISOKeyboard = false;
this._layoutInfo = null;
this._rawMapping = null;
this._keyboardMapper = null;
this._initialized = false;
}
public _onKeyboardLayoutChanged(): void {
public _onKeyboardLayoutChanged(isISOKeyboard: boolean): void {
this._isISOKeyboard = isISOKeyboard;
if (this._initialized) {
this._setKeyboardData(nativeKeymap.getCurrentKeyboardLayout(), nativeKeymap.getKeyMap());
}
......@@ -124,11 +127,11 @@ export class KeyboardMapperFactory {
this._initialized = true;
this._rawMapping = rawMapping;
this._keyboardMapper = KeyboardMapperFactory._createKeyboardMapper(KeyboardMapperFactory._isUSStandard(this._layoutInfo), this._rawMapping);
this._keyboardMapper = KeyboardMapperFactory._createKeyboardMapper(this._isISOKeyboard, KeyboardMapperFactory._isUSStandard(this._layoutInfo), this._rawMapping);
this._onDidChangeKeyboardMapper.fire();
}
private static _createKeyboardMapper(isUSStandard: boolean, rawMapping: nativeKeymap.IKeyboardMapping): IKeyboardMapper {
private static _createKeyboardMapper(isISOKeyboard: boolean, isUSStandard: boolean, rawMapping: nativeKeymap.IKeyboardMapping): IKeyboardMapper {
if (OS === OperatingSystem.Windows) {
return new WindowsKeyboardMapper(<IWindowsKeyboardMapping>rawMapping);
}
......@@ -138,7 +141,7 @@ export class KeyboardMapperFactory {
return new MacLinuxFallbackKeyboardMapper(OS);
}
return new MacLinuxKeyboardMapper(isUSStandard, <IMacLinuxKeyboardMapping>rawMapping, OS);
return new MacLinuxKeyboardMapper(isISOKeyboard, isUSStandard, <IMacLinuxKeyboardMapping>rawMapping, OS);
}
private static _equals(a: nativeKeymap.IKeyboardMapping, b: nativeKeymap.IKeyboardMapping): boolean {
......
......@@ -19,7 +19,7 @@ const WRITE_FILE_IF_DIFFERENT = false;
function createKeyboardMapper(isUSStandard: boolean, file: string, OS: OperatingSystem): TPromise<MacLinuxKeyboardMapper> {
return readRawMapping<IMacLinuxKeyboardMapping>(file).then((rawMappings) => {
return new MacLinuxKeyboardMapper(isUSStandard, rawMappings, OS);
return new MacLinuxKeyboardMapper(false, isUSStandard, rawMappings, OS);
});
}
......@@ -1562,7 +1562,7 @@ suite('keyboardMapper - LINUX en_us', () => {
suite('keyboardMapper', () => {
test('issue #23706: Linux UK layout: Ctrl + Apostrophe also toggles terminal', () => {
let mapper = new MacLinuxKeyboardMapper(false, {
let mapper = new MacLinuxKeyboardMapper(false, false, {
'Backquote': {
'value': '`',
'withShift': '¬',
......@@ -1600,7 +1600,7 @@ suite('keyboardMapper', () => {
});
test('issue #24064: NumLock/NumPad keys stopped working in 1.11 on Linux', () => {
let mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux);
let mapper = new MacLinuxKeyboardMapper(false, false, {}, OperatingSystem.Linux);
function assertNumpadKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string, userSettingsLabel: string, dispatch: string): void {
assertResolveKeyboardEvent(
......@@ -1645,7 +1645,7 @@ suite('keyboardMapper', () => {
});
test('issue #24107: Delete, Insert, Home, End, PgUp, PgDn, and arrow keys no longer work editor in 1.11', () => {
let mapper = new MacLinuxKeyboardMapper(false, {}, OperatingSystem.Linux);
let mapper = new MacLinuxKeyboardMapper(false, false, {}, OperatingSystem.Linux);
function assertKeyboardEvent(keyCode: KeyCode, code: string, label: string, electronAccelerator: string, userSettingsLabel: string, dispatch: string): void {
assertResolveKeyboardEvent(
......@@ -1701,6 +1701,77 @@ suite('keyboardMapper', () => {
assertKeyboardEvent(KeyCode.UpArrow, 'Lang3', 'UpArrow', 'Up', 'up', '[ArrowUp]');
});
test('issue #24153: ISO Keyboards: Backslash and IntlBackslash "swapped"', () => {
let mapper = new MacLinuxKeyboardMapper(true, false, {
'Backquote': {
'value': '`',
'withShift': '~',
'withAltGr': '`',
'withShiftAltGr': '`'
},
'IntlBackslash': {
'value': '§',
'withShift': '°',
'withAltGr': '§',
'withShiftAltGr': '°'
}
}, OperatingSystem.Macintosh);
assertResolveKeyboardEvent(
mapper,
{
ctrlKey: true,
shiftKey: false,
altKey: false,
metaKey: false,
keyCode: -1,
code: 'Backquote'
},
{
label: '⌃§',
ariaLabel: 'Control+§',
labelWithoutModifiers: '§',
ariaLabelWithoutModifiers: '§',
electronAccelerator: null,
userSettingsLabel: 'ctrl+[IntlBackslash]',
isWYSIWYG: false,
isChord: false,
hasCtrlModifier: true,
hasShiftModifier: false,
hasAltModifier: false,
hasMetaModifier: false,
dispatchParts: ['ctrl+[IntlBackslash]', null],
}
);
assertResolveKeyboardEvent(
mapper,
{
ctrlKey: true,
shiftKey: false,
altKey: false,
metaKey: false,
keyCode: -1,
code: 'IntlBackslash'
},
{
label: '⌃`',
ariaLabel: 'Control+`',
labelWithoutModifiers: '`',
ariaLabelWithoutModifiers: '`',
electronAccelerator: null,
userSettingsLabel: 'ctrl+`',
isWYSIWYG: true,
isChord: false,
hasCtrlModifier: true,
hasShiftModifier: false,
hasAltModifier: false,
hasMetaModifier: false,
dispatchParts: ['ctrl+[Backquote]', null],
}
);
});
});
suite('keyboardMapper - LINUX ru', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册