diff options
author | Samuel Mannehed <samuel@cendio.se> | 2021-09-03 17:51:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-03 17:51:18 +0200 |
commit | 784103761829b7c14579b7e26a18193310a194f4 (patch) | |
tree | 79c580df3c0d6c7e01add61def70603ea7491234 | |
parent | fcb95821b76e105ed4a7ce4c2c19549c8dbbeb44 (diff) | |
parent | 1afa18f09ee407fb8856ba28a3fc8f59021f7b23 (diff) | |
download | novnc-784103761829b7c14579b7e26a18193310a194f4.tar.gz |
Merge pull request #1365 from baleeds/feature/detect-parent-resize
feature: Detect parent resize
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | core/rfb.js | 14 | ||||
-rw-r--r-- | tests/test.rfb.js | 32 |
3 files changed, 31 insertions, 17 deletions
@@ -91,7 +91,7 @@ noVNC uses many modern web technologies so a formal requirement list is not available. However these are the minimum versions we are currently aware of: -* Chrome 49, Firefox 44, Safari 11, Opera 36, Edge 79 +* Chrome 64, Firefox 79, Safari 13.4, Opera 51, Edge 79 ### Server Requirements diff --git a/core/rfb.js b/core/rfb.js index 228aeca..ea3bf58 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -134,6 +134,7 @@ export default class RFB extends EventTargetMixin { this._flushing = false; // Display flushing state this._keyboard = null; // Keyboard input handler object this._gestures = null; // Gesture input handler object + this._resizeObserver = null; // Resize observer object // Timers this._disconnTimer = null; // disconnection timer @@ -171,7 +172,7 @@ export default class RFB extends EventTargetMixin { // Bound event handlers this._eventHandlers = { focusCanvas: this._focusCanvas.bind(this), - windowResize: this._windowResize.bind(this), + handleResize: this._handleResize.bind(this), handleMouse: this._handleMouse.bind(this), handleWheel: this._handleWheel.bind(this), handleGesture: this._handleGesture.bind(this), @@ -239,6 +240,8 @@ export default class RFB extends EventTargetMixin { this._sock.on('message', this._handleMessage.bind(this)); this._sock.on('error', this._socketError.bind(this)); + this._resizeObserver = new ResizeObserver(this._eventHandlers.handleResize); + // All prepared, kick off the connection this._updateConnectionState('connecting'); @@ -488,9 +491,8 @@ export default class RFB extends EventTargetMixin { this._cursor.attach(this._canvas); this._refreshCursor(); - // Monitor size changes of the screen - // FIXME: Use ResizeObserver, or hidden overflow - window.addEventListener('resize', this._eventHandlers.windowResize); + // Monitor size changes of the screen element + this._resizeObserver.observe(this._screen); // Always grab focus on some kind of click event this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas); @@ -531,7 +533,7 @@ export default class RFB extends EventTargetMixin { this._canvas.removeEventListener('contextmenu', this._eventHandlers.handleMouse); this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas); this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas); - window.removeEventListener('resize', this._eventHandlers.windowResize); + this._resizeObserver.disconnect(); this._keyboard.ungrab(); this._gestures.detach(); this._sock.close(); @@ -617,7 +619,7 @@ export default class RFB extends EventTargetMixin { { detail: { name: this._fbName } })); } - _windowResize(event) { + _handleResize() { // If the window resized then our screen element might have // as well. Update the viewport dimensions. window.requestAnimationFrame(() => { diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 404f7db..5f50581 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -71,6 +71,18 @@ function deflateWithSize(data) { describe('Remote Frame Buffer Protocol Client', function () { let clock; let raf; + let fakeResizeObserver = null; + const realObserver = window.ResizeObserver; + + class FakeResizeObserver { + constructor(handler) { + this.fire = handler; + fakeResizeObserver = this; + } + disconnect() {} + observe(target, options) {} + unobserve(target) {} + } before(FakeWebSocket.replace); after(FakeWebSocket.restore); @@ -80,6 +92,9 @@ describe('Remote Frame Buffer Protocol Client', function () { // sinon doesn't support this yet raf = window.requestAnimationFrame; window.requestAnimationFrame = setTimeout; + // We must do this in a 'before' since it needs to be set before + // the RFB constructor, which runs in beforeEach further down + window.ResizeObserver = FakeResizeObserver; // Use a single set of buffers instead of reallocating to // speed up tests const sock = new Websock(); @@ -100,6 +115,7 @@ describe('Remote Frame Buffer Protocol Client', function () { delete Websock.prototype.toString; this.clock.restore(); window.requestAnimationFrame = raf; + window.ResizeObserver = realObserver; }); let container; @@ -470,6 +486,7 @@ describe('Remote Frame Buffer Protocol Client', function () { describe('Clipping', function () { let client; + beforeEach(function () { client = makeRFB(); container.style.width = '70px'; @@ -495,8 +512,7 @@ describe('Remote Frame Buffer Protocol Client', function () { container.style.width = '40px'; container.style.height = '50px'; - const event = new UIEvent('resize'); - window.dispatchEvent(event); + fakeResizeObserver.fire(); clock.tick(); expect(client._display.viewportChangeSize).to.have.been.calledOnce; @@ -692,8 +708,7 @@ describe('Remote Frame Buffer Protocol Client', function () { container.style.width = '40px'; container.style.height = '50px'; - const event = new UIEvent('resize'); - window.dispatchEvent(event); + fakeResizeObserver.fire(); clock.tick(); expect(client._display.autoscale).to.have.been.calledOnce; @@ -782,8 +797,7 @@ describe('Remote Frame Buffer Protocol Client', function () { it('should request a resize when the container resizes', function () { container.style.width = '40px'; container.style.height = '50px'; - const event = new UIEvent('resize'); - window.dispatchEvent(event); + fakeResizeObserver.fire(); clock.tick(1000); expect(RFB.messages.setDesktopSize).to.have.been.calledOnce; @@ -793,16 +807,14 @@ describe('Remote Frame Buffer Protocol Client', function () { it('should not resize until the container size is stable', function () { container.style.width = '20px'; container.style.height = '30px'; - const event1 = new UIEvent('resize'); - window.dispatchEvent(event1); + fakeResizeObserver.fire(); clock.tick(400); expect(RFB.messages.setDesktopSize).to.not.have.been.called; container.style.width = '40px'; container.style.height = '50px'; - const event2 = new UIEvent('resize'); - window.dispatchEvent(event2); + fakeResizeObserver.fire(); clock.tick(400); expect(RFB.messages.setDesktopSize).to.not.have.been.called; |