Move wheel event handling to RFB class
The Mouse class does very little now so it mostly just obfuscate things. Move everything directly in to the RFB class instead.
This commit is contained in:
parent
4a87038080
commit
f84bc57bda
|
@ -7,22 +7,16 @@
|
|||
import * as Log from '../util/logging.js';
|
||||
import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
|
||||
|
||||
const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
|
||||
const WHEEL_LINE_HEIGHT = 19;
|
||||
|
||||
export default class Mouse {
|
||||
constructor(target) {
|
||||
this._target = target || document;
|
||||
|
||||
this._pos = null;
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
|
||||
this._eventHandlers = {
|
||||
'mousedown': this._handleMouseDown.bind(this),
|
||||
'mouseup': this._handleMouseUp.bind(this),
|
||||
'mousemove': this._handleMouseMove.bind(this),
|
||||
'mousewheel': this._handleMouseWheel.bind(this),
|
||||
'mousedisable': this._handleMouseDisable.bind(this)
|
||||
};
|
||||
|
||||
|
@ -61,68 +55,6 @@ export default class Mouse {
|
|||
this._handleMouseButton(e, 0);
|
||||
}
|
||||
|
||||
// Mouse wheel events are sent in steps over VNC. This means that the VNC
|
||||
// protocol can't handle a wheel event with specific distance or speed.
|
||||
// Therefor, if we get a lot of small mouse wheel events we combine them.
|
||||
_generateWheelStepX() {
|
||||
|
||||
if (this._accumulatedWheelDeltaX < 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 5);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 5);
|
||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 6);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 6);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
}
|
||||
|
||||
_generateWheelStepY() {
|
||||
|
||||
if (this._accumulatedWheelDeltaY < 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 3);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 3);
|
||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 1, 1 << 4);
|
||||
this.onmousebutton(this._pos.x, this._pos.y, 0, 1 << 4);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
}
|
||||
|
||||
_handleMouseWheel(e) {
|
||||
this._updateMousePosition(e);
|
||||
|
||||
let dX = e.deltaX;
|
||||
let dY = e.deltaY;
|
||||
|
||||
// Pixel units unless it's non-zero.
|
||||
// Note that if deltamode is line or page won't matter since we aren't
|
||||
// sending the mouse wheel delta to the server anyway.
|
||||
// The difference between pixel and line can be important however since
|
||||
// we have a threshold that can be smaller than the line height.
|
||||
if (e.deltaMode !== 0) {
|
||||
dX *= WHEEL_LINE_HEIGHT;
|
||||
dY *= WHEEL_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaX += dX;
|
||||
this._accumulatedWheelDeltaY += dY;
|
||||
|
||||
// Generate a mouse wheel step event when the accumulated delta
|
||||
// for one of the axes is large enough.
|
||||
// Small delta events that do not pass the threshold get sent
|
||||
// after a timeout.
|
||||
if (Math.abs(this._accumulatedWheelDeltaX) > WHEEL_STEP) {
|
||||
this._generateWheelStepX();
|
||||
}
|
||||
if (Math.abs(this._accumulatedWheelDeltaY) > WHEEL_STEP) {
|
||||
this._generateWheelStepY();
|
||||
}
|
||||
|
||||
stopEvent(e);
|
||||
}
|
||||
|
||||
_handleMouseMove(e) {
|
||||
this._updateMousePosition(e);
|
||||
this.onmousemove(this._pos.x, this._pos.y);
|
||||
|
@ -172,7 +104,6 @@ export default class Mouse {
|
|||
t.addEventListener('mousedown', this._eventHandlers.mousedown);
|
||||
t.addEventListener('mouseup', this._eventHandlers.mouseup);
|
||||
t.addEventListener('mousemove', this._eventHandlers.mousemove);
|
||||
t.addEventListener('wheel', this._eventHandlers.mousewheel);
|
||||
|
||||
// Prevent middle-click pasting (see above for why we bind to document)
|
||||
document.addEventListener('click', this._eventHandlers.mousedisable);
|
||||
|
@ -188,7 +119,6 @@ export default class Mouse {
|
|||
t.removeEventListener('mousedown', this._eventHandlers.mousedown);
|
||||
t.removeEventListener('mouseup', this._eventHandlers.mouseup);
|
||||
t.removeEventListener('mousemove', this._eventHandlers.mousemove);
|
||||
t.removeEventListener('wheel', this._eventHandlers.mousewheel);
|
||||
|
||||
document.removeEventListener('click', this._eventHandlers.mousedisable);
|
||||
|
||||
|
|
66
core/rfb.js
66
core/rfb.js
|
@ -41,6 +41,10 @@ const DEFAULT_BACKGROUND = 'rgb(40, 40, 40)';
|
|||
// Minimum wait (ms) between two mouse moves
|
||||
const MOUSE_MOVE_DELAY = 17;
|
||||
|
||||
// Wheel thresholds
|
||||
const WHEEL_STEP = 10; // Pixels needed for one step
|
||||
const WHEEL_LINE_HEIGHT = 19; // Assumed pixels for one line step
|
||||
|
||||
// Gesture thresholds
|
||||
const GESTURE_ZOOMSENS = 75;
|
||||
const GESTURE_SCRLSENS = 50;
|
||||
|
@ -152,6 +156,8 @@ export default class RFB extends EventTargetMixin {
|
|||
this._viewportDragging = false;
|
||||
this._viewportDragPos = {};
|
||||
this._viewportHasMoved = false;
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
|
||||
// Gesture state
|
||||
this._gestureLastTapTime = null;
|
||||
|
@ -163,6 +169,7 @@ export default class RFB extends EventTargetMixin {
|
|||
this._eventHandlers = {
|
||||
focusCanvas: this._focusCanvas.bind(this),
|
||||
windowResize: this._windowResize.bind(this),
|
||||
handleWheel: this._handleWheel.bind(this),
|
||||
handleGesture: this._handleGesture.bind(this),
|
||||
};
|
||||
|
||||
|
@ -532,6 +539,9 @@ export default class RFB extends EventTargetMixin {
|
|||
this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas);
|
||||
this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas);
|
||||
|
||||
// Wheel events
|
||||
this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel);
|
||||
|
||||
// Gesture events
|
||||
this._canvas.addEventListener("gesturestart", this._eventHandlers.handleGesture);
|
||||
this._canvas.addEventListener("gesturemove", this._eventHandlers.handleGesture);
|
||||
|
@ -546,6 +556,7 @@ export default class RFB extends EventTargetMixin {
|
|||
this._canvas.removeEventListener("gesturestart", this._eventHandlers.handleGesture);
|
||||
this._canvas.removeEventListener("gesturemove", this._eventHandlers.handleGesture);
|
||||
this._canvas.removeEventListener("gestureend", this._eventHandlers.handleGesture);
|
||||
this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel);
|
||||
this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas);
|
||||
this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas);
|
||||
window.removeEventListener('resize', this._eventHandlers.windowResize);
|
||||
|
@ -939,6 +950,61 @@ export default class RFB extends EventTargetMixin {
|
|||
this._display.absY(y), mask);
|
||||
}
|
||||
|
||||
_handleWheel(ev) {
|
||||
if (this._rfbConnectionState !== 'connected') { return; }
|
||||
if (this._viewOnly) { return; } // View only, skip mouse events
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
let pos = clientToElement(ev.clientX, ev.clientY,
|
||||
this._canvas);
|
||||
|
||||
let dX = ev.deltaX;
|
||||
let dY = ev.deltaY;
|
||||
|
||||
// Pixel units unless it's non-zero.
|
||||
// Note that if deltamode is line or page won't matter since we aren't
|
||||
// sending the mouse wheel delta to the server anyway.
|
||||
// The difference between pixel and line can be important however since
|
||||
// we have a threshold that can be smaller than the line height.
|
||||
if (ev.deltaMode !== 0) {
|
||||
dX *= WHEEL_LINE_HEIGHT;
|
||||
dY *= WHEEL_LINE_HEIGHT;
|
||||
}
|
||||
|
||||
// Mouse wheel events are sent in steps over VNC. This means that the VNC
|
||||
// protocol can't handle a wheel event with specific distance or speed.
|
||||
// Therefor, if we get a lot of small mouse wheel events we combine them.
|
||||
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);
|
||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 6);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 6);
|
||||
}
|
||||
|
||||
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);
|
||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 4);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 4);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_handleTapEvent(ev, bmask) {
|
||||
let pos = clientToElement(ev.detail.clientX, ev.detail.clientY,
|
||||
this._canvas);
|
||||
|
|
|
@ -69,87 +69,5 @@ describe('Mouse Event Handling', function () {
|
|||
mouse._handleMouseMove(mouseevent('mousemove',
|
||||
{ clientX: 50, clientY: 20 }));
|
||||
});
|
||||
it('should decode mousewheel events', function (done) {
|
||||
let calls = 0;
|
||||
const mouse = new Mouse(target);
|
||||
mouse.onmousebutton = (x, y, down, bmask) => {
|
||||
calls++;
|
||||
expect(bmask).to.be.equal(1<<6);
|
||||
if (calls === 1) {
|
||||
expect(down).to.be.equal(1);
|
||||
} else if (calls === 2) {
|
||||
expect(down).to.not.be.equal(1);
|
||||
done();
|
||||
}
|
||||
};
|
||||
mouse._handleMouseWheel(mouseevent('mousewheel',
|
||||
{ deltaX: 50, deltaY: 0,
|
||||
deltaMode: 0}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Accumulate mouse wheel events with small delta', function () {
|
||||
|
||||
it('should accumulate wheel events if small enough', function () {
|
||||
const mouse = new Mouse(target);
|
||||
mouse.onmousebutton = sinon.spy();
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 4, deltaY: 0, deltaMode: 0 }));
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 4, deltaY: 0, deltaMode: 0 }));
|
||||
|
||||
// threshold is 10
|
||||
expect(mouse._accumulatedWheelDeltaX).to.be.equal(8);
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 4, deltaY: 0, deltaMode: 0 }));
|
||||
|
||||
expect(mouse.onmousebutton).to.have.callCount(2); // mouse down and up
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 4, deltaY: 9, deltaMode: 0 }));
|
||||
|
||||
expect(mouse._accumulatedWheelDeltaX).to.be.equal(4);
|
||||
expect(mouse._accumulatedWheelDeltaY).to.be.equal(9);
|
||||
|
||||
expect(mouse.onmousebutton).to.have.callCount(2); // still
|
||||
});
|
||||
|
||||
it('should not accumulate large wheel events', function () {
|
||||
const mouse = new Mouse(target);
|
||||
mouse.onmousebutton = sinon.spy();
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 11, deltaY: 0, deltaMode: 0 }));
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 0, deltaY: 70, deltaMode: 0 }));
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 400, deltaY: 400, deltaMode: 0 }));
|
||||
|
||||
expect(mouse.onmousebutton).to.have.callCount(8); // mouse down and up
|
||||
});
|
||||
|
||||
it('should account for non-zero deltaMode', function () {
|
||||
const mouse = new Mouse(target);
|
||||
mouse.onmousebutton = sinon.spy();
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 0, deltaY: 2, deltaMode: 1 }));
|
||||
|
||||
mouse._handleMouseWheel(mouseevent(
|
||||
'mousewheel', { clientX: 18, clientY: 40,
|
||||
deltaX: 1, deltaY: 0, deltaMode: 2 }));
|
||||
|
||||
expect(mouse.onmousebutton).to.have.callCount(4); // mouse down and up
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2731,20 +2731,44 @@ describe('Remote Frame Buffer Protocol Client', function () {
|
|||
|
||||
describe('Asynchronous Events', function () {
|
||||
let client;
|
||||
let pointerEvent;
|
||||
let keyEvent;
|
||||
let qemuKeyEvent;
|
||||
|
||||
beforeEach(function () {
|
||||
client = makeRFB();
|
||||
client._display.resize(100, 100);
|
||||
|
||||
pointerEvent = sinon.spy(RFB.messages, 'pointerEvent');
|
||||
keyEvent = sinon.spy(RFB.messages, 'keyEvent');
|
||||
qemuKeyEvent = sinon.spy(RFB.messages, 'QEMUExtendedKeyEvent');
|
||||
});
|
||||
|
||||
describe('Mouse event handlers', function () {
|
||||
beforeEach(function () {
|
||||
this.clock = sinon.useFakeTimers(Date.now());
|
||||
sinon.spy(RFB.messages, 'pointerEvent');
|
||||
});
|
||||
afterEach(function () {
|
||||
this.clock.restore();
|
||||
RFB.messages.pointerEvent.restore();
|
||||
});
|
||||
afterEach(function () {
|
||||
pointerEvent.restore();
|
||||
keyEvent.restore();
|
||||
qemuKeyEvent.restore();
|
||||
});
|
||||
|
||||
function elementToClient(x, y) {
|
||||
let res = { x: 0, y: 0 };
|
||||
|
||||
let bounds = client._canvas.getBoundingClientRect();
|
||||
|
||||
/*
|
||||
* If the canvas is on a fractional position we will calculate
|
||||
* a fractional mouse position. But that gets truncated when we
|
||||
* send the event, AND the same thing happens in RFB when it
|
||||
* generates the PointerEvent message. To compensate for that
|
||||
* fact we round the value upwards here.
|
||||
*/
|
||||
res.x = Math.ceil(bounds.left + x);
|
||||
res.y = Math.ceil(bounds.top + y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
describe('Mouse Events', function () {
|
||||
it('should not send button messages in view-only mode', function () {
|
||||
client._viewOnly = true;
|
||||
client._handleMouseButton(0, 0, 1, 0x001);
|
||||
|
@ -2878,7 +2902,128 @@ describe('Remote Frame Buffer Protocol Client', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Keyboard Event Handlers', function () {
|
||||
describe('Wheel Events', function () {
|
||||
function sendWheelEvent(x, y, dx, dy, mode=0) {
|
||||
let pos = elementToClient(x, y);
|
||||
let ev;
|
||||
|
||||
try {
|
||||
ev = new WheelEvent('wheel',
|
||||
{ 'screenX': pos.x + window.screenX,
|
||||
'screenY': pos.y + window.screenY,
|
||||
'clientX': pos.x,
|
||||
'clientY': pos.y,
|
||||
'deltaX': dx,
|
||||
'deltaY': dy,
|
||||
'deltaMode': mode });
|
||||
} catch (e) {
|
||||
ev = document.createEvent('WheelEvent');
|
||||
ev.initWheelEvent('wheel', true, true, window, 0,
|
||||
pos.x + window.screenX,
|
||||
pos.y + window.screenY,
|
||||
pos.x, pos.y,
|
||||
0, null, "",
|
||||
dx, dy, 0, mode);
|
||||
}
|
||||
|
||||
client._canvas.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
it('should handle wheel up event', function () {
|
||||
sendWheelEvent(10, 10, 0, -50);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<3);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should handle wheel down event', function () {
|
||||
sendWheelEvent(10, 10, 0, 50);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<4);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should handle wheel left event', function () {
|
||||
sendWheelEvent(10, 10, -50, 0);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<5);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should handle wheel right event', function () {
|
||||
sendWheelEvent(10, 10, 50, 0);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<6);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should ignore wheel when in view only', function () {
|
||||
client._viewOnly = true;
|
||||
|
||||
sendWheelEvent(10, 10, 50, 0);
|
||||
|
||||
expect(pointerEvent).to.not.have.been.called;
|
||||
});
|
||||
|
||||
it('should accumulate wheel events if small enough', function () {
|
||||
sendWheelEvent(10, 10, 0, 4);
|
||||
sendWheelEvent(10, 10, 0, 4);
|
||||
|
||||
expect(pointerEvent).to.not.have.been.called;
|
||||
|
||||
sendWheelEvent(10, 10, 0, 4);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<4);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should not accumulate large wheel events', function () {
|
||||
sendWheelEvent(10, 10, 0, 400);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<4);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should handle line based wheel event', function () {
|
||||
sendWheelEvent(10, 10, 0, 1, 1);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<4);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
|
||||
it('should handle page based wheel event', function () {
|
||||
sendWheelEvent(10, 10, 0, 1, 2);
|
||||
|
||||
expect(pointerEvent).to.have.been.calledTwice;
|
||||
expect(pointerEvent.firstCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 1<<4);
|
||||
expect(pointerEvent.secondCall).to.have.been.calledWith(client._sock,
|
||||
10, 10, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Keyboard Events', function () {
|
||||
it('should send a key message on a key press', function () {
|
||||
client._handleKeyEvent(0x41, 'KeyA', true);
|
||||
const keyMsg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: () => {}};
|
||||
|
@ -2895,42 +3040,14 @@ describe('Remote Frame Buffer Protocol Client', function () {
|
|||
});
|
||||
|
||||
describe('Gesture event handlers', function () {
|
||||
let pointerEvent;
|
||||
|
||||
beforeEach(function () {
|
||||
// Touch events and gestures are not supported on IE
|
||||
if (browser.isIE()) {
|
||||
this.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
pointerEvent = sinon.spy(RFB.messages, 'pointerEvent');
|
||||
|
||||
client._display.resize(100, 100);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
pointerEvent.restore();
|
||||
});
|
||||
|
||||
function elementToClient(x, y) {
|
||||
let res = { x: 0, y: 0 };
|
||||
|
||||
let bounds = client._canvas.getBoundingClientRect();
|
||||
|
||||
/*
|
||||
* If the canvas is on a fractional position we will calculate
|
||||
* a fractional mouse position. But that gets truncated when we
|
||||
* send the event, AND the same thing happens in RFB when it
|
||||
* generates the PointerEvent message. To compensate for that
|
||||
* fact we round the value upwards here.
|
||||
*/
|
||||
res.x = Math.ceil(bounds.left + x);
|
||||
res.y = Math.ceil(bounds.top + y);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function gestureStart(gestureType, x, y,
|
||||
magnitudeX = 0, magnitudeY = 0) {
|
||||
let pos = elementToClient(x, y);
|
||||
|
@ -3392,25 +3509,6 @@ describe('Remote Frame Buffer Protocol Client', function () {
|
|||
});
|
||||
|
||||
describe('Gesture pinch', function () {
|
||||
let keyEvent;
|
||||
let qemuKeyEvent;
|
||||
|
||||
beforeEach(function () {
|
||||
// Touch events and gestures are not supported on IE
|
||||
if (browser.isIE()) {
|
||||
this.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
keyEvent = sinon.spy(RFB.messages, 'keyEvent');
|
||||
qemuKeyEvent = sinon.spy(RFB.messages, 'QEMUExtendedKeyEvent');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
keyEvent.restore();
|
||||
qemuKeyEvent.restore();
|
||||
});
|
||||
|
||||
it('should handle gesture pinch in events', function () {
|
||||
let keysym = KeyTable.XK_Control_L;
|
||||
let bmask = 0x10; // Button mask for scroll down
|
||||
|
|
Loading…
Reference in New Issue