fix(meta-key): fix edge cases for meta key usage. (#761)

This commit is contained in:
Nick Randall 2016-10-03 09:29:33 -06:00 committed by Leo Lamprecht
parent de1a01ff57
commit ee172c3164
2 changed files with 97 additions and 9 deletions

View file

@ -1,4 +1,5 @@
import {hterm, lib} from 'hterm-umdjs';
import fromCharCode from './utils/key-code';
const selection = require('./utils/selection');
@ -39,6 +40,8 @@ hterm.Terminal.prototype.copySelectionToClipboard = function () {
// hyperterm and not the terminal itself
const oldKeyDown = hterm.Keyboard.prototype.onKeyDown_;
hterm.Keyboard.prototype.onKeyDown_ = function (e) {
const modifierKeysConf = this.terminal.modifierKeys;
/**
* Add fixes for U.S. International PC Keyboard layout
* These keys are sent through as 'Dead' keys, as they're used as modifiers.
@ -58,7 +61,7 @@ hterm.Keyboard.prototype.onKeyDown_ = function (e) {
return;
}
// This key is also a tilde on all tested keyboards
if (e.code === 'KeyN' && e.altKey === true) {
if (e.code === 'KeyN' && e.altKey === true && modifierKeysConf.altIsMeta === false) {
this.terminal.onVTKeystroke('~');
return;
}
@ -80,11 +83,11 @@ hterm.Keyboard.prototype.onKeyDown_ = function (e) {
return;
}
// Italian keyboard layout
if (e.code === 'Digit9' && e.altKey === true) {
if (e.code === 'Digit9' && e.altKey === true && modifierKeysConf.altIsMeta === false) {
this.terminal.onVTKeystroke('`');
return;
}
if (e.code === 'Digit8' && e.altKey === true) {
if (e.code === 'Digit8' && e.altKey === true && modifierKeysConf.altIsMeta === false) {
this.terminal.onVTKeystroke('´');
// To fix issue with changing the terminal prompt
e.preventDefault();
@ -102,21 +105,27 @@ hterm.Keyboard.prototype.onKeyDown_ = function (e) {
console.warn('Uncaught dead key on international keyboard', e);
}
const modifierKeysConf = this.terminal.modifierKeys;
if (e.altKey &&
e.code !== 'alt' &&
e.code !== 'altLeft' &&
e.code !== 'altRight' &&
e.which !== 16 && // Ignore other modifer keys
e.which !== 17 &&
e.which !== 18 &&
e.which !== 91 &&
modifierKeysConf.altIsMeta) {
this.terminal.onVTKeystroke('\x1b' + String.fromCharCode(e.keyCode));
const char = fromCharCode(e);
this.terminal.onVTKeystroke('\x1b' + char);
e.preventDefault();
}
if (e.metaKey &&
e.code !== 'MetaLeft' &&
e.code !== 'MetaRight' &&
e.which !== 16 &&
e.which !== 17 &&
e.which !== 18 &&
e.which !== 91 &&
modifierKeysConf.cmdIsMeta) {
this.terminal.onVTKeystroke('\x1b' + String.fromCharCode(e.keyCode));
const char = fromCharCode(e);
this.terminal.onVTKeystroke('\x1b' + char);
e.preventDefault();
}

79
lib/utils/key-code.js Normal file
View file

@ -0,0 +1,79 @@
/**
* Keyboard event keyCodes have proven to be really unreliable.
* This util function will cover most of the edge cases where
* String.fromCharCode() will not work
*/
const _toAscii = {
'188': '44',
'109': '45',
'190': '46',
'191': '47',
'192': '96',
'220': '92',
'222': '39',
'221': '93',
'219': '91',
'173': '45',
'187': '61', // IE Key codes
'186': '59', // IE Key codes
'189': '45' // IE Key codes
};
const _shiftUps = {
'96': '~',
'49': '!',
'50': '@',
'51': '#',
'52': '$',
'53': '%',
'54': '^',
'55': '&',
'56': '*',
'57': '(',
'48': ')',
'45': '_',
'61': '+',
'91': '{',
'93': '}',
'92': '|',
'59': ':',
'39': '\'',
'44': '<',
'46': '>',
'47': '?'
};
const _arrowKeys = {
'38': '',
'40': '',
'39': '',
'37': ''
};
/**
* This fn takes a keyboard event and returns
* the character that was pressed. This fn
* purposely doens't take into account if the alt/meta
* key was pressed.
*/
export default function fromCharCode(e) {
let code = String(e.which);
if ({}.hasOwnProperty.call(_arrowKeys, code)) {
return _arrowKeys[code];
}
if ({}.hasOwnProperty.call(_toAscii, code)) {
code = _toAscii[code];
}
const char = String.fromCharCode(code);
if (e.shiftKey) {
if ({}.hasOwnProperty.call(_shiftUps, code)) {
return _shiftUps[code];
}
return char.toUpperCase();
}
return char.toLowerCase();
}