summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-01-27 12:24:20 +0100
committerPierre Ossman <ossman@cendio.se>2017-05-04 12:13:47 +0200
commit9fce233d51c803b08b6779bc8e906334de6916cf (patch)
treef1fdcdca4c5d22afa6db76123043885391e40490
parentf7363fd26dd7d9fced3bce4c629f5119d8b476ae (diff)
downloadnovnc-9fce233d51c803b08b6779bc8e906334de6916cf.tar.gz
Simplify handling of keypress
Use a dedicated variable to track a two stage key rather than piggy-backing on the key state array.
-rw-r--r--core/input/devices.js39
-rw-r--r--tests/test.keyboard.js18
2 files changed, 40 insertions, 17 deletions
diff --git a/core/input/devices.js b/core/input/devices.js
index f981c6f..d1c0649 100644
--- a/core/input/devices.js
+++ b/core/input/devices.js
@@ -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
diff --git a/tests/test.keyboard.js b/tests/test.keyboard.js
index e4ee503..51c6b8f 100644
--- a/tests/test.keyboard.js
+++ b/tests/test.keyboard.js
@@ -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() {