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:
Pierre Ossman
2020-06-10 13:59:10 +02:00
committed by Samuel Mannehed
parent 4a87038080
commit f84bc57bda
4 changed files with 221 additions and 209 deletions
-82
View File
@@ -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
});
});
});
+155 -57
View File
@@ -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