Simplify handling of keypress

Use a dedicated variable to track a two stage key rather than
piggy-backing on the key state array.
This commit is contained in:
Pierre Ossman 2017-01-27 12:24:20 +01:00
parent f7363fd26d
commit 9fce233d51
2 changed files with 40 additions and 17 deletions

View File

@ -21,6 +21,7 @@ import * as KeyboardUtil from "./util.js";
const Keyboard = function (defaults) {
this._keyDownList = []; // List of depressed keys
// (even if they are happy)
this._pendingKey = null; // Key waiting for keypress
this._modifierState = KeyboardUtil.ModifierSync();
@ -75,12 +76,15 @@ Keyboard.prototype = {
var keysym = KeyboardUtil.getKeysym(e);
// If this is a legacy browser then we'll need to wait for
// a keypress event as well. Otherwise we supress the
// browser's handling at this point
if (keysym) {
stopEvent(e);
// a keypress event as well
if (!keysym) {
this._pendingKey = code;
return;
}
this._pendingKey = null;
stopEvent(e);
// if a char modifier is pressed, get the keys it consists
// of (on Windows, AltGr is equivalent to Ctrl+Alt)
var active = this._modifierState.activeCharModifier();
@ -90,7 +94,7 @@ Keyboard.prototype = {
// the modifier as a char modifier, and (b) we'll have to
// "escape" the modifier to undo the modifier when sending
// the char.
if (active && keysym) {
if (active) {
var isCharModifier = false;
for (var i = 0; i < active.length; ++i) {
if (active[i] === keysym) {
@ -115,15 +119,9 @@ Keyboard.prototype = {
this._keyDownList.push(last);
}
// Wait for keypress?
if (!keysym) {
return;
}
// make sure last event contains this keysym (a single "logical" keyevent
// can cause multiple key events to be sent to the VNC server)
last.keysyms[keysym] = keysym;
last.ignoreKeyPress = true;
// undo modifiers
if (escape) {
@ -149,9 +147,22 @@ Keyboard.prototype = {
stopEvent(e);
// Are we expecting a keypress?
if (this._pendingKey === null) {
return;
}
var code = this._getKeyCode(e);
var keysym = KeyboardUtil.getKeysym(e);
// The key we were waiting for?
if ((code !== 'Unidentified') && (code != this._pendingKey)) {
return;
}
code = this._pendingKey;
this._pendingKey = null;
// if a char modifier is pressed, get the keys it consists
// of (on Windows, AltGr is equivalent to Ctrl+Alt)
var active = this._modifierState.activeCharModifier();
@ -189,12 +200,6 @@ Keyboard.prototype = {
return;
}
// If we didn't expect a keypress, and already sent a keydown to the VNC server
// based on the keydown, make sure to skip this event.
if (last.ignoreKeyPress) {
return;
}
last.keysyms[keysym] = keysym;
// undo modifiers

View File

@ -65,6 +65,24 @@ describe('Key Event Handling', function() {
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyA', charCode: 0x61}));
});
it('should ignore keypress with different code', function() {
var callback = sinon.spy();
var kbd = new Keyboard({onKeyEvent: callback});
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
kbd._handleKeyPress(keyevent('keypress', {code: 'KeyB', charCode: 0x61}));
expect(callback).to.not.have.been.called;
});
it('should handle keypress with missing code', function(done) {
var kbd = new Keyboard({
onKeyEvent: function(keysym, code, down) {
expect(keysym).to.be.equal(0x61);
expect(code).to.be.equal('KeyA');
expect(down).to.be.equal(true);
done();
}});
kbd._handleKeyDown(keyevent('keydown', {code: 'KeyA', keyCode: 0x41}));
kbd._handleKeyPress(keyevent('keypress', {charCode: 0x61}));
});
});
describe('suppress the right events at the right time', function() {