diff --git a/core/rfb.js b/core/rfb.js index 3f946142..4b105cb5 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -1033,6 +1033,35 @@ export default class RFB extends EventTargetMixin { this.sendKey(keysym, code, down); } + static _convertButtonMask(buttons) { + /* The bits in MouseEvent.buttons property correspond + * to the following mouse buttons: + * 0: Left + * 1: Right + * 2: Middle + * 3: Back + * 4: Forward + * + * These bits needs to be converted to what they are defined as + * in the RFB protocol. + */ + + const buttonMaskMap = { + 0: 1 << 0, // Left + 1: 1 << 2, // Right + 2: 1 << 1, // Middle + 3: 1 << 7, // Back + }; + + let bmask = 0; + for (let i = 0; i < 4; i++) { + if (buttons & (1 << i)) { + bmask |= buttonMaskMap[i]; + } + } + return bmask; + } + _handleMouse(ev) { /* * We don't check connection status or viewOnly here as the @@ -1062,76 +1091,73 @@ export default class RFB extends EventTargetMixin { let pos = clientToElement(ev.clientX, ev.clientY, this._canvas); + let bmask = RFB._convertButtonMask(ev.buttons); + + let down = ev.type == 'mousedown'; switch (ev.type) { case 'mousedown': - setCapture(this._canvas); - this._handleMouseButton(pos.x, pos.y, - true, 1 << ev.button); - break; case 'mouseup': - this._handleMouseButton(pos.x, pos.y, - false, 1 << ev.button); + if (this.dragViewport) { + if (down && !this._viewportDragging) { + this._viewportDragging = true; + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; + this._viewportHasMoved = false; + + // Skip sending mouse events, instead save the current + // mouse mask so we can send it later. + this._mouseButtonMask = bmask; + break; + } else { + this._viewportDragging = false; + + // If we actually performed a drag then we are done + // here and should not send any mouse events + if (this._viewportHasMoved) { + this._mouseButtonMask = bmask; + break; + } + // Otherwise we treat this as a mouse click event. + // Send the previously saved button mask, followed + // by the current button mask at the end of this + // function. + this._sendMouse(pos.x, pos.y, this._mouseButtonMask); + } + } + if (down) { + setCapture(this._canvas); + } + this._handleMouseButton(pos.x, pos.y, bmask); break; case 'mousemove': + if (this._viewportDragging) { + const deltaX = this._viewportDragPos.x - pos.x; + const deltaY = this._viewportDragPos.y - pos.y; + + if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || + Math.abs(deltaY) > dragThreshold)) { + this._viewportHasMoved = true; + + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; + this._display.viewportChangePos(deltaX, deltaY); + } + + // Skip sending mouse events + break; + } this._handleMouseMove(pos.x, pos.y); break; } } - _handleMouseButton(x, y, down, bmask) { - if (this.dragViewport) { - if (down && !this._viewportDragging) { - this._viewportDragging = true; - this._viewportDragPos = {'x': x, 'y': y}; - this._viewportHasMoved = false; - - // Skip sending mouse events - return; - } else { - this._viewportDragging = false; - - // If we actually performed a drag then we are done - // here and should not send any mouse events - if (this._viewportHasMoved) { - return; - } - - // Otherwise we treat this as a mouse click event. - // Send the button down event here, as the button up - // event is sent at the end of this function. - this._sendMouse(x, y, bmask); - } - } - + _handleMouseButton(x, y, bmask) { // Flush waiting move event first this._flushMouseMoveTimer(x, y); - if (down) { - this._mouseButtonMask |= bmask; - } else { - this._mouseButtonMask &= ~bmask; - } - + this._mouseButtonMask = bmask; this._sendMouse(x, y, this._mouseButtonMask); } _handleMouseMove(x, y) { - if (this._viewportDragging) { - const deltaX = this._viewportDragPos.x - x; - const deltaY = this._viewportDragPos.y - y; - - if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || - Math.abs(deltaY) > dragThreshold)) { - this._viewportHasMoved = true; - - this._viewportDragPos = {'x': x, 'y': y}; - this._display.viewportChangePos(deltaX, deltaY); - } - - // Skip sending mouse events - return; - } - this._mousePos = { 'x': x, 'y': y }; // Limit many mouse move events to one every MOUSE_MOVE_DELAY ms @@ -1175,6 +1201,7 @@ export default class RFB extends EventTargetMixin { let pos = clientToElement(ev.clientX, ev.clientY, this._canvas); + let bmask = RFB._convertButtonMask(ev.buttons); let dX = ev.deltaX; let dY = ev.deltaY; @@ -1194,26 +1221,27 @@ export default class RFB extends EventTargetMixin { this._accumulatedWheelDeltaX += dX; this._accumulatedWheelDeltaY += dY; + // Generate a mouse wheel step event when the accumulated delta // for one of the axes is large enough. if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) { if (this._accumulatedWheelDeltaX < 0) { - this._handleMouseButton(pos.x, pos.y, true, 1 << 5); - this._handleMouseButton(pos.x, pos.y, false, 1 << 5); + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 5); + this._handleMouseButton(pos.x, pos.y, bmask); } else if (this._accumulatedWheelDeltaX > 0) { - this._handleMouseButton(pos.x, pos.y, true, 1 << 6); - this._handleMouseButton(pos.x, pos.y, false, 1 << 6); + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 6); + this._handleMouseButton(pos.x, pos.y, bmask); } this._accumulatedWheelDeltaX = 0; } if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) { if (this._accumulatedWheelDeltaY < 0) { - this._handleMouseButton(pos.x, pos.y, true, 1 << 3); - this._handleMouseButton(pos.x, pos.y, false, 1 << 3); + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 3); + this._handleMouseButton(pos.x, pos.y, bmask); } else if (this._accumulatedWheelDeltaY > 0) { - this._handleMouseButton(pos.x, pos.y, true, 1 << 4); - this._handleMouseButton(pos.x, pos.y, false, 1 << 4); + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 4); + this._handleMouseButton(pos.x, pos.y, bmask); } this._accumulatedWheelDeltaY = 0; @@ -1252,8 +1280,8 @@ export default class RFB extends EventTargetMixin { this._gestureLastTapTime = Date.now(); this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y); - this._handleMouseButton(pos.x, pos.y, true, bmask); - this._handleMouseButton(pos.x, pos.y, false, bmask); + this._handleMouseButton(pos.x, pos.y, bmask); + this._handleMouseButton(pos.x, pos.y, 0x0); } _handleGesture(ev) { @@ -1274,14 +1302,31 @@ export default class RFB extends EventTargetMixin { this._handleTapEvent(ev, 0x2); break; case 'drag': - this._fakeMouseMove(ev, pos.x, pos.y); - this._handleMouseButton(pos.x, pos.y, true, 0x1); + if (this.dragViewport) { + this._viewportHasMoved = false; + this._viewportDragging = true; + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; + + this._fakeMouseMove(ev, pos.x, pos.y); + } else { + this._fakeMouseMove(ev, pos.x, pos.y); + this._handleMouseButton(pos.x, pos.y, 0x1); + } break; case 'longpress': - this._fakeMouseMove(ev, pos.x, pos.y); - this._handleMouseButton(pos.x, pos.y, true, 0x4); - break; + if (this.dragViewport) { + // If dragViewport is true, we need to wait to see + // if we have dragged outside the threshold before + // sending any events to the server. + this._viewportHasMoved = false; + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; + this._fakeMouseMove(ev, pos.x, pos.y); + } else { + this._fakeMouseMove(ev, pos.x, pos.y); + this._handleMouseButton(pos.x, pos.y, 0x4); + } + break; case 'twodrag': this._gestureLastMagnitudeX = ev.detail.magnitudeX; this._gestureLastMagnitudeY = ev.detail.magnitudeY; @@ -1303,6 +1348,19 @@ export default class RFB extends EventTargetMixin { break; case 'drag': case 'longpress': + if (this.dragViewport) { + this._viewportDragging = true; + const deltaX = this._viewportDragPos.x - pos.x; + const deltaY = this._viewportDragPos.y - pos.y; + + if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || + Math.abs(deltaY) > dragThreshold)) { + this._viewportHasMoved = true; + + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; + this._display.viewportChangePos(deltaX, deltaY); + } + } this._fakeMouseMove(ev, pos.x, pos.y); break; case 'twodrag': @@ -1311,23 +1369,23 @@ export default class RFB extends EventTargetMixin { // every update. this._fakeMouseMove(ev, pos.x, pos.y); while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) > GESTURE_SCRLSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x8); - this._handleMouseButton(pos.x, pos.y, false, 0x8); + this._handleMouseButton(pos.x, pos.y, 0x8); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeY += GESTURE_SCRLSENS; } while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) < -GESTURE_SCRLSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x10); - this._handleMouseButton(pos.x, pos.y, false, 0x10); + this._handleMouseButton(pos.x, pos.y, 0x10); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeY -= GESTURE_SCRLSENS; } while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) > GESTURE_SCRLSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x20); - this._handleMouseButton(pos.x, pos.y, false, 0x20); + this._handleMouseButton(pos.x, pos.y, 0x20); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeX += GESTURE_SCRLSENS; } while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) < -GESTURE_SCRLSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x40); - this._handleMouseButton(pos.x, pos.y, false, 0x40); + this._handleMouseButton(pos.x, pos.y, 0x40); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeX -= GESTURE_SCRLSENS; } break; @@ -1340,13 +1398,13 @@ export default class RFB extends EventTargetMixin { if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) { this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); while ((magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x8); - this._handleMouseButton(pos.x, pos.y, false, 0x8); + this._handleMouseButton(pos.x, pos.y, 0x8); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeX += GESTURE_ZOOMSENS; } while ((magnitude - this._gestureLastMagnitudeX) < -GESTURE_ZOOMSENS) { - this._handleMouseButton(pos.x, pos.y, true, 0x10); - this._handleMouseButton(pos.x, pos.y, false, 0x10); + this._handleMouseButton(pos.x, pos.y, 0x10); + this._handleMouseButton(pos.x, pos.y, 0x0); this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS; } } @@ -1364,12 +1422,32 @@ export default class RFB extends EventTargetMixin { case 'twodrag': break; case 'drag': - this._fakeMouseMove(ev, pos.x, pos.y); - this._handleMouseButton(pos.x, pos.y, false, 0x1); + if (this.dragViewport) { + this._viewportDragging = false; + } else { + this._fakeMouseMove(ev, pos.x, pos.y); + this._handleMouseButton(pos.x, pos.y, 0x0); + } break; case 'longpress': - this._fakeMouseMove(ev, pos.x, pos.y); - this._handleMouseButton(pos.x, pos.y, false, 0x4); + if (this._viewportHasMoved) { + // We don't want to send any events if we have moved + // our viewport + break; + } + + if (this.dragViewport && !this._viewportHasMoved) { + this._fakeMouseMove(ev, pos.x, pos.y); + // If dragViewport is true, we need to wait to see + // if we have dragged outside the threshold before + // sending any events to the server. + this._handleMouseButton(pos.x, pos.y, 0x4); + this._handleMouseButton(pos.x, pos.y, 0x0); + this._viewportDragging = false; + } else { + this._fakeMouseMove(ev, pos.x, pos.y); + this._handleMouseButton(pos.x, pos.y, 0x0); + } break; } break; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index b643e169..84298188 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -176,7 +176,7 @@ describe('Remote Frame Buffer protocol client', function () { return res; } - function sendMouseMoveEvent(x, y, client) { + function sendMouseMoveEvent(x, y, buttons, client) { let pos = elementToClient(x, y, client); let ev; @@ -184,11 +184,12 @@ describe('Remote Frame Buffer protocol client', function () { { 'screenX': pos.x + window.screenX, 'screenY': pos.y + window.screenY, 'clientX': pos.x, - 'clientY': pos.y }); + 'clientY': pos.y, + 'buttons': buttons }); client._canvas.dispatchEvent(ev); } - function sendMouseButtonEvent(x, y, down, button, client) { + function sendMouseButtonEvent(x, y, down, buttons, client) { let pos = elementToClient(x, y, client); let ev; @@ -197,8 +198,7 @@ describe('Remote Frame Buffer protocol client', function () { 'screenY': pos.y + window.screenY, 'clientX': pos.x, 'clientY': pos.y, - 'button': button, - 'buttons': 1 << button }); + 'buttons': buttons}); client._canvas.dispatchEvent(ev); } @@ -711,14 +711,14 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should not send button messages when initiating viewport dragging', function () { - sendMouseButtonEvent(13, 9, true, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; }); it('should send button messages when release without movement', function () { // Just up and down - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseButtonEvent(13, 9, false, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseButtonEvent(13, 9, false, 0x0, client); expect(RFB.messages.pointerEvent).to.have.been.calledTwice; expect(RFB.messages.pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -743,9 +743,9 @@ describe('Remote Frame Buffer protocol client', function () { it('should send button messages when release with small movement', function () { // Small movement - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseMoveEvent(15, 14, client); - sendMouseButtonEvent(15, 14, false, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseMoveEvent(15, 14, 0x1, client); + sendMouseButtonEvent(15, 14, false, 0x0, client); expect(RFB.messages.pointerEvent).to.have.been.calledTwice; expect(RFB.messages.pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -757,15 +757,15 @@ describe('Remote Frame Buffer protocol client', function () { it('should not send button messages when in view only', function () { client._viewOnly = true; - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseButtonEvent(13, 9, false, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseButtonEvent(13, 9, false, 0x0, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; }); it('should send button message directly when drag is disabled', function () { client.dragViewport = false; - sendMouseButtonEvent(13, 9, true, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); expect(RFB.messages.pointerEvent).to.have.been.calledOnce; expect(RFB.messages.pointerEvent.firstCall).to.have.been.calledWith(client._sock, 13, 9, 0x1); @@ -775,8 +775,8 @@ describe('Remote Frame Buffer protocol client', function () { sinon.spy(client._display, "viewportChangePos"); // Too small movement - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseMoveEvent(18, 9, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseMoveEvent(18, 9, 0x1, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; @@ -784,7 +784,7 @@ describe('Remote Frame Buffer protocol client', function () { // Sufficient movement - sendMouseMoveEvent(43, 9, client); + sendMouseMoveEvent(43, 9, 0x1, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; expect(client._display.viewportChangePos).to.have.been.calledOnce; @@ -794,7 +794,7 @@ describe('Remote Frame Buffer protocol client', function () { // Now a small movement should move right away - sendMouseMoveEvent(43, 14, client); + sendMouseMoveEvent(43, 14, 0x1, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; expect(client._display.viewportChangePos).to.have.been.calledOnce; @@ -823,8 +823,7 @@ describe('Remote Frame Buffer protocol client', function () { expect(RFB.messages.pointerEvent).to.not.have.been.called; - // FIXME: We only want to move the viewport once - // expect(client._display.viewportChangePos).to.have.been.calledOnce; + expect(client._display.viewportChangePos).to.have.been.calledOnce; expect(client._display.viewportChangePos).to.have.been.calledWith(0, -5); }); @@ -867,14 +866,12 @@ describe('Remote Frame Buffer protocol client', function () { gestureEnd('longpress', 14, 9, client); - // FIXME: We want the pointer event to come after the - // 'gestureEnd' call instead. - // expect(RFB.messages.pointerEvent).to.have.been.calledThrice; - // expect(RFB.messages.pointerEvent.firstCall).to.have.been.calledWith(client._sock, - // 14, 9, 0x0); + expect(RFB.messages.pointerEvent).to.have.been.calledThrice; expect(RFB.messages.pointerEvent.firstCall).to.have.been.calledWith(client._sock, - 14, 9, 0x4); + 14, 9, 0x0); expect(RFB.messages.pointerEvent.secondCall).to.have.been.calledWith(client._sock, + 14, 9, 0x4); + expect(RFB.messages.pointerEvent.thirdCall).to.have.been.calledWith(client._sock, 14, 9, 0x0); expect(client._display.viewportChangePos).to.not.have.been.called; @@ -883,9 +880,9 @@ describe('Remote Frame Buffer protocol client', function () { it('should not send button messages when dragging ends', function () { // First the movement - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseMoveEvent(43, 9, client); - sendMouseButtonEvent(43, 9, false, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseMoveEvent(43, 9, 0x1, client); + sendMouseButtonEvent(43, 9, false, 0x0, client); expect(RFB.messages.pointerEvent).to.not.have.been.called; }); @@ -893,15 +890,15 @@ describe('Remote Frame Buffer protocol client', function () { it('should terminate viewport dragging on a button up event', function () { // First the dragging movement - sendMouseButtonEvent(13, 9, true, 0, client); - sendMouseMoveEvent(43, 9, client); - sendMouseButtonEvent(43, 9, false, 0, client); + sendMouseButtonEvent(13, 9, true, 0x1, client); + sendMouseMoveEvent(43, 9, 0x1, client); + sendMouseButtonEvent(43, 9, false, 0x0, client); // Another movement now should not move the viewport sinon.spy(client._display, "viewportChangePos"); - sendMouseMoveEvent(43, 59, client); + sendMouseMoveEvent(43, 59, 0x0, client); expect(client._display.viewportChangePos).to.not.have.been.called; }); @@ -3773,60 +3770,62 @@ describe('Remote Frame Buffer protocol client', function () { it('should not send button messages in view-only mode', function () { client._viewOnly = true; - sendMouseButtonEvent(10, 10, true, 0, client); + sendMouseButtonEvent(10, 10, true, 0x1, client); + clock.tick(50); expect(pointerEvent).to.not.have.been.called; }); it('should not send movement messages in view-only mode', function () { client._viewOnly = true; - sendMouseMoveEvent(10, 10, client); + sendMouseMoveEvent(10, 10, 0x0, client); + clock.tick(50); expect(pointerEvent).to.not.have.been.called; }); it('should handle left mouse button', function () { - sendMouseButtonEvent(10, 10, true, 0, client); + sendMouseButtonEvent(10, 10, true, 0x1, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x1); pointerEvent.resetHistory(); - sendMouseButtonEvent(10, 10, false, 0, client); + sendMouseButtonEvent(10, 10, false, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x0); }); it('should handle middle mouse button', function () { - sendMouseButtonEvent(10, 10, true, 1, client); + sendMouseButtonEvent(10, 10, true, 0x4, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x2); pointerEvent.resetHistory(); - sendMouseButtonEvent(10, 10, false, 1, client); + sendMouseButtonEvent(10, 10, false, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x0); }); it('should handle right mouse button', function () { - sendMouseButtonEvent(10, 10, true, 2, client); + sendMouseButtonEvent(10, 10, true, 0x2, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x4); pointerEvent.resetHistory(); - sendMouseButtonEvent(10, 10, false, 2, client); + sendMouseButtonEvent(10, 10, false, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 10, 10, 0x0); }); it('should handle multiple mouse buttons', function () { - sendMouseButtonEvent(10, 10, true, 0, client); - sendMouseButtonEvent(10, 10, true, 2, client); + sendMouseButtonEvent(10, 10, true, 0x1, client); + sendMouseButtonEvent(10, 10, true, 0x3, client); expect(pointerEvent).to.have.been.calledTwice; expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -3836,8 +3835,9 @@ describe('Remote Frame Buffer protocol client', function () { pointerEvent.resetHistory(); - sendMouseButtonEvent(10, 10, false, 0, client); - sendMouseButtonEvent(10, 10, false, 2, client); + + sendMouseButtonEvent(10, 10, false, 0x2, client); + sendMouseButtonEvent(10, 10, false, 0x0, client); expect(pointerEvent).to.have.been.calledTwice; expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -3847,14 +3847,14 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should handle mouse movement', function () { - sendMouseMoveEvent(50, 70, client); + sendMouseMoveEvent(50, 70, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 50, 70, 0x0); }); it('should handle click and drag', function () { - sendMouseButtonEvent(10, 10, true, 0, client); - sendMouseMoveEvent(50, 70, client); + sendMouseButtonEvent(10, 10, true, 0x1, client); + sendMouseMoveEvent(50, 70, 0x1, client); expect(pointerEvent).to.have.been.calledTwice; expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -3864,7 +3864,7 @@ describe('Remote Frame Buffer protocol client', function () { pointerEvent.resetHistory(); - sendMouseButtonEvent(50, 70, false, 0, client); + sendMouseButtonEvent(50, 70, false, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 50, 70, 0x0); @@ -3872,15 +3872,15 @@ describe('Remote Frame Buffer protocol client', function () { describe('Event aggregation', function () { it('should send a single pointer event on mouse movement', function () { - sendMouseMoveEvent(50, 70, client); + sendMouseMoveEvent(50, 70, 0x0, client); clock.tick(100); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 50, 70, 0x0); }); it('should delay one move if two events are too close', function () { - sendMouseMoveEvent(18, 30, client); - sendMouseMoveEvent(20, 50, client); + sendMouseMoveEvent(18, 30, 0x0, client); + sendMouseMoveEvent(20, 50, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 18, 30, 0x0); @@ -3893,9 +3893,9 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should only send first and last move of many close events', function () { - sendMouseMoveEvent(18, 30, client); - sendMouseMoveEvent(20, 50, client); - sendMouseMoveEvent(21, 55, client); + sendMouseMoveEvent(18, 30, 0x0, client); + sendMouseMoveEvent(20, 50, 0x0, client); + sendMouseMoveEvent(21, 55, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 18, 30, 0x0); @@ -3909,46 +3909,46 @@ describe('Remote Frame Buffer protocol client', function () { // We selected the 17ms since that is ~60 FPS it('should send move events every 17 ms', function () { - sendMouseMoveEvent(1, 10, client); // instant send + sendMouseMoveEvent(1, 10, 0x0, client); // instant send clock.tick(10); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 1, 10, 0x0); pointerEvent.resetHistory(); - sendMouseMoveEvent(2, 20, client); // delayed + sendMouseMoveEvent(2, 20, 0x0, client); // delayed clock.tick(10); // timeout send expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 2, 20, 0x0); pointerEvent.resetHistory(); - sendMouseMoveEvent(3, 30, client); // delayed + sendMouseMoveEvent(3, 30, 0x0, client); // delayed clock.tick(10); - sendMouseMoveEvent(4, 40, client); // delayed + sendMouseMoveEvent(4, 40, 0x0, client); // delayed clock.tick(10); // timeout send expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 4, 40, 0x0); pointerEvent.resetHistory(); - sendMouseMoveEvent(5, 50, client); // delayed + sendMouseMoveEvent(5, 50, 0x0, client); // delayed expect(pointerEvent).to.not.have.been.called; }); it('should send waiting move events before a button press', function () { - sendMouseMoveEvent(13, 9, client); + sendMouseMoveEvent(13, 9, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 13, 9, 0x0); pointerEvent.resetHistory(); - sendMouseMoveEvent(20, 70, client); + sendMouseMoveEvent(20, 70, 0x0, client); expect(pointerEvent).to.not.have.been.called; - sendMouseButtonEvent(20, 70, true, 0, client); + sendMouseButtonEvent(20, 70, true, 0x1, client); expect(pointerEvent).to.have.been.calledTwice; expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock, @@ -3958,7 +3958,7 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should send move events with enough time apart normally', function () { - sendMouseMoveEvent(58, 60, client); + sendMouseMoveEvent(58, 60, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 58, 60, 0x0); @@ -3966,7 +3966,7 @@ describe('Remote Frame Buffer protocol client', function () { clock.tick(20); - sendMouseMoveEvent(25, 60, client); + sendMouseMoveEvent(25, 60, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 25, 60, 0x0); @@ -3974,13 +3974,13 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should not send waiting move events if disconnected', function () { - sendMouseMoveEvent(88, 99, client); + sendMouseMoveEvent(88, 99, 0x0, client); expect(pointerEvent).to.have.been.calledOnceWith(client._sock, 88, 99, 0x0); pointerEvent.resetHistory(); - sendMouseMoveEvent(66, 77, client); + sendMouseMoveEvent(66, 77, 0x0, client); client.disconnect(); clock.tick(20); @@ -3998,7 +3998,7 @@ describe('Remote Frame Buffer protocol client', function () { }); describe('Wheel events', function () { - function sendWheelEvent(x, y, dx, dy, mode=0) { + function sendWheelEvent(x, y, dx, dy, mode=0, buttons=0) { let pos = elementToClient(x, y, client); let ev; @@ -4009,7 +4009,8 @@ describe('Remote Frame Buffer protocol client', function () { 'clientY': pos.y, 'deltaX': dx, 'deltaY': dy, - 'deltaMode': mode }); + 'deltaMode': mode, + 'buttons': buttons }); client._canvas.dispatchEvent(ev); } @@ -4107,8 +4108,8 @@ describe('Remote Frame Buffer protocol client', function () { }); it('should handle wheel event with buttons pressed', function () { - sendMouseButtonEvent(10, 10, true, 0, client); - sendWheelEvent(10, 10, 0, 50); + sendMouseButtonEvent(10, 10, true, 0x1, client); + sendWheelEvent(10, 10, 0, 50, 0, 0x1); expect(pointerEvent).to.have.been.called.calledThrice;