Properly limit mouse moves to once every 17 ms
Previous attempt in c958269 had a number of issues, this is a full rewrite, complete with improved unit tests. Fixes github issue #1402
This commit is contained in:
committed by
Lauri Kasanen
parent
8a8fa1d906
commit
19c473f792
@@ -11,7 +11,6 @@ import { setCapture, stopEvent, getPointerEvent } from '../util/events.js';
|
||||
const WHEEL_STEP = 10; // Delta threshold for a mouse wheel step
|
||||
const WHEEL_STEP_TIMEOUT = 50; // ms
|
||||
const WHEEL_LINE_HEIGHT = 19;
|
||||
const MOUSE_MOVE_DELAY = 17; // Minimum wait (ms) between two mouse moves
|
||||
|
||||
export default class Mouse {
|
||||
constructor(target) {
|
||||
@@ -23,7 +22,6 @@ export default class Mouse {
|
||||
this._pos = null;
|
||||
this._wheelStepXTimer = null;
|
||||
this._wheelStepYTimer = null;
|
||||
this._oldMouseMoveTime = 0;
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
|
||||
@@ -200,19 +198,7 @@ export default class Mouse {
|
||||
|
||||
_handleMouseMove(e) {
|
||||
this._updateMousePosition(e);
|
||||
|
||||
// Limit mouse move events to one every MOUSE_MOVE_DELAY ms
|
||||
clearTimeout(this.mouseMoveTimer);
|
||||
const newMouseMoveTime = Date.now();
|
||||
if (newMouseMoveTime < this._oldMouseMoveTime + MOUSE_MOVE_DELAY) {
|
||||
this.mouseMoveTimer = setTimeout(this.onmousemove.bind(this),
|
||||
MOUSE_MOVE_DELAY,
|
||||
this._pos.x, this._pos.y);
|
||||
} else {
|
||||
this.onmousemove(this._pos.x, this._pos.y);
|
||||
}
|
||||
this._oldMouseMoveTime = newMouseMoveTime;
|
||||
|
||||
this.onmousemove(this._pos.x, this._pos.y);
|
||||
stopEvent(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ const DEFAULT_BACKGROUND = 'rgb(40, 40, 40)';
|
||||
var _videoQuality = 2;
|
||||
var _enableWebP = false;
|
||||
|
||||
// Minimum wait (ms) between two mouse moves
|
||||
const MOUSE_MOVE_DELAY = 17;
|
||||
|
||||
// Extended clipboard pseudo-encoding formats
|
||||
const extendedClipboardFormatText = 1;
|
||||
/*eslint-disable no-unused-vars */
|
||||
@@ -138,6 +141,7 @@ export default class RFB extends EventTargetMixin {
|
||||
// Timers
|
||||
this._disconnTimer = null; // disconnection timer
|
||||
this._resizeTimeout = null; // resize rate limiting
|
||||
this._mouseMoveTimer = null;
|
||||
|
||||
// Decoder states
|
||||
this._decoders = {};
|
||||
@@ -152,7 +156,9 @@ export default class RFB extends EventTargetMixin {
|
||||
};
|
||||
|
||||
// Mouse state
|
||||
this._mousePos = {};
|
||||
this._mouseButtonMask = 0;
|
||||
this._mouseLastMoveTime = 0;
|
||||
this._viewportDragging = false;
|
||||
this._viewportDragPos = {};
|
||||
this._viewportHasMoved = false;
|
||||
@@ -564,6 +570,7 @@ export default class RFB extends EventTargetMixin {
|
||||
}
|
||||
}
|
||||
clearTimeout(this._resizeTimeout);
|
||||
clearTimeout(this._mouseMoveTimer);
|
||||
Log.Debug("<< RFB.disconnect");
|
||||
}
|
||||
|
||||
@@ -880,12 +887,6 @@ export default class RFB extends EventTargetMixin {
|
||||
}
|
||||
|
||||
_handleMouseButton(x, y, down, bmask) {
|
||||
if (down) {
|
||||
this._mouseButtonMask |= bmask;
|
||||
} else {
|
||||
this._mouseButtonMask &= ~bmask;
|
||||
}
|
||||
|
||||
if (this.dragViewport) {
|
||||
if (down && !this._viewportDragging) {
|
||||
this._viewportDragging = true;
|
||||
@@ -903,24 +904,29 @@ export default class RFB extends EventTargetMixin {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._viewOnly) { 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.sentEventsCounter+=1;
|
||||
RFB.messages.pointerEvent(this._sock,
|
||||
this._display.absX(x),
|
||||
this._display.absY(y),
|
||||
bmask);
|
||||
this._sendMouse(x, y, bmask);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._viewOnly) { return; } // View only, skip mouse events
|
||||
|
||||
if (this._rfbConnectionState !== 'connected') { return; }
|
||||
this.sentEventsCounter+=1;
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouseButtonMask);
|
||||
// Flush waiting move event first
|
||||
if (this._mouseMoveTimer !== null) {
|
||||
clearTimeout(this._mouseMoveTimer);
|
||||
this._mouseMoveTimer = null;
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
}
|
||||
|
||||
if (down) {
|
||||
this._mouseButtonMask |= bmask;
|
||||
} else {
|
||||
this._mouseButtonMask &= ~bmask;
|
||||
}
|
||||
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
}
|
||||
|
||||
_handleMouseMove(x, y) {
|
||||
@@ -940,10 +946,37 @@ export default class RFB extends EventTargetMixin {
|
||||
return;
|
||||
}
|
||||
|
||||
this._mousePos = { 'x': x, 'y': y };
|
||||
|
||||
// Limit many mouse move events to one every MOUSE_MOVE_DELAY ms
|
||||
if (this._mouseMoveTimer == null) {
|
||||
|
||||
const timeSinceLastMove = Date.now() - this._mouseLastMoveTime;
|
||||
if (timeSinceLastMove > MOUSE_MOVE_DELAY) {
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
this._mouseLastMoveTime = Date.now();
|
||||
} else {
|
||||
// Too soon since the latest move, wait the remaining time
|
||||
this._mouseMoveTimer = setTimeout(() => {
|
||||
this._handleDelayedMouseMove();
|
||||
}, MOUSE_MOVE_DELAY - timeSinceLastMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleDelayedMouseMove() {
|
||||
this._mouseMoveTimer = null;
|
||||
this._sendMouse(this._mousePos.x, this._mousePos.y,
|
||||
this._mouseButtonMask);
|
||||
this._mouseLastMoveTime = Date.now();
|
||||
}
|
||||
|
||||
_sendMouse(x, y, mask) {
|
||||
if (this._rfbConnectionState !== 'connected') { return; }
|
||||
if (this._viewOnly) { return; } // View only, skip mouse events
|
||||
|
||||
if (this._rfbConnectionState !== 'connected') { return; }
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouseButtonMask);
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x),
|
||||
this._display.absY(y), mask);
|
||||
}
|
||||
|
||||
// Message Handlers
|
||||
|
||||
Reference in New Issue
Block a user