Use MouseEvent.buttons for button state tracking

Instead of keeping track of button states ourselves by looking at
MouseEvent.button, we can use the MouseEvent.buttons which already
contains the state of all buttons.
This commit is contained in:
Adam Halim 2024-11-29 14:47:19 +01:00
parent f9eb476f6d
commit b9230cf23e
2 changed files with 234 additions and 155 deletions

View File

@ -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);
break;
case 'mousemove':
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._viewportDragPos = {'x': pos.x, 'y': pos.y};
this._viewportHasMoved = false;
// Skip sending mouse events
return;
// 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) {
return;
this._mouseButtonMask = bmask;
break;
}
// 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);
// 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);
}
}
// Flush waiting move event first
this._flushMouseMoveTimer(x, y);
if (down) {
this._mouseButtonMask |= bmask;
} else {
this._mouseButtonMask &= ~bmask;
setCapture(this._canvas);
}
this._sendMouse(x, y, this._mouseButtonMask);
}
_handleMouseMove(x, y) {
this._handleMouseButton(pos.x, pos.y, bmask);
break;
case 'mousemove':
if (this._viewportDragging) {
const deltaX = this._viewportDragPos.x - x;
const deltaY = this._viewportDragPos.y - y;
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': x, 'y': y};
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
this._display.viewportChangePos(deltaX, deltaY);
}
// Skip sending mouse events
return;
break;
}
this._handleMouseMove(pos.x, pos.y);
break;
}
}
_handleMouseButton(x, y, bmask) {
// Flush waiting move event first
this._flushMouseMoveTimer(x, y);
this._mouseButtonMask = bmask;
this._sendMouse(x, y, this._mouseButtonMask);
}
_handleMouseMove(x, y) {
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':
if (this.dragViewport) {
this._viewportHasMoved = false;
this._viewportDragging = true;
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, true, 0x1);
} 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':
if (this.dragViewport) {
this._viewportDragging = false;
} else {
this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, false, 0x1);
this._handleMouseButton(pos.x, pos.y, 0x0);
}
break;
case 'longpress':
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);
this._handleMouseButton(pos.x, pos.y, false, 0x4);
// 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;

View File

@ -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;