/*
* noVNC: HTML5 VNC client
- * Copyright (C) 2018 The noVNC Authors
+ * Copyright (C) 2019 The noVNC Authors
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
*/
'keydown': this._handleKeyDown.bind(this),
'keypress': this._handleKeyPress.bind(this),
'blur': this._allKeysUp.bind(this),
- 'checkalt': this._checkAlt.bind(this),
};
// ===== EVENT HANDLERS =====
// We cannot handle keys we cannot track, but we also need
// to deal with virtual keyboards which omit key info
- // (iOS omits tracking info on keyup events, which forces us to
- // special treat that platform here)
- if ((code === 'Unidentified') || browser.isIOS()) {
+ if (code === 'Unidentified') {
if (keysym) {
// If it's a virtual keyboard then it should be
// sufficient to just send press and release right
// keys around a bit to make things more sane for the remote
// server. This method is used by RealVNC and TigerVNC (and
// possibly others).
- if (browser.isMac()) {
+ if (browser.isMac() || browser.isIOS()) {
switch (keysym) {
case KeyTable.XK_Super_L:
keysym = KeyTable.XK_Alt_L;
// state change events. That gets extra confusing for CapsLock
// which toggles on each press, but not on release. So pretend
// it was a quick press and release of the button.
- if (browser.isMac() && (code === 'CapsLock')) {
+ if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
stopEvent(e);
// If this is a legacy browser then we'll need to wait for
// a keypress event as well
- // (IE and Edge has a broken KeyboardEvent.key, so we can't
+ // (Edge has a broken KeyboardEvent.key, so we can't
// just check for the presence of that field)
- if (!keysym && (!e.key || browser.isIE() || browser.isEdge())) {
+ if (!keysym && (!e.key || browser.isEdge())) {
this._pendingKey = code;
// However we might not get a keypress event if the key
// is non-printable, which needs some special fallback
}
// See comment in _handleKeyDown()
- if (browser.isMac() && (code === 'CapsLock')) {
+ if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true);
this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false);
return;
}
this._sendKeyEvent(this._keyDownList[code], code, false);
+
+ // Windows has a rather nasty bug where it won't send key
+ // release events for a Shift button if the other Shift is still
+ // pressed
+ if (browser.isWindows() && ((code === 'ShiftLeft') ||
+ (code === 'ShiftRight'))) {
+ if ('ShiftRight' in this._keyDownList) {
+ this._sendKeyEvent(this._keyDownList['ShiftRight'],
+ 'ShiftRight', false);
+ }
+ if ('ShiftLeft' in this._keyDownList) {
+ this._sendKeyEvent(this._keyDownList['ShiftLeft'],
+ 'ShiftLeft', false);
+ }
+ }
}
_handleAltGrTimeout() {
Log.Debug("<< Keyboard.allKeysUp");
}
- // Alt workaround for Firefox on Windows, see below
- _checkAlt(e) {
- if (e.skipCheckAlt) {
- return;
- }
- if (e.altKey) {
- return;
- }
-
- const target = this._target;
- const downList = this._keyDownList;
- ['AltLeft', 'AltRight'].forEach((code) => {
- if (!(code in downList)) {
- return;
- }
-
- const event = new KeyboardEvent('keyup',
- { key: downList[code],
- code: code });
- event.skipCheckAlt = true;
- target.dispatchEvent(event);
- });
- }
-
// ===== PUBLIC METHODS =====
grab() {
// Release (key up) if window loses focus
window.addEventListener('blur', this._eventHandlers.blur);
- // Firefox on Windows has broken handling of Alt, so we need to
- // poll as best we can for releases (still doesn't prevent the
- // menu from popping up though as we can't call
- // preventDefault())
- if (browser.isWindows() && browser.isFirefox()) {
- const handler = this._eventHandlers.checkalt;
- ['mousedown', 'mouseup', 'mousemove', 'wheel',
- 'touchstart', 'touchend', 'touchmove',
- 'keydown', 'keyup'].forEach(type =>
- document.addEventListener(type, handler,
- { capture: true,
- passive: true }));
- }
-
//Log.Debug("<< Keyboard.grab");
}
ungrab() {
//Log.Debug(">> Keyboard.ungrab");
- if (browser.isWindows() && browser.isFirefox()) {
- const handler = this._eventHandlers.checkalt;
- ['mousedown', 'mouseup', 'mousemove', 'wheel',
- 'touchstart', 'touchend', 'touchmove',
- 'keydown', 'keyup'].forEach(type => document.removeEventListener(type, handler));
- }
-
this._target.removeEventListener('keydown', this._eventHandlers.keydown);
this._target.removeEventListener('keyup', this._eventHandlers.keyup);
this._target.removeEventListener('keypress', this._eventHandlers.keypress);