]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Send keyboard events from single place
authorPierre Ossman <ossman@cendio.se>
Thu, 26 Jan 2017 16:59:25 +0000 (17:59 +0100)
committerPierre Ossman <ossman@cendio.se>
Thu, 4 May 2017 10:13:47 +0000 (12:13 +0200)
This makes it easier to handle any needed variations, like different
types of messages.

app/ui.js
core/rfb.js
tests/test.rfb.js

index cd0901b3a34451720e2d24438280580da960a0e8..b53aaeaad92bf04f91be80439fa782e0f1805a10 100644 (file)
--- a/app/ui.js
+++ b/app/ui.js
@@ -1516,7 +1516,7 @@ const UI = {
 
         // Send the key events
         for (i = 0; i < backspaces; i++) {
-            UI.rfb.sendKey(KeyTable.XK_BackSpace);
+            UI.rfb.sendKey(KeyTable.XK_BackSpace, "Backspace");
         }
         for (i = newLen - inputs; i < newLen; i++) {
             UI.rfb.sendKey(keysyms.lookup(newValue.charCodeAt(i)));
@@ -1573,7 +1573,7 @@ const UI = {
     },
 
     sendEsc: function() {
-        UI.rfb.sendKey(KeyTable.XK_Escape);
+        UI.rfb.sendKey(KeyTable.XK_Escape, "Escape");
     },
 
     sendTab: function() {
@@ -1583,10 +1583,10 @@ const UI = {
     toggleCtrl: function() {
         var btn = document.getElementById('noVNC_toggle_ctrl_button');
         if (btn.classList.contains("noVNC_selected")) {
-            UI.rfb.sendKey(KeyTable.XK_Control_L, false);
+            UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
             btn.classList.remove("noVNC_selected");
         } else {
-            UI.rfb.sendKey(KeyTable.XK_Control_L, true);
+            UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
             btn.classList.add("noVNC_selected");
         }
     },
@@ -1594,10 +1594,10 @@ const UI = {
     toggleAlt: function() {
         var btn = document.getElementById('noVNC_toggle_alt_button');
         if (btn.classList.contains("noVNC_selected")) {
-            UI.rfb.sendKey(KeyTable.XK_Alt_L, false);
+            UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
             btn.classList.remove("noVNC_selected");
         } else {
-            UI.rfb.sendKey(KeyTable.XK_Alt_L, true);
+            UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
             btn.classList.add("noVNC_selected");
         }
     },
index 9afe9e59e5a632be45d060490a598fda1f9a8247..7f55123cce1b461ee65daef8cdae4620310cdb53 100644 (file)
@@ -298,12 +298,13 @@ RFB.prototype = {
         if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; }
         Log.Info("Sending Ctrl-Alt-Del");
 
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 1);
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 1);
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 1);
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 0);
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 0);
-        RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 0);
+        this.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
+        this.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
+        this.sendKey(KeyTable.XK_Delete, "Delete", true);
+        this.sendKey(KeyTable.XK_Delete, "Delete", false);
+        this.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
+        this.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
+
         return true;
     },
 
@@ -328,16 +329,33 @@ RFB.prototype = {
 
     // Send a key press. If 'down' is not specified then send a down key
     // followed by an up key.
-    sendKey: function (keysym, down) {
+    sendKey: function (keysym, code, down) {
         if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; }
-        if (typeof down !== 'undefined') {
+
+        if (down === undefined) {
+            this.sendKey(keysym, code, true);
+            this.sendKey(keysym, code, false);
+            return true;
+        }
+
+        if (this._qemuExtKeyEventSupported) {
+            var scancode = XtScancode[code];
+
+            if (scancode === undefined) {
+                Log.Error('Unable to find a xt scancode for code: ' + code);
+                // FIXME: not in the spec, but this is what
+                // gtk-vnc does
+                scancode = 0;
+            }
+
+            Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);
+
+            RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
+        } else {
             Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);
             RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
-        } else {
-            Log.Info("Sending keysym (down + up): " + keysym);
-            RFB.messages.keyEvent(this._sock, keysym, 1);
-            RFB.messages.keyEvent(this._sock, keysym, 0);
         }
+
         return true;
     },
 
@@ -647,21 +665,8 @@ RFB.prototype = {
     },
 
     _handleKeyPress: function (keyevent) {
-        if (this._view_only) { return; } // View only, skip keyboard, events
-
         var down = (keyevent.type == 'keydown');
-        if (this._qemuExtKeyEventSupported) {
-            var scancode = XtScancode[keyevent.code];
-            if (scancode) {
-                var keysym = keyevent.keysym;
-                RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
-            } else {
-                Log.Error('Unable to find a xt scancode for code = ' + keyevent.code);
-            }
-        } else {
-            keysym = keyevent.keysym;
-            RFB.messages.keyEvent(this._sock, keysym, down);
-        }
+        this.sendKey(keyevent.keysym, keyevent.code, down);
     },
 
     _handleMouseButton: function (x, y, down, bmask) {
index c8035f40722a57f72ad66faf4da8f9b80fd7a079..70504a5fd47aa4a3ae6901a7e56cb23b0ef7dba7 100644 (file)
@@ -193,7 +193,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
             it('should send a single key with the given code and state (down = true)', function () {
                 var expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
                 RFB.messages.keyEvent(expected, 123, 1);
-                client.sendKey(123, true);
+                client.sendKey(123, 'Key123', true);
                 expect(client._sock).to.have.sent(expected._sQ);
             });
 
@@ -201,21 +201,29 @@ describe('Remote Frame Buffer Protocol Client', function() {
                 var expected = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function () {}};
                 RFB.messages.keyEvent(expected, 123, 1);
                 RFB.messages.keyEvent(expected, 123, 0);
-                client.sendKey(123);
+                client.sendKey(123, 'Key123');
                 expect(client._sock).to.have.sent(expected._sQ);
             });
 
             it('should not send the key if we are not in a normal state', function () {
                 client._rfb_connection_state = "broken";
-                client.sendKey(123);
+                client.sendKey(123, 'Key123');
                 expect(client._sock.flush).to.not.have.been.called;
             });
 
             it('should not send the key if we are set as view_only', function () {
                 client._view_only = true;
-                client.sendKey(123);
+                client.sendKey(123, 'Key123');
                 expect(client._sock.flush).to.not.have.been.called;
             });
+
+            it('should send QEMU extended events if supported', function () {
+                client._qemuExtKeyEventSupported = true;
+                var expected = {_sQ: new Uint8Array(12), _sQlen: 0, flush: function () {}};
+                RFB.messages.QEMUExtendedKeyEvent(expected, 0x20, true, 0x0039);
+                client.sendKey(0x20, 'Space', true);
+                expect(client._sock).to.have.sent(expected._sQ);
+            });
         });
 
         describe('#clipboardPasteFrom', function () {
@@ -2012,6 +2020,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
                 client._sock.open('ws://', 'binary');
                 client._sock._websocket._open();
                 sinon.spy(client._sock, 'flush');
+                client._rfb_connection_state = 'connected';
+                client._view_only = false;
             });
 
             it('should send a key message on a key press', function () {