]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Simplify handling of keypress
authorPierre Ossman <ossman@cendio.se>
Fri, 27 Jan 2017 11:24:20 +0000 (12:24 +0100)
committerPierre Ossman <ossman@cendio.se>
Thu, 4 May 2017 10:13:47 +0000 (12:13 +0200)
Use a dedicated variable to track a two stage key rather than
piggy-backing on the key state array.

core/input/devices.js
tests/test.keyboard.js

index f981c6f9fa0a13367f0575f6627bbbcfee73e6cd..d1c0649f05271e7cbf57c485521e6776fa91e839 100644 (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
index e4ee503f47235008034018c537645a409fb5051c..51c6b8f7d50d77aad81a825ff3d0194055dda596 100644 (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() {