Handle missing Shift events on Windows

This is a bug in the OS that leaks through to the browsers. We need
to fake a Shift release here to avoid Shift getting stuck in the remote
session.
pull/36/head
Pierre Ossman 6 years ago committed by Lauri Kasanen
parent 796de9653f
commit 740a8217ab

@ -281,6 +281,21 @@ export default class Keyboard {
}
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() {

@ -459,4 +459,74 @@ describe('Key Event Handling', function () {
expect(kbd.onkeyevent).to.have.been.calledWith(0xfe03, 'AltRight', true);
});
});
describe('Missing Shift keyup on Windows', function () {
let origNavigator;
beforeEach(function () {
// window.navigator is a protected read-only property in many
// environments, so we need to redefine it whilst running these
// tests.
origNavigator = Object.getOwnPropertyDescriptor(window, "navigator");
if (origNavigator === undefined) {
// Object.getOwnPropertyDescriptor() doesn't work
// properly in any version of IE
this.skip();
}
Object.defineProperty(window, "navigator", {value: {}});
if (window.navigator.platform !== undefined) {
// Object.defineProperty() doesn't work properly in old
// versions of Chrome
this.skip();
}
window.navigator.platform = "Windows x86_64";
this.clock = sinon.useFakeTimers();
});
afterEach(function () {
Object.defineProperty(window, "navigator", origNavigator);
this.clock.restore();
});
it('should fake a left Shift keyup', function () {
const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftLeft', key: 'Shift', location: 1}));
expect(kbd.onkeyevent).to.have.been.calledOnce;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', true);
kbd.onkeyevent.resetHistory();
kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftRight', key: 'Shift', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledOnce;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', true);
kbd.onkeyevent.resetHistory();
kbd._handleKeyUp(keyevent('keyup', {code: 'ShiftLeft', key: 'Shift', location: 1}));
expect(kbd.onkeyevent).to.have.been.calledTwice;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', false);
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', false);
});
it('should fake a right Shift keyup', function () {
const kbd = new Keyboard(document);
kbd.onkeyevent = sinon.spy();
kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftLeft', key: 'Shift', location: 1}));
expect(kbd.onkeyevent).to.have.been.calledOnce;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', true);
kbd.onkeyevent.resetHistory();
kbd._handleKeyDown(keyevent('keydown', {code: 'ShiftRight', key: 'Shift', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledOnce;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', true);
kbd.onkeyevent.resetHistory();
kbd._handleKeyUp(keyevent('keyup', {code: 'ShiftRight', key: 'Shift', location: 2}));
expect(kbd.onkeyevent).to.have.been.calledTwice;
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe2, 'ShiftRight', false);
expect(kbd.onkeyevent).to.have.been.calledWith(0xffe1, 'ShiftLeft', false);
});
});
});

Loading…
Cancel
Save