Fake cursor position when using touch

With the new gestures we will simulate the cursor being in a different
location than any of the touch points. This is a bit too complex for the
Cursor class, so let's just explicitly tell it where we want the cursor
rendered.
This commit is contained in:
Samuel Mannehed 2020-06-11 15:52:34 +02:00
parent 50cde2faab
commit 32ed7c6724
2 changed files with 29 additions and 43 deletions

View File

@ -1058,6 +1058,11 @@ export default class RFB extends EventTargetMixin {
} }
} }
_fakeMouseMove(ev, elementX, elementY) {
this._handleMouseMove(elementX, elementY);
this._cursor.move(ev.detail.clientX, ev.detail.clientY);
}
_handleTapEvent(ev, bmask) { _handleTapEvent(ev, bmask) {
let pos = clientToElement(ev.detail.clientX, ev.detail.clientY, let pos = clientToElement(ev.detail.clientX, ev.detail.clientY,
this._canvas); this._canvas);
@ -1084,7 +1089,7 @@ export default class RFB extends EventTargetMixin {
} }
this._gestureLastTapTime = Date.now(); this._gestureLastTapTime = Date.now();
this._handleMouseMove(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, true, bmask);
this._handleMouseButton(pos.x, pos.y, false, bmask); this._handleMouseButton(pos.x, pos.y, false, bmask);
} }
@ -1107,23 +1112,23 @@ export default class RFB extends EventTargetMixin {
this._handleTapEvent(ev, 0x2); this._handleTapEvent(ev, 0x2);
break; break;
case 'drag': case 'drag':
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, true, 0x1); this._handleMouseButton(pos.x, pos.y, true, 0x1);
break; break;
case 'longpress': case 'longpress':
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, true, 0x4); this._handleMouseButton(pos.x, pos.y, true, 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;
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
break; break;
case 'pinch': case 'pinch':
this._gestureLastMagnitudeX = Math.hypot(ev.detail.magnitudeX, this._gestureLastMagnitudeX = Math.hypot(ev.detail.magnitudeX,
ev.detail.magnitudeY); ev.detail.magnitudeY);
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
break; break;
} }
break; break;
@ -1136,13 +1141,13 @@ export default class RFB extends EventTargetMixin {
break; break;
case 'drag': case 'drag':
case 'longpress': case 'longpress':
this._handleMouseMove(pos.x, pos.y); 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.
// We don't know if the mouse was moved so we need to move it // We don't know if the mouse was moved so we need to move it
// every update. // every update.
this._handleMouseMove(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, true, 0x8);
this._handleMouseButton(pos.x, pos.y, false, 0x8); this._handleMouseButton(pos.x, pos.y, false, 0x8);
@ -1168,7 +1173,7 @@ export default class RFB extends EventTargetMixin {
// Always scroll in the same position. // Always scroll in the same position.
// We don't know if the mouse was moved so we need to move it // We don't know if the mouse was moved so we need to move it
// every update. // every update.
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY); magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY);
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);
@ -1184,6 +1189,7 @@ export default class RFB extends EventTargetMixin {
} }
} }
this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", false); this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", false);
break;
} }
break; break;
@ -1196,11 +1202,11 @@ export default class RFB extends EventTargetMixin {
case 'twodrag': case 'twodrag':
break; break;
case 'drag': case 'drag':
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, false, 0x1); this._handleMouseButton(pos.x, pos.y, false, 0x1);
break; break;
case 'longpress': case 'longpress':
this._handleMouseMove(pos.x, pos.y); this._fakeMouseMove(ev, pos.x, pos.y);
this._handleMouseButton(pos.x, pos.y, false, 0x4); this._handleMouseButton(pos.x, pos.y, false, 0x4);
break; break;
} }

View File

@ -30,9 +30,6 @@ export default class Cursor {
'mouseleave': this._handleMouseLeave.bind(this), 'mouseleave': this._handleMouseLeave.bind(this),
'mousemove': this._handleMouseMove.bind(this), 'mousemove': this._handleMouseMove.bind(this),
'mouseup': this._handleMouseUp.bind(this), 'mouseup': this._handleMouseUp.bind(this),
'touchstart': this._handleTouchStart.bind(this),
'touchmove': this._handleTouchMove.bind(this),
'touchend': this._handleTouchEnd.bind(this),
}; };
} }
@ -54,11 +51,6 @@ export default class Cursor {
this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options); this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options);
this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options); this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options);
this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options); this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options);
// There is no "touchleave" so we monitor touchstart globally
window.addEventListener('touchstart', this._eventHandlers.touchstart, options);
this._target.addEventListener('touchmove', this._eventHandlers.touchmove, options);
this._target.addEventListener('touchend', this._eventHandlers.touchend, options);
} }
this.clear(); this.clear();
@ -76,10 +68,6 @@ export default class Cursor {
this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options); this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options);
this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options); this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options);
window.removeEventListener('touchstart', this._eventHandlers.touchstart, options);
this._target.removeEventListener('touchmove', this._eventHandlers.touchmove, options);
this._target.removeEventListener('touchend', this._eventHandlers.touchend, options);
document.body.removeChild(this._canvas); document.body.removeChild(this._canvas);
} }
@ -131,6 +119,19 @@ export default class Cursor {
this._hotSpot.y = 0; this._hotSpot.y = 0;
} }
// Mouse events might be emulated, this allows
// moving the cursor in such cases
move(clientX, clientY) {
if (!useFallback) {
return;
}
this._position.x = clientX;
this._position.y = clientY;
this._updatePosition();
let target = document.elementFromPoint(clientX, clientY);
this._updateVisibility(target);
}
_handleMouseOver(event) { _handleMouseOver(event) {
// This event could be because we're entering the target, or // This event could be because we're entering the target, or
// moving around amongst its sub elements. Let the move handler // moving around amongst its sub elements. Let the move handler
@ -179,27 +180,6 @@ export default class Cursor {
} }
} }
_handleTouchStart(event) {
// Just as for mouseover, we let the move handler deal with it
this._handleTouchMove(event);
}
_handleTouchMove(event) {
this._updateVisibility(event.target);
this._position.x = event.changedTouches[0].clientX - this._hotSpot.x;
this._position.y = event.changedTouches[0].clientY - this._hotSpot.y;
this._updatePosition();
}
_handleTouchEnd(event) {
// Same principle as for mouseup
let target = document.elementFromPoint(event.changedTouches[0].clientX,
event.changedTouches[0].clientY);
this._updateVisibility(target);
}
_showCursor() { _showCursor() {
if (this._canvas.style.visibility === 'hidden') { if (this._canvas.style.visibility === 'hidden') {
this._canvas.style.visibility = ''; this._canvas.style.visibility = '';