Merge branch 'mouse-buttonstate-remove' of https://github.com/CendioHalim/noVNC
This commit is contained in:
commit
9cdbd28761
261
core/rfb.js
261
core/rfb.js
|
@ -1033,6 +1033,35 @@ export default class RFB extends EventTargetMixin {
|
||||||
this.sendKey(keysym, code, down);
|
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) {
|
_handleMouse(ev) {
|
||||||
/*
|
/*
|
||||||
* We don't check connection status or viewOnly here as the
|
* We don't check connection status or viewOnly here as the
|
||||||
|
@ -1062,80 +1091,75 @@ export default class RFB extends EventTargetMixin {
|
||||||
let pos = clientToElement(ev.clientX, ev.clientY,
|
let pos = clientToElement(ev.clientX, ev.clientY,
|
||||||
this._canvas);
|
this._canvas);
|
||||||
|
|
||||||
|
let bmask = RFB._convertButtonMask(ev.buttons);
|
||||||
|
|
||||||
|
let down = ev.type == 'mousedown';
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case 'mousedown':
|
case 'mousedown':
|
||||||
setCapture(this._canvas);
|
|
||||||
this._handleMouseButton(pos.x, pos.y,
|
|
||||||
true, 1 << ev.button);
|
|
||||||
break;
|
|
||||||
case 'mouseup':
|
case 'mouseup':
|
||||||
this._handleMouseButton(pos.x, pos.y,
|
if (this.dragViewport) {
|
||||||
false, 1 << ev.button);
|
if (down && !this._viewportDragging) {
|
||||||
|
this._viewportDragging = true;
|
||||||
|
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||||
|
this._viewportHasMoved = false;
|
||||||
|
|
||||||
|
this._flushMouseMoveTimer(pos.x, pos.y);
|
||||||
|
|
||||||
|
// 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;
|
break;
|
||||||
case 'mousemove':
|
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);
|
this._handleMouseMove(pos.x, pos.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMouseButton(x, y, down, bmask) {
|
_handleMouseButton(x, y, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush waiting move event first
|
// Flush waiting move event first
|
||||||
if (this._mouseMoveTimer !== null) {
|
this._flushMouseMoveTimer(x, y);
|
||||||
clearTimeout(this._mouseMoveTimer);
|
|
||||||
this._mouseMoveTimer = null;
|
|
||||||
this._sendMouse(x, y, this._mouseButtonMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (down) {
|
|
||||||
this._mouseButtonMask |= bmask;
|
|
||||||
} else {
|
|
||||||
this._mouseButtonMask &= ~bmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this._mouseButtonMask = bmask;
|
||||||
this._sendMouse(x, y, this._mouseButtonMask);
|
this._sendMouse(x, y, this._mouseButtonMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleMouseMove(x, y) {
|
_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 };
|
this._mousePos = { 'x': x, 'y': y };
|
||||||
|
|
||||||
// Limit many mouse move events to one every MOUSE_MOVE_DELAY ms
|
// Limit many mouse move events to one every MOUSE_MOVE_DELAY ms
|
||||||
|
@ -1179,6 +1203,7 @@ export default class RFB extends EventTargetMixin {
|
||||||
let pos = clientToElement(ev.clientX, ev.clientY,
|
let pos = clientToElement(ev.clientX, ev.clientY,
|
||||||
this._canvas);
|
this._canvas);
|
||||||
|
|
||||||
|
let bmask = RFB._convertButtonMask(ev.buttons);
|
||||||
let dX = ev.deltaX;
|
let dX = ev.deltaX;
|
||||||
let dY = ev.deltaY;
|
let dY = ev.deltaY;
|
||||||
|
|
||||||
|
@ -1198,26 +1223,27 @@ export default class RFB extends EventTargetMixin {
|
||||||
this._accumulatedWheelDeltaX += dX;
|
this._accumulatedWheelDeltaX += dX;
|
||||||
this._accumulatedWheelDeltaY += dY;
|
this._accumulatedWheelDeltaY += dY;
|
||||||
|
|
||||||
|
|
||||||
// Generate a mouse wheel step event when the accumulated delta
|
// Generate a mouse wheel step event when the accumulated delta
|
||||||
// for one of the axes is large enough.
|
// for one of the axes is large enough.
|
||||||
if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) {
|
if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) {
|
||||||
if (this._accumulatedWheelDeltaX < 0) {
|
if (this._accumulatedWheelDeltaX < 0) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 5);
|
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 5);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 5);
|
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
} else if (this._accumulatedWheelDeltaX > 0) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 6);
|
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 6);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 6);
|
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._accumulatedWheelDeltaX = 0;
|
this._accumulatedWheelDeltaX = 0;
|
||||||
}
|
}
|
||||||
if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) {
|
if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) {
|
||||||
if (this._accumulatedWheelDeltaY < 0) {
|
if (this._accumulatedWheelDeltaY < 0) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 3);
|
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 3);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 3);
|
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
} else if (this._accumulatedWheelDeltaY > 0) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 4);
|
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 4);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 4);
|
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._accumulatedWheelDeltaY = 0;
|
this._accumulatedWheelDeltaY = 0;
|
||||||
|
@ -1256,8 +1282,8 @@ export default class RFB extends EventTargetMixin {
|
||||||
this._gestureLastTapTime = Date.now();
|
this._gestureLastTapTime = Date.now();
|
||||||
|
|
||||||
this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y);
|
this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y);
|
||||||
this._handleMouseButton(pos.x, pos.y, true, bmask);
|
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, bmask);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleGesture(ev) {
|
_handleGesture(ev) {
|
||||||
|
@ -1278,14 +1304,27 @@ export default class RFB extends EventTargetMixin {
|
||||||
this._handleTapEvent(ev, 0x2);
|
this._handleTapEvent(ev, 0x2);
|
||||||
break;
|
break;
|
||||||
case 'drag':
|
case 'drag':
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
if (this.dragViewport) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 0x1);
|
this._viewportHasMoved = false;
|
||||||
|
this._viewportDragging = true;
|
||||||
|
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||||
|
} else {
|
||||||
|
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||||
|
this._handleMouseButton(pos.x, pos.y, 0x1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'longpress':
|
case 'longpress':
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
if (this.dragViewport) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 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._viewportHasMoved = false;
|
||||||
|
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||||
|
} else {
|
||||||
|
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||||
|
this._handleMouseButton(pos.x, pos.y, 0x4);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'twodrag':
|
case 'twodrag':
|
||||||
this._gestureLastMagnitudeX = ev.detail.magnitudeX;
|
this._gestureLastMagnitudeX = ev.detail.magnitudeX;
|
||||||
this._gestureLastMagnitudeY = ev.detail.magnitudeY;
|
this._gestureLastMagnitudeY = ev.detail.magnitudeY;
|
||||||
|
@ -1307,7 +1346,21 @@ export default class RFB extends EventTargetMixin {
|
||||||
break;
|
break;
|
||||||
case 'drag':
|
case 'drag':
|
||||||
case 'longpress':
|
case 'longpress':
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'twodrag':
|
case 'twodrag':
|
||||||
// Always scroll in the same position.
|
// Always scroll in the same position.
|
||||||
|
@ -1315,23 +1368,23 @@ export default class RFB extends EventTargetMixin {
|
||||||
// every update.
|
// every update.
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||||
while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) > GESTURE_SCRLSENS) {
|
while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) > GESTURE_SCRLSENS) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 0x8);
|
this._handleMouseButton(pos.x, pos.y, 0x8);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x8);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeY += GESTURE_SCRLSENS;
|
this._gestureLastMagnitudeY += GESTURE_SCRLSENS;
|
||||||
}
|
}
|
||||||
while ((ev.detail.magnitudeY - 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, 0x10);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x10);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeY -= GESTURE_SCRLSENS;
|
this._gestureLastMagnitudeY -= GESTURE_SCRLSENS;
|
||||||
}
|
}
|
||||||
while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) > GESTURE_SCRLSENS) {
|
while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) > GESTURE_SCRLSENS) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 0x20);
|
this._handleMouseButton(pos.x, pos.y, 0x20);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x20);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeX += GESTURE_SCRLSENS;
|
this._gestureLastMagnitudeX += GESTURE_SCRLSENS;
|
||||||
}
|
}
|
||||||
while ((ev.detail.magnitudeX - 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, 0x40);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x40);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeX -= GESTURE_SCRLSENS;
|
this._gestureLastMagnitudeX -= GESTURE_SCRLSENS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1344,13 +1397,13 @@ export default class RFB extends EventTargetMixin {
|
||||||
if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
||||||
this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||||
while ((magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
while ((magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 0x8);
|
this._handleMouseButton(pos.x, pos.y, 0x8);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x8);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeX += GESTURE_ZOOMSENS;
|
this._gestureLastMagnitudeX += GESTURE_ZOOMSENS;
|
||||||
}
|
}
|
||||||
while ((magnitude - this._gestureLastMagnitudeX) < -GESTURE_ZOOMSENS) {
|
while ((magnitude - this._gestureLastMagnitudeX) < -GESTURE_ZOOMSENS) {
|
||||||
this._handleMouseButton(pos.x, pos.y, true, 0x10);
|
this._handleMouseButton(pos.x, pos.y, 0x10);
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x10);
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS;
|
this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1368,18 +1421,46 @@ export default class RFB extends EventTargetMixin {
|
||||||
case 'twodrag':
|
case 'twodrag':
|
||||||
break;
|
break;
|
||||||
case 'drag':
|
case 'drag':
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
if (this.dragViewport) {
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x1);
|
this._viewportDragging = false;
|
||||||
|
} else {
|
||||||
|
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||||
|
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'longpress':
|
case 'longpress':
|
||||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
if (this._viewportHasMoved) {
|
||||||
this._handleMouseButton(pos.x, pos.y, false, 0x4);
|
// 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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_flushMouseMoveTimer(x, y) {
|
||||||
|
if (this._mouseMoveTimer !== null) {
|
||||||
|
clearTimeout(this._mouseMoveTimer);
|
||||||
|
this._mouseMoveTimer = null;
|
||||||
|
this._sendMouse(x, y, this._mouseButtonMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Message handlers
|
// Message handlers
|
||||||
|
|
||||||
_negotiateProtocolVersion() {
|
_negotiateProtocolVersion() {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue