]> git.proxmox.com Git - mirror_novnc.git/commitdiff
Support automatic resize [Part 1/4]: display.js
authorsamhed <samuel@cendio.se>
Fri, 6 Feb 2015 15:43:45 +0000 (16:43 +0100)
committersamhed <samuel@cendio.se>
Fri, 6 Feb 2015 15:54:14 +0000 (16:54 +0100)
* Split viewportChange into two functions, one for changing size and the other for changing position.
* Modified viewport code to be capable of changing to a bigger size in the context of a
  client-initiated resize.
* Made clearer distinctions between when viewport-clipping or not.
* Added public function for telling when viewport-clipping.
* Updated tests that were using viewportChange.

include/display.js
tests/test.display.js
tests/test.rfb.js
tests/viewport.html

index db45d7b1ddbd17ac8978401703efc9b101845473..d1278681fe8a1fbcc10e1992d592e834627ebea8 100644 (file)
@@ -111,54 +111,12 @@ var Display;
 
     Display.prototype = {
         // Public methods
-        viewportChange: function (deltaX, deltaY, width, height) {
+        viewportChangePos: function (deltaX, deltaY) {
             var vp = this._viewportLoc;
-            var cr = this._cleanRect;
-            var canvas = this._target;
 
             if (!this._viewport) {
-                Util.Debug("Setting viewport to full display region");
                 deltaX = -vp.w;  // clamped later of out of bounds
                 deltaY = -vp.h;
-                width = this._fb_width;
-                height = this._fb_height;
-            }
-
-            if (typeof(deltaX) === "undefined") { deltaX = 0; }
-            if (typeof(deltaY) === "undefined") { deltaY = 0; }
-            if (typeof(width) === "undefined") { width = vp.w; }
-            if (typeof(height) === "undefined") { height = vp.h; }
-
-            // Size change
-            if (width > this._fb_width) { width = this._fb_width; }
-            if (height > this._fb_height) { height = this._fb_height; }
-
-            if (vp.w !== width || vp.h !== height) {
-                // Change width
-                if (width < vp.w &&  cr.x2 > vp.x + width - 1) {
-                    cr.x2 = vp.x + width - 1;
-                }
-                vp.w = width;
-
-                // Change height
-                if (height < vp.h &&  cr.y2 > vp.y + height - 1) {
-                    cr.y2 = vp.y + height - 1;
-                }
-                vp.h = height;
-
-                var saveImg = null;
-                if (vp.w > 0 && vp.h > 0 && canvas.width > 0 && canvas.height > 0) {
-                    var img_width = canvas.width < vp.w ? canvas.width : vp.w;
-                    var img_height = canvas.height < vp.h ? canvas.height : vp.h;
-                    saveImg = this._drawCtx.getImageData(0, 0, img_width, img_height);
-                }
-
-                canvas.width = vp.w;
-                canvas.height = vp.h;
-
-                if (saveImg) {
-                    this._drawCtx.putImageData(saveImg, 0, 0);
-                }
             }
 
             var vx2 = vp.x + vp.w - 1;
@@ -191,6 +149,7 @@ var Display;
             vy2 += deltaY;
 
             // Update the clean rectangle
+            var cr = this._cleanRect;
             if (vp.x > cr.x1) {
                 cr.x1 = vp.x;
             }
@@ -228,6 +187,7 @@ var Display;
 
             // Copy the valid part of the viewport to the shifted location
             var saveStyle = this._drawCtx.fillStyle;
+            var canvas = this._target;
             this._drawCtx.fillStyle = "rgb(255,255,255)";
             if (deltaX !== 0) {
                 this._drawCtx.drawImage(canvas, 0, 0, vp.w, vp.h, -deltaX, 0, vp.w, vp.h);
@@ -240,6 +200,58 @@ var Display;
             this._drawCtx.fillStyle = saveStyle;
         },
 
+        viewportChangeSize: function(width, height) {
+
+            if (!this._viewport ||
+                typeof(width) === "undefined" || typeof(height) === "undefined") {
+
+                Util.Debug("Setting viewport to full display region");
+                width = this._fb_width;
+                height = this._fb_height;
+            }
+
+            var vp = this._viewportLoc;
+            if (vp.w !== width || vp.h !== height) {
+
+                var cr = this._cleanRect;
+
+                if (width < vp.w &&  cr.x2 > vp.x + width - 1) {
+                    cr.x2 = vp.x + width - 1;
+                }
+
+                if (height < vp.h &&  cr.y2 > vp.y + height - 1) {
+                    cr.y2 = vp.y + height - 1;
+                }
+
+                if (this.fbuClip()) {
+                    // clipping
+                    vp.w = window.innerWidth;
+                    var cb = document.getElementById('noVNC-control-bar');
+                    var controlbar_h = (cb !== null) ? cb.offsetHeight : 0;
+                    vp.h = window.innerHeight - controlbar_h - 5;
+                } else {
+                    // scrollbars
+                    vp.w = width;
+                    vp.h = height;
+                }
+
+                var saveImg = null;
+                var canvas = this._target;
+                if (vp.w > 0 && vp.h > 0 && canvas.width > 0 && canvas.height > 0) {
+                    var img_width = canvas.width < vp.w ? canvas.width : vp.w;
+                    var img_height = canvas.height < vp.h ? canvas.height : vp.h;
+                    saveImg = this._drawCtx.getImageData(0, 0, img_width, img_height);
+                }
+
+                canvas.width = vp.w;
+                canvas.height = vp.h;
+
+                if (saveImg) {
+                    this._drawCtx.putImageData(saveImg, 0, 0);
+                }
+            }
+        },
+
         // Return a map of clean and dirty areas of the viewport and reset the
         // tracking of clean and dirty areas
         //
@@ -305,7 +317,7 @@ var Display;
 
             this._rescale(this._scale);
 
-            this.viewportChange();
+            this.viewportChangeSize();
         },
 
         clear: function () {
@@ -475,6 +487,14 @@ var Display;
             this._target.style.cursor = "none";
         },
 
+        fbuClip: function () {
+            var cb = document.getElementById('noVNC-control-bar');
+            var controlbar_h = (cb !== null) ? cb.offsetHeight : 0;
+            return (this._viewport &&
+                    (this._fb_width > window.innerWidth
+                     || this._fb_height > window.innerHeight - controlbar_h - 5));
+        },
+
         // Overridden getters/setters
         get_context: function () {
             return this._drawCtx;
@@ -485,14 +505,14 @@ var Display;
         },
 
         set_width: function (w) {
-            this.resize(w, this._fb_height);
+            this._fb_width = w;
         },
         get_width: function () {
             return this._fb_width;
         },
 
         set_height: function (h) {
-            this.resize(this._fb_width, h);
+            this._fb_height =  h;
         },
         get_height: function () {
             return this._fb_height;
index 25adfbeacc19005661bf28dd2db284305a779f8b..949aca1e708672f6f54754d954dc508c49ae9a40 100644 (file)
@@ -65,13 +65,15 @@ describe('Display/Canvas Helper', function () {
         beforeEach(function () {
             display = new Display({ target: document.createElement('canvas'), prefer_js: false, viewport: true });
             display.resize(5, 5);
-            display.viewportChange(1, 1, 3, 3);
+            display.viewportChangeSize(3, 3);
+            display.viewportChangePos(1, 1);
             display.getCleanDirtyReset();
         });
 
         it('should take viewport location into consideration when drawing images', function () {
-            display.resize(4, 4);
-            display.viewportChange(0, 0, 2, 2);
+            display.set_width(4);
+            display.set_height(4);
+            display.viewportChangeSize(2, 2);
             display.drawImage(make_image_canvas(basic_data), 1, 1);
 
             var expected = new Uint8Array(16);
@@ -82,7 +84,7 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should redraw the left side when shifted left', function () {
-            display.viewportChange(-1, 0, 3, 3);
+            display.viewportChangePos(-1, 0);
             var cdr = display.getCleanDirtyReset();
             expect(cdr.cleanBox).to.deep.equal({ x: 1, y: 1, w: 2, h: 3 });
             expect(cdr.dirtyBoxes).to.have.length(1);
@@ -90,7 +92,7 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should redraw the right side when shifted right', function () {
-            display.viewportChange(1, 0, 3, 3);
+            display.viewportChangePos(1, 0);
             var cdr = display.getCleanDirtyReset();
             expect(cdr.cleanBox).to.deep.equal({ x: 2, y: 1, w: 2, h: 3 });
             expect(cdr.dirtyBoxes).to.have.length(1);
@@ -98,7 +100,7 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should redraw the top part when shifted up', function () {
-            display.viewportChange(0, -1, 3, 3);
+            display.viewportChangePos(0, -1);
             var cdr = display.getCleanDirtyReset();
             expect(cdr.cleanBox).to.deep.equal({ x: 1, y: 1, w: 3, h: 2 });
             expect(cdr.dirtyBoxes).to.have.length(1);
@@ -106,7 +108,7 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should redraw the bottom part when shifted down', function () {
-            display.viewportChange(0, 1, 3, 3);
+            display.viewportChangePos(0, 1);
             var cdr = display.getCleanDirtyReset();
             expect(cdr.cleanBox).to.deep.equal({ x: 1, y: 2, w: 3, h: 2 });
             expect(cdr.dirtyBoxes).to.have.length(1);
@@ -114,7 +116,7 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should reset the entire viewport to being clean after calculating the clean/dirty boxes', function () {
-            display.viewportChange(0, 1, 3, 3);
+            display.viewportChangePos(0, 1);
             var cdr1 = display.getCleanDirtyReset();
             var cdr2 = display.getCleanDirtyReset();
             expect(cdr1).to.not.deep.equal(cdr2);
@@ -146,9 +148,9 @@ describe('Display/Canvas Helper', function () {
         });
 
         it('should update the viewport dimensions', function () {
-            sinon.spy(display, 'viewportChange');
+            sinon.spy(display, 'viewportChangeSize');
             display.resize(2, 2);
-            expect(display.viewportChange).to.have.been.calledOnce;
+            expect(display.viewportChangeSize).to.have.been.calledOnce;
         });
     });
 
index d777a86096ee84ef7f41cca0b01f9dd5aee36cf7..2ac8a12905f83af1f3f9fca1a2221b4c12f2c175 100644 (file)
@@ -1593,7 +1593,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
 
             it('should not send movement messages when viewport dragging', function () {
                 client._viewportDragging = true;
-                client._display.viewportChange = sinon.spy();
+                client._display.viewportChangePos = sinon.spy();
                 client._mouse._onMouseMove(13, 9);
                 expect(client._sock.send).to.not.have.been.called;
             });
@@ -1622,14 +1622,14 @@ describe('Remote Frame Buffer Protocol Client', function() {
                 client._viewportDrag = true;
                 client._viewportDragging = true;
                 client._viewportDragPos = { x: 13, y: 9 };
-                client._display.viewportChange = sinon.spy();
+                client._display.viewportChangePos = sinon.spy();
 
                 client._mouse._onMouseMove(10, 4);
 
                 expect(client._viewportDragging).to.be.true;
                 expect(client._viewportDragPos).to.deep.equal({ x: 10, y: 4 });
-                expect(client._display.viewportChange).to.have.been.calledOnce;
-                expect(client._display.viewportChange).to.have.been.calledWith(3, 5);
+                expect(client._display.viewportChangePos).to.have.been.calledOnce;
+                expect(client._display.viewportChangePos).to.have.been.calledWith(3, 5);
             });
         });
 
index cb13ecf3572164e36348571da12b7f6126f957b4..374d8b1594c94853cc85ab6f2f7b6002cf86c070 100644 (file)
@@ -97,7 +97,7 @@
                 deltaY = lastPos.y - y; // drag frame buffer
                 lastPos = {'x': x, 'y': y};
 
-                display.viewportChange(deltaX, deltaY);
+                display.viewportChangePos(deltaX, deltaY);
                 return;
             }
 
             var p = $D('canvas').parentNode;
             message("doResize1: [" + (p.offsetWidth - padW) +
                     "," + (p.offsetHeight - padH) + "]");
-            display.viewportChange(0, 0,
-                p.offsetWidth - padW, p.offsetHeight - padH);
+            display.viewportChangeSize(p.offsetWidth - padW, p.offsetHeight - padH);
             /*
             var pos, new_w, new_h;pos
             pos = Util.getPosition($D('canvas').parentNode);
             new_w = window.innerWidth - pos.x;
             new_h = window.innerHeight - pos.y;
-            display.viewportChange(0, 0, new_w, new_h);
+            display.viewportChangeSize(new_w, new_h);
             */
         }
 
             Util.addEvent(window, 'resize', doResize);
             // Shrink viewport for first resize call so that the
             // scrollbars are disabled
-            display.viewportChange(0, 0, 10, 10);
+            display.viewportChangeSize(10, 10);
             setTimeout(doResize, 1);
             setInterval(dirtyRedraw, 50);