diff --git a/include/display.js b/include/display.js index db45d7b..d127868 100644 --- a/include/display.js +++ b/include/display.js @@ -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; diff --git a/tests/test.display.js b/tests/test.display.js index 25adfbe..949aca1 100644 --- a/tests/test.display.js +++ b/tests/test.display.js @@ -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; }); }); diff --git a/tests/test.rfb.js b/tests/test.rfb.js index d777a86..2ac8a12 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -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); }); }); diff --git a/tests/viewport.html b/tests/viewport.html index cb13ecf..374d8b1 100644 --- a/tests/viewport.html +++ b/tests/viewport.html @@ -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; } @@ -166,14 +166,13 @@ 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); */ } @@ -194,7 +193,7 @@ 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);