]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Add resize as a capability
authorPierre Ossman <ossman@cendio.se>
Fri, 13 Oct 2017 12:40:25 +0000 (14:40 +0200)
committerPierre Ossman <ossman@cendio.se>
Thu, 9 Nov 2017 11:51:15 +0000 (12:51 +0100)
Makes the API more transparent than piggybacking on completion
of the first framebuffer update.

app/ui.js
core/rfb.js
docs/API.md
tests/test.rfb.js
vnc_lite.html

index 6f1690ec14a8d206388cc857bc748530c746838e..1aa5f8ccd9aef4bff4cdf9d6222f13638af57ba1 100644 (file)
--- a/app/ui.js
+++ b/app/ui.js
@@ -207,10 +207,9 @@ var UI = {
                               'onUpdateState': UI.updateState,
                               'onDisconnected': UI.disconnectFinished,
                               'onCredentialsRequired': UI.credentials,
-                              'onCapabilities': UI.updatePowerButton,
+                              'onCapabilities': function () { UI.updatePowerButton(); UI.initialResize(); },
                               'onClipboard': UI.clipboardReceive,
                               'onBell': UI.bell,
-                              'onFBUComplete': UI.initialResize,
                               'onFBResize': UI.updateSessionSize,
                               'onDesktopName': UI.updateDesktopName});
             return true;
@@ -431,6 +430,7 @@ var UI = {
             case 'connected':
                 UI.connected = true;
                 UI.inhibit_reconnect = false;
+                UI.doneInitialResize = false;
                 document.documentElement.classList.add("noVNC_connected");
                 if (rfb && rfb.get_encrypt()) {
                     msg = _("Connected (encrypted) to ") + UI.desktopName;
@@ -1079,9 +1079,6 @@ var UI = {
         // Disable automatic reconnecting
         UI.inhibit_reconnect = true;
 
-        // Restore the callback used for initial resize
-        UI.rfb.set_onFBUComplete(UI.initialResize);
-
         // Don't display the connection settings until we're actually disconnected
     },
 
@@ -1275,13 +1272,14 @@ var UI = {
     // Normally we only apply the current resize mode after a window resize
     // event. This means that when a new connection is opened, there is no
     // resize mode active.
-    // We have to wait until the first FBU because this is where the client
-    // will find the supported encodings of the server. Some calls later in
-    // the chain is dependant on knowing the server-capabilities.
-    initialResize: function(rfb, fbu) {
+    // We have to wait until we know the capabilities of the server as
+    // some calls later in the chain is dependant on knowing the
+    // server-capabilities.
+    initialResize: function() {
+        if (UI.doneInitialResize) return;
+
         UI.applyResizeMode();
-        // After doing this once, we remove the callback.
-        UI.rfb.set_onFBUComplete(function() { });
+        UI.doneInitialResize = true;
     },
 
 /* ------^-------
index 5b66abb43d8df6839a234244cada1e5289a7d1dd..fb2f4302d4c438e65875ce5697a2598034ff920b 100644 (file)
@@ -49,7 +49,7 @@ export default function RFB(defaults) {
     this._rfb_tightvnc = false;
     this._rfb_xvp_ver = 0;
 
-    this._capabilities = { power: false };
+    this._capabilities = { power: false, resize: false };
 
     this._encHandlers = {};
     this._encStats = {};
@@ -638,6 +638,11 @@ RFB.prototype = {
         }
     },
 
+    _setCapability: function (cap, val) {
+        this._capabilities[cap] = val;
+        this._onCapabilities(this, this._capabilities);
+    },
+
     _handle_message: function () {
         if (this._sock.rQlen() === 0) {
             Log.Warn("handle_message called on an empty receive queue");
@@ -1277,8 +1282,7 @@ RFB.prototype = {
             case 1:  // XVP_INIT
                 this._rfb_xvp_ver = xvp_ver;
                 Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")");
-                this._capabilities.power = true;
-                this._onCapabilities(this, this._capabilities)
+                this._setCapability("power", true);
                 break;
             default:
                 this._fail("Unexpected server message",
@@ -2398,6 +2402,8 @@ RFB.encodingHandlers = {
         if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) { return false; }
 
         this._supportsSetDesktopSize = true;
+        this._setCapability("resize", true);
+
         var number_of_screens = this._sock.rQpeek8();
 
         this._FBU.bytes = 4 + (number_of_screens * 16);
index 92222e67c36c417005a6d6e01404ec45241e4d7c..18d92397d955ed261345ca8e87a43d0ae76fb767 100644 (file)
@@ -41,7 +41,7 @@ attribute mode is one of the following:
 | wsProtocols       | arr   | RW   | ['binary'] | Protocols to use in the WebSocket connection
 | repeaterID        | str   | RW   | ''         | UltraVNC RepeaterID to connect to
 | viewportDrag      | bool  | RW   | false      | Move the viewport on mouse drags
-| capabilities      | arr   | RO   | []         | Supported capabilities (can include: 'power')
+| capabilities      | arr   | RO   | []         | Supported capabilities (can include: 'power', 'resize')
 
 
 ## 2 Methods
index f59a2fe341a79aae068303a11a52ccb846da321e..4c4b12f6afdb4c7f7a07c1cfeb0be8ac7a614d16 100644 (file)
@@ -1684,6 +1684,25 @@ describe('Remote Frame Buffer Protocol Client', function() {
                         return data;
                     }
 
+                    it('should call callback when resize is supported', function () {
+                        client.set_onCapabilities(sinon.spy());
+
+                        expect(client._supportsSetDesktopSize).to.be.false;
+                        expect(client.get_capabilities().resize).to.be.false;
+
+                        var reason_for_change = 0; // server initiated
+                        var status_code       = 0; // No error
+
+                        send_fbu_msg([{ x: reason_for_change, y: status_code,
+                                        width: 4, height: 4, encoding: -308 }],
+                                     make_screen_data(1), client);
+
+                        expect(client._supportsSetDesktopSize).to.be.true;
+                        expect(client.get_onCapabilities()).to.have.been.calledOnce;
+                        expect(client.get_onCapabilities().args[0][1].resize).to.be.true;
+                        expect(client.get_capabilities().resize).to.be.true;
+                    }),
+
                     it('should handle a resize requested by this client', function () {
                         var reason_for_change = 1; // requested by this client
                         var status_code       = 0; // No error
@@ -1692,7 +1711,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
                                         width: 20, height: 50, encoding: -308 }],
                                      make_screen_data(1), client);
 
-                        expect(client._supportsSetDesktopSize).to.be.true;
                         expect(client._fb_width).to.equal(20);
                         expect(client._fb_height).to.equal(50);
 
@@ -1712,7 +1730,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
                                         width: 20, height: 50, encoding: -308 }],
                                      make_screen_data(1), client);
 
-                        expect(client._supportsSetDesktopSize).to.be.true;
                         expect(client._fb_width).to.equal(20);
                         expect(client._fb_height).to.equal(50);
 
@@ -1732,7 +1749,6 @@ describe('Remote Frame Buffer Protocol Client', function() {
                                         width: 60, height: 50, encoding: -308 }],
                                      make_screen_data(3), client);
 
-                        expect(client._supportsSetDesktopSize).to.be.true;
                         expect(client._fb_width).to.equal(60);
                         expect(client._fb_height).to.equal(50);
 
@@ -1799,7 +1815,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
                 client._sock._websocket._receive_data(new Uint8Array([250, 0, 10, 1]));
                 expect(client._rfb_xvp_ver).to.equal(10);
                 expect(client.get_onCapabilities()).to.have.been.calledOnce;
-                expect(client.get_onCapabilities()).to.have.been.calledWith(client, { power: true });
+                expect(client.get_onCapabilities().args[0][1].power).to.be.true;
+                expect(client.get_capabilities().power).to.be.true;
             });
 
             it('should fail on unknown XVP message types', function () {
index e252aa5c252be1502188ecfe017d56f65d1642a8..f1bf6f376d37b988c7f31e7c9b433af7cf3dfa40 100644 (file)
@@ -80,6 +80,7 @@
         import RFB from './core/rfb.js';
 
         var rfb;
+        var doneInitialResize;
         var resizeTimeout;
         var desktopName;
 
                     rfb.requestDesktopSize(innerW, innerH - controlbarH);
             }
         }
-        function FBUComplete(rfb, fbu) {
+        function initialResize() {
+            if (doneInitialResize) return;
             UIresize();
-            rfb.set_onFBUComplete(function() { });
+            doneInitialResize = true;
         }
         function updateDesktopName(rfb, name) {
             desktopName = name;
                     status("Connecting", "normal");
                     break;
                 case 'connected':
+                    doneInitialResize = false;
                     if (rfb && rfb.get_encrypt()) {
                         status("Connected (encrypted) to " +
                                desktopName, "normal");
                                'onNotification':  notification,
                                'onUpdateState':  updateState,
                                'onDisconnected': disconnected,
-                               'onCapabilities': updatePowerButtons,
+                               'onCapabilities': function () { updatePowerButtons(); initialResize(); },
                                'onCredentialsRequired': credentials,
-                               'onFBUComplete': FBUComplete,
                                'onDesktopName': updateDesktopName});
             } catch (exc) {
                 status('Unable to create RFB client -- ' + exc, 'error');