提交 3d786a20 编写于 作者: A Alex Dima

Prepare for working around Chromium's implementing w3c's DOM Level 3 events Section B.2.4 on Mac

上级 d8e64108
......@@ -141,13 +141,21 @@ interface INormalizedKeyCode {
key: string;
}
function extractKeyCode(e:KeyboardEvent): KeyCode {
export function lookupKeyCode(e:KeyboardEvent): KeyCode {
return KEY_CODE_MAP[e.keyCode] || KeyCode.Unknown;
}
let extractKeyCode = function extractKeyCode(e:KeyboardEvent): KeyCode {
if (e.charCode) {
// "keypress" events mostly
let char = String.fromCharCode(e.charCode).toUpperCase();
return KeyCode.fromString(char);
}
return KEY_CODE_MAP[e.keyCode] || KeyCode.Unknown;
return lookupKeyCode(e);
}
export function setExtractKeyCode(newExtractKeyCode:(e:KeyboardEvent)=>KeyCode): void {
extractKeyCode = newExtractKeyCode;
}
export interface IKeyboardEvent {
......
......@@ -21,6 +21,7 @@ import {KeyCode, Keybinding, IKeyBindingLabelProvider, MacUIKeyLabelProvider, Cl
import * as nativeKeymap from 'native-keymap';
import Platform = require('vs/base/common/platform');
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
import {lookupKeyCode, setExtractKeyCode} from 'vs/base/browser/keyboardEvent';
interface ContributedKeyBinding {
command: string;
......@@ -109,6 +110,318 @@ let keybindingsExtPoint = PluginsRegistry.registerExtensionPoint<ContributedKeyB
]
});
let getNativeKeymap = (function() {
var called = false;
var result: nativeKeymap.INativeKeyMap[];
return function getNativeKeymap() {
if (!called) {
called = true;
result = nativeKeymap.getKeyMap();
}
return result;
}
})();
// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
// See https://github.com/alexandrudima/vscode-keyboard/blob/master/deps/chromium/keyboard_codes_win.h
const NATIVE_KEY_CODE_TO_KEY_CODE: {[nativeKeyCode:string]:KeyCode;} = {
VKEY_BACK: KeyCode.Backspace,
VKEY_TAB: KeyCode.Tab,
VKEY_CLEAR: KeyCode.Unknown, // MISSING
VKEY_RETURN: KeyCode.Enter,
VKEY_SHIFT: KeyCode.Shift,
VKEY_CONTROL: KeyCode.Ctrl,
VKEY_MENU: KeyCode.Alt,
VKEY_PAUSE: KeyCode.PauseBreak,
VKEY_CAPITAL: KeyCode.CapsLock,
VKEY_KANA: KeyCode.Unknown, // MISSING
VKEY_HANGUL: KeyCode.Unknown, // MISSING
VKEY_JUNJA: KeyCode.Unknown, // MISSING
VKEY_FINAL: KeyCode.Unknown, // MISSING
VKEY_HANJA: KeyCode.Unknown, // MISSING
VKEY_KANJI: KeyCode.Unknown, // MISSING
VKEY_ESCAPE: KeyCode.Escape,
VKEY_CONVERT: KeyCode.Unknown, // MISSING
VKEY_NONCONVERT: KeyCode.Unknown, // MISSING
VKEY_ACCEPT: KeyCode.Unknown, // MISSING
VKEY_MODECHANGE: KeyCode.Unknown, // MISSING
VKEY_SPACE: KeyCode.Space,
VKEY_PRIOR: KeyCode.PageUp,
VKEY_NEXT: KeyCode.PageDown,
VKEY_END: KeyCode.End,
VKEY_HOME: KeyCode.Home,
VKEY_LEFT: KeyCode.LeftArrow,
VKEY_UP: KeyCode.UpArrow,
VKEY_RIGHT: KeyCode.RightArrow,
VKEY_DOWN: KeyCode.DownArrow,
VKEY_SELECT: KeyCode.Unknown, // MISSING
VKEY_PRINT: KeyCode.Unknown, // MISSING
VKEY_EXECUTE: KeyCode.Unknown, // MISSING
VKEY_SNAPSHOT: KeyCode.Unknown, // MISSING
VKEY_INSERT: KeyCode.Insert,
VKEY_DELETE: KeyCode.Delete,
VKEY_HELP: KeyCode.Unknown, // MISSING
VKEY_0: KeyCode.KEY_0,
VKEY_1: KeyCode.KEY_1,
VKEY_2: KeyCode.KEY_2,
VKEY_3: KeyCode.KEY_3,
VKEY_4: KeyCode.KEY_4,
VKEY_5: KeyCode.KEY_5,
VKEY_6: KeyCode.KEY_6,
VKEY_7: KeyCode.KEY_7,
VKEY_8: KeyCode.KEY_8,
VKEY_9: KeyCode.KEY_9,
VKEY_A: KeyCode.KEY_A,
VKEY_B: KeyCode.KEY_B,
VKEY_C: KeyCode.KEY_C,
VKEY_D: KeyCode.KEY_D,
VKEY_E: KeyCode.KEY_E,
VKEY_F: KeyCode.KEY_F,
VKEY_G: KeyCode.KEY_G,
VKEY_H: KeyCode.KEY_H,
VKEY_I: KeyCode.KEY_I,
VKEY_J: KeyCode.KEY_J,
VKEY_K: KeyCode.KEY_K,
VKEY_L: KeyCode.KEY_L,
VKEY_M: KeyCode.KEY_M,
VKEY_N: KeyCode.KEY_N,
VKEY_O: KeyCode.KEY_O,
VKEY_P: KeyCode.KEY_P,
VKEY_Q: KeyCode.KEY_Q,
VKEY_R: KeyCode.KEY_R,
VKEY_S: KeyCode.KEY_S,
VKEY_T: KeyCode.KEY_T,
VKEY_U: KeyCode.KEY_U,
VKEY_V: KeyCode.KEY_V,
VKEY_W: KeyCode.KEY_W,
VKEY_X: KeyCode.KEY_X,
VKEY_Y: KeyCode.KEY_Y,
VKEY_Z: KeyCode.KEY_Z,
VKEY_LWIN: KeyCode.Meta,
VKEY_COMMAND: KeyCode.Meta,
VKEY_RWIN: KeyCode.Meta,
VKEY_APPS: KeyCode.Unknown, // MISSING
VKEY_SLEEP: KeyCode.Unknown, // MISSING
VKEY_NUMPAD0: KeyCode.NUMPAD_0,
VKEY_NUMPAD1: KeyCode.NUMPAD_1,
VKEY_NUMPAD2: KeyCode.NUMPAD_2,
VKEY_NUMPAD3: KeyCode.NUMPAD_3,
VKEY_NUMPAD4: KeyCode.NUMPAD_4,
VKEY_NUMPAD5: KeyCode.NUMPAD_5,
VKEY_NUMPAD6: KeyCode.NUMPAD_6,
VKEY_NUMPAD7: KeyCode.NUMPAD_7,
VKEY_NUMPAD8: KeyCode.NUMPAD_8,
VKEY_NUMPAD9: KeyCode.NUMPAD_9,
VKEY_MULTIPLY: KeyCode.NUMPAD_MULTIPLY,
VKEY_ADD: KeyCode.NUMPAD_ADD,
VKEY_SEPARATOR: KeyCode.Unknown, // MISSING
VKEY_SUBTRACT: KeyCode.NUMPAD_SUBTRACT,
VKEY_DECIMAL: KeyCode.NUMPAD_DECIMAL,
VKEY_DIVIDE: KeyCode.NUMPAD_DIVIDE,
VKEY_F1: KeyCode.F1,
VKEY_F2: KeyCode.F2,
VKEY_F3: KeyCode.F3,
VKEY_F4: KeyCode.F4,
VKEY_F5: KeyCode.F5,
VKEY_F6: KeyCode.F6,
VKEY_F7: KeyCode.F7,
VKEY_F8: KeyCode.F8,
VKEY_F9: KeyCode.F9,
VKEY_F10: KeyCode.F10,
VKEY_F11: KeyCode.F11,
VKEY_F12: KeyCode.F12,
VKEY_F13: KeyCode.Unknown, // MISSING
VKEY_F14: KeyCode.Unknown, // MISSING
VKEY_F15: KeyCode.Unknown, // MISSING
VKEY_F16: KeyCode.Unknown, // MISSING
VKEY_F17: KeyCode.Unknown, // MISSING
VKEY_F18: KeyCode.Unknown, // MISSING
VKEY_F19: KeyCode.Unknown, // MISSING
VKEY_F20: KeyCode.Unknown, // MISSING
VKEY_F21: KeyCode.Unknown, // MISSING
VKEY_F22: KeyCode.Unknown, // MISSING
VKEY_F23: KeyCode.Unknown, // MISSING
VKEY_F24: KeyCode.Unknown, // MISSING
VKEY_NUMLOCK: KeyCode.NumLock,
VKEY_SCROLL: KeyCode.ScrollLock,
VKEY_LSHIFT: KeyCode.Shift,
VKEY_RSHIFT: KeyCode.Shift,
VKEY_LCONTROL: KeyCode.Ctrl,
VKEY_RCONTROL: KeyCode.Ctrl,
VKEY_LMENU: KeyCode.Unknown, // MISSING
VKEY_RMENU: KeyCode.Unknown, // MISSING
VKEY_BROWSER_BACK: KeyCode.Unknown, // MISSING
VKEY_BROWSER_FORWARD: KeyCode.Unknown, // MISSING
VKEY_BROWSER_REFRESH: KeyCode.Unknown, // MISSING
VKEY_BROWSER_STOP: KeyCode.Unknown, // MISSING
VKEY_BROWSER_SEARCH: KeyCode.Unknown, // MISSING
VKEY_BROWSER_FAVORITES: KeyCode.Unknown, // MISSING
VKEY_BROWSER_HOME: KeyCode.Unknown, // MISSING
VKEY_VOLUME_MUTE: KeyCode.Unknown, // MISSING
VKEY_VOLUME_DOWN: KeyCode.Unknown, // MISSING
VKEY_VOLUME_UP: KeyCode.Unknown, // MISSING
VKEY_MEDIA_NEXT_TRACK: KeyCode.Unknown, // MISSING
VKEY_MEDIA_PREV_TRACK: KeyCode.Unknown, // MISSING
VKEY_MEDIA_STOP: KeyCode.Unknown, // MISSING
VKEY_MEDIA_PLAY_PAUSE: KeyCode.Unknown, // MISSING
VKEY_MEDIA_LAUNCH_MAIL: KeyCode.Unknown, // MISSING
VKEY_MEDIA_LAUNCH_MEDIA_SELECT: KeyCode.Unknown, // MISSING
VKEY_MEDIA_LAUNCH_APP1: KeyCode.Unknown, // MISSING
VKEY_MEDIA_LAUNCH_APP2: KeyCode.Unknown, // MISSING
VKEY_OEM_1: KeyCode.US_SEMICOLON,
VKEY_OEM_PLUS: KeyCode.US_EQUAL,
VKEY_OEM_COMMA: KeyCode.US_COMMA,
VKEY_OEM_MINUS: KeyCode.US_MINUS,
VKEY_OEM_PERIOD: KeyCode.US_DOT,
VKEY_OEM_2: KeyCode.US_SLASH,
VKEY_OEM_3: KeyCode.US_BACKTICK,
VKEY_OEM_4: KeyCode.US_OPEN_SQUARE_BRACKET,
VKEY_OEM_5: KeyCode.US_BACKSLASH,
VKEY_OEM_6: KeyCode.US_CLOSE_SQUARE_BRACKET,
VKEY_OEM_7: KeyCode.US_QUOTE,
VKEY_OEM_8: KeyCode.Unknown, // MISSING
VKEY_OEM_102: KeyCode.Unknown, // MISSING
VKEY_PROCESSKEY: KeyCode.Unknown, // MISSING
VKEY_PACKET: KeyCode.Unknown, // MISSING
VKEY_DBE_SBCSCHAR: KeyCode.Unknown, // MISSING
VKEY_DBE_DBCSCHAR: KeyCode.Unknown, // MISSING
VKEY_ATTN: KeyCode.Unknown, // MISSING
VKEY_CRSEL: KeyCode.Unknown, // MISSING
VKEY_EXSEL: KeyCode.Unknown, // MISSING
VKEY_EREOF: KeyCode.Unknown, // MISSING
VKEY_PLAY: KeyCode.Unknown, // MISSING
VKEY_ZOOM: KeyCode.Unknown, // MISSING
VKEY_NONAME: KeyCode.Unknown, // MISSING
VKEY_PA1: KeyCode.Unknown, // MISSING
VKEY_OEM_CLEAR: KeyCode.Unknown, // MISSING
VKEY_UNKNOWN: KeyCode.Unknown,
// Windows does not have a specific key code for AltGr. We use the unused
// VK_OEM_AX to represent AltGr, matching the behaviour of Firefox on Linux.
VKEY_ALTGR: KeyCode.Unknown, // MISSING
};
// See http://www.w3.org/TR/DOM-Level-3-Events/#h-optionally-fixed-virtual-key-codes
// See issue #1302: Chromium has implemented section B.2.4 of DOM Level 3 Events on mac
// This is bad news because we cannot trust the event's keyCode to be the actual pressed key.
// Here we try to find out the actual pressed key by "undoing" their massaging
// Key Character Virtual Key Code
// Semicolon ';' 186
// Colon ':' 186
// Equals sign '=' 187
// Plus '+' 187
// Comma ',' 188
// Less than sign '<' 188
// Minus '-' 189
// Underscore '_' 189
// Period '.' 190
// Greater than sign '>' 190
// Forward slash '/' 191
// Question mark '?' 191
// Backtick '`' 192
// Tilde '~' 192
// Opening square bracket '[' 219
// Opening curly brace '{' 219
// Backslash '\' 220
// Pipe '|' 220
// Closing square bracket ']' 221
// Closing curly brace '}' 221
// Single quote ''' 222
// Double quote '"' 222
interface IFixedVirtualKeyCodeElement {
char:string;
virtualKeyCode:number;
}
let _b24_fixedVirtualKeyCodes: IFixedVirtualKeyCodeElement[] = [
{ char: ';', virtualKeyCode: 186 },
{ char: ':', virtualKeyCode: 186 },
{ char: '=', virtualKeyCode: 187 },
{ char: '+', virtualKeyCode: 187 },
{ char: ',', virtualKeyCode: 188 },
{ char: '<', virtualKeyCode: 188 },
{ char: '-', virtualKeyCode: 189 },
{ char: '_', virtualKeyCode: 189 },
{ char: '.', virtualKeyCode: 190 },
{ char: '>', virtualKeyCode: 190 },
{ char: '/', virtualKeyCode: 191 },
{ char: '?', virtualKeyCode: 191 },
{ char: '`', virtualKeyCode: 192 },
{ char: '~', virtualKeyCode: 192 },
{ char: '[', virtualKeyCode: 219 },
{ char: '{', virtualKeyCode: 219 },
{ char: '\\', virtualKeyCode: 220 },
{ char: '|', virtualKeyCode: 220 },
{ char: ']', virtualKeyCode: 221 },
{ char: '}', virtualKeyCode: 221 },
{ char: '\'', virtualKeyCode: 222 },
{ char: '"', virtualKeyCode: 222 },
];
let _b24_interestingChars: {[char:string]:boolean;} = Object.create(null);
_b24_fixedVirtualKeyCodes.forEach(el => _b24_interestingChars[el.char] = true);
let _b24_interestingVirtualKeyCodes: {[virtualKeyCode:number]:boolean;} = Object.create(null);
_b24_fixedVirtualKeyCodes.forEach(el => _b24_interestingVirtualKeyCodes[el.virtualKeyCode] = true);
interface IUnfixedVirtualKeyCodeMap {
[char:string]: KeyCode;
}
let _b24_getActualKeyCodeMap = (function() {
var result: IUnfixedVirtualKeyCodeMap = null;
return function() {
if (!result) {
result = Object.create(null);
let nativeMappings = getNativeKeymap();
for (let i = 0, len = nativeMappings.length; i < len; i++) {
let nativeMapping = nativeMappings[i];
if (nativeMapping.value && _b24_interestingChars[nativeMapping.value]) {
let keyCode = NATIVE_KEY_CODE_TO_KEY_CODE[nativeMapping.key_code];
if (keyCode && keyCode !== KeyCode.Unknown) {
result[nativeMapping.value] = keyCode;
}
}
if (nativeMapping.withShift && _b24_interestingChars[nativeMapping.withShift]) {
let keyCode = NATIVE_KEY_CODE_TO_KEY_CODE[nativeMapping.key_code];
if (keyCode && keyCode !== KeyCode.Unknown) {
result[nativeMapping.withShift] = keyCode;
}
}
}
}
return result;
}
})();
setExtractKeyCode((e:KeyboardEvent) => {
if (e.charCode) {
// "keypress" events mostly
let char = String.fromCharCode(e.charCode).toUpperCase();
return KeyCode.fromString(char);
}
if (Platform.isMacintosh && _b24_interestingVirtualKeyCodes[e.keyCode] && typeof (<any>e).keyIdentifier === 'string') {
let keyIdentifier:string = (<any>e).keyIdentifier;
let strCharCode = keyIdentifier.substr(2);
try {
let charCode = parseInt(strCharCode, 16);
let char = String.fromCharCode(charCode);
// console.log(keyIdentifier + ' => ' + char);
} catch(err) {
}
}
// _b24_getActualKeyCodeMap();
// console.log('injected!!!');
return lookupKeyCode(e);
});
export default class PluginWorkbenchKeybindingService extends WorkbenchKeybindingService {
private _pluginService: IPluginService;
......@@ -225,18 +538,18 @@ export default class PluginWorkbenchKeybindingService extends WorkbenchKeybindin
// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
// See https://github.com/alexandrudima/vscode-keyboard/blob/master/deps/chromium/keyboard_codes_win.h
let interestingKeyCodes:{[vkeyCode:string]:KeyCode;} = {
VKEY_OEM_1: KeyCode.US_SEMICOLON, // (0xBA) as ;
VKEY_OEM_PLUS: KeyCode.US_EQUAL, // (0xBB) as =
VKEY_OEM_COMMA: KeyCode.US_COMMA, // (0xBC) as ,
VKEY_OEM_MINUS: KeyCode.US_MINUS, // (0xBD) as -
VKEY_OEM_PERIOD: KeyCode.US_DOT, // (0xBE) as .
VKEY_OEM_2: KeyCode.US_SLASH, // (0xBF) as /
VKEY_OEM_3: KeyCode.US_BACKTICK, // (0xC0) as `
VKEY_OEM_4: KeyCode.US_OPEN_SQUARE_BRACKET, // (0xDB) as [
VKEY_OEM_5: KeyCode.US_BACKSLASH, // (0xDC) as \
VKEY_OEM_6: KeyCode.US_CLOSE_SQUARE_BRACKET, // (0xDD) as ]
VKEY_OEM_7: KeyCode.US_QUOTE, // (0xDE) as '
let interestingKeyCodes:{[vkeyCode:string]:boolean;} = {
VKEY_OEM_1: true,
VKEY_OEM_PLUS: true,
VKEY_OEM_COMMA: true,
VKEY_OEM_MINUS: true,
VKEY_OEM_PERIOD: true,
VKEY_OEM_2: true,
VKEY_OEM_3: true,
VKEY_OEM_4: true,
VKEY_OEM_5: true,
VKEY_OEM_6: true,
VKEY_OEM_7: true,
};
let remaps:string[] = [];
......@@ -244,7 +557,7 @@ export default class PluginWorkbenchKeybindingService extends WorkbenchKeybindin
remaps[i] = null;
}
let nativeMappings = nativeKeymap.getKeyMap();
let nativeMappings = getNativeKeymap();
let hadRemap = false;
for (let i = 0, len = nativeMappings.length; i < len; i++) {
let nativeMapping = nativeMappings[i];
......@@ -253,7 +566,7 @@ export default class PluginWorkbenchKeybindingService extends WorkbenchKeybindin
let newValue = nativeMapping.value || nativeMapping.withShift;
if (newValue.length > 0) {
hadRemap = true;
remaps[interestingKeyCodes[nativeMapping.key_code]] = newValue;
remaps[NATIVE_KEY_CODE_TO_KEY_CODE[nativeMapping.key_code]] = newValue;
} else {
console.warn('invalid remap for ', nativeMapping);
}
......@@ -263,7 +576,7 @@ export default class PluginWorkbenchKeybindingService extends WorkbenchKeybindin
if (hadRemap) {
for (let interestingKeyCode in interestingKeyCodes) {
if (interestingKeyCodes.hasOwnProperty(interestingKeyCode)) {
let keyCode = interestingKeyCodes[interestingKeyCode];
let keyCode = NATIVE_KEY_CODE_TO_KEY_CODE[interestingKeyCode];
remaps[keyCode] = remaps[keyCode] || '';
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册