fixed: unable to move mouse cursor under touchpad mode or on mousepad widget when finger moves slowly

This commit is contained in:
TrueZhuanjia committed 2025-12-01 18:51:58 +08:00
1 parent cbf42b1e52
commit 9916f64065
4 files changed
+78 -63

No files matched your search

+54 -31
View File
@@ -135,6 +135,9 @@ import UIKit
@objc public var deltaX: CGFloat @objc public var deltaX: CGFloat
@objc public var deltaY: CGFloat @objc public var deltaY: CGFloat
@objc private var weightedDeltaX: Int = 0
@objc private var weightedDeltaY: Int = 0
// for LSPAD, RSPAD // for LSPAD, RSPAD
@objc public var offSetX: CGFloat @objc public var offSetX: CGFloat
@objc public var offSetY: CGFloat @objc public var offSetY: CGFloat
@@ -1683,21 +1686,23 @@ import UIKit
self.mousePointerMoved = true self.mousePointerMoved = true
} }
let vector = UITouchUtil.vector(of: touch, in: self)
self.deltaX = vector.dx
self.deltaY = vector.dy
self.offSetX = currentTouchLocation.x - self.touchBeganLocation.x
self.offSetY = currentTouchLocation.y - self.touchBeganLocation.y
}
private func updateTouchLocation(_ touches: Set<UITouch>){
let currentTouchLocation = touches.first!.location(in: self)
//if !firstTouchMoved, !self.isAdjacentPoints(currentTouchLocation, from: touchBeganLocation, tolerance: 0.5) {
if !firstTouchMoved, !self.isAdjacentPoints(currentTouchLocation, from: touchBeganLocation, tolerance: slideThreshold) { if !firstTouchMoved, !self.isAdjacentPoints(currentTouchLocation, from: touchBeganLocation, tolerance: slideThreshold) {
// First move event // First move event
self.latestTouchLocation = currentTouchLocation self.latestTouchLocation = currentTouchLocation
self.firstTouchMoved = true self.firstTouchMoved = true
} }
self.deltaX = currentTouchLocation.x - self.latestTouchLocation.x
self.deltaY = currentTouchLocation.y - self.latestTouchLocation.y
self.offSetX = currentTouchLocation.x - self.touchBeganLocation.x
self.offSetY = currentTouchLocation.y - self.touchBeganLocation.y
}
private func updateTouchLocation(touch: UITouch){
let currentTouchLocation: CGPoint = (touch.location(in: self))
if weightedDeltaX != 0 || weightedDeltaY != 0 {
self.latestTouchLocation = currentTouchLocation
}
} }
private func handleTouchPadMoveEvent (_ touches: Set<UITouch>, with event: UIEvent?){ private func handleTouchPadMoveEvent (_ touches: Set<UITouch>, with event: UIEvent?){
@@ -1706,24 +1711,30 @@ import UIKit
switch self.touchPadString{ switch self.touchPadString{
case "MOUSEPAD": case "MOUSEPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
if self.firstTouchMoved {LiSendMouseMoveEvent(Int16(self.deltaX * 1.7 * self.sensitivityFactorX), Int16(self.deltaY * 1.7 * self.sensitivityFactorY))} self.weightedDeltaX = Int(self.deltaX * 1.7 * self.sensitivityFactorX)
self.updateTouchLocation(touches) self.weightedDeltaY = Int(self.deltaY * 1.7 * self.sensitivityFactorY)
if self.firstTouchMoved {LiSendMouseMoveEvent(Int16(self.weightedDeltaX), Int16(self.weightedDeltaY))}
self.updateTouchLocation(touch: touches.first!)
} }
break break
case "TRACKBALL": case "TRACKBALL":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = Int(self.deltaX * 1.7 * self.sensitivityFactorX)
self.weightedDeltaY = Int(self.deltaY * 1.7 * self.sensitivityFactorY)
if self.firstTouchMoved { if self.firstTouchMoved {
LiSendMouseMoveEvent(Int16(self.deltaX * 1.7 * self.sensitivityFactorX), Int16(self.deltaY * 1.7 * self.sensitivityFactorY)) LiSendMouseMoveEvent(Int16(self.weightedDeltaX), Int16(self.weightedDeltaY))
self.trackballVelocity = CGPoint(x: self.deltaX * 1.7 * self.sensitivityFactorX, y: self.deltaY * 1.7 * self.sensitivityFactorY) self.trackballVelocity = CGPoint(x: self.weightedDeltaX, y: self.weightedDeltaY)
self.stopTrackballMomentum() self.stopTrackballMomentum()
} }
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
} }
break break
case "ABSMOUSE": case "ABSMOUSE":
self.weightedDeltaX = Int(self.deltaX * 1.7 * self.sensitivityFactorX)
self.weightedDeltaY = Int(self.deltaY * 1.7 * self.sensitivityFactorY)
if self.firstTouchMoved { if self.firstTouchMoved {
if !self.absMousePaused { if !self.absMousePaused {
let reachedEdgeMask = LiSendMouseMoveAsMousePositionEvent(Int16(truncatingIfNeeded: Int(self.deltaX * 1.7 * self.sensitivityFactorX)), Int16(truncatingIfNeeded: Int(self.deltaY * 1.7 * self.sensitivityFactorY)), Int16(self.superViewWidth), Int16(self.superViewHeight)) let reachedEdgeMask = LiSendMouseMoveAsMousePositionEvent(Int16(truncatingIfNeeded: self.weightedDeltaX), Int16(truncatingIfNeeded: self.weightedDeltaY), Int16(self.superViewWidth), Int16(self.superViewHeight))
if reachedEdgeMask>0 { if reachedEdgeMask>0 {
self.handleMousePadButtonActionUp() self.handleMousePadButtonActionUp()
self.absMousePaused = true self.absMousePaused = true
@@ -1735,59 +1746,71 @@ import UIKit
} }
} }
} }
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
break break
case "LSPAD": case "LSPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendLeftStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY) self.sendLeftStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY)
} }
if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()} if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()}
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
case "RSPAD": case "RSPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendRightStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY) self.sendRightStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY)
} }
if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()} if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()}
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
case "LSVPAD": case "LSVPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = Int(self.deltaX*1.5167*self.sensitivityFactorX)
self.weightedDeltaY = Int(self.deltaY*1.5167*self.sensitivityFactorY)
if self.firstTouchMoved { if self.firstTouchMoved {
self.sendLeftStickTouchPadEvent(inputX: self.deltaX*1.5167*self.sensitivityFactorX, inputY: self.deltaY*1.5167*self.sensitivityFactorY) self.sendLeftStickTouchPadEvent(inputX: CGFloat(self.weightedDeltaX), inputY: CGFloat(self.weightedDeltaY))
} }
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
} }
case "RSVPAD": case "RSVPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = Int(self.deltaX*1.5167*self.sensitivityFactorX)
self.weightedDeltaY = Int(self.deltaY*1.5167*self.sensitivityFactorY)
if self.firstTouchMoved { if self.firstTouchMoved {
self.sendRightStickTouchPadEvent(inputX: self.deltaX*1.5167*self.sensitivityFactorX, inputY: self.deltaY*1.5167*self.sensitivityFactorY) self.sendRightStickTouchPadEvent(inputX: CGFloat(self.weightedDeltaX), inputY: CGFloat(self.weightedDeltaY))
} }
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
} }
case "LTPAD": case "LTPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.sendLeftTriggerTouchPadEvent(inputY: (-self.offSetY*4.5*self.sensitivityFactorY)) self.weightedDeltaY = 1
self.updateTouchLocation(touches) self.sendLeftTriggerTouchPadEvent(inputY: -self.offSetY*4.5*self.sensitivityFactorY)
self.updateTouchLocation(touch: touches.first!)
} }
case "RTPAD": case "RTPAD":
DispatchQueue.global(qos: .userInteractive).async { DispatchQueue.global(qos: .userInteractive).async {
self.sendRightTriggerTouchPadEvent(inputY: (-self.offSetY*4.5*self.sensitivityFactorY)) self.weightedDeltaY = 1
self.updateTouchLocation(touches) self.sendRightTriggerTouchPadEvent(inputY: -self.offSetY*4.5*self.sensitivityFactorY)
self.updateTouchLocation(touch: touches.first!)
} }
case "DPAD", "WASDPAD", "ARROWPAD": case "DPAD", "WASDPAD", "ARROWPAD":
self.weightedDeltaX = 1
handleLrudTouchMove() handleLrudTouchMove()
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
case "MOUSEWHEEL","WHEEL": case "MOUSEWHEEL","WHEEL":
if firstTouchMoved {LiSendHighResScrollEvent(Int16(self.deltaY*7.5*self.sensitivityFactorY))} self.weightedDeltaY = Int(self.deltaY*7.5*self.sensitivityFactorY)
self.updateTouchLocation(touches) if firstTouchMoved {LiSendHighResScrollEvent(Int16(self.weightedDeltaY))}
self.updateTouchLocation(touch: touches.first!)
case "DISCRETEWHEEL", "DSWHEEL": case "DISCRETEWHEEL", "DSWHEEL":
let currentLocation = touches.first!.location(in: self) let currentLocation = touches.first!.location(in: self)
tickFlag = (tickFlag+1)%UInt8(CGFloat(tickCycle)/abs(sensitivityFactorY)) tickFlag = (tickFlag+1)%UInt8(CGFloat(tickCycle)/abs(sensitivityFactorY))
var delta = self.deltaY var delta = self.deltaY
self.weightedDeltaY = 1
if delta==0 {self.weightedDeltaY = 0}
if delta==0 {delta=self.touchBeganLocation.y-currentLocation.y} if delta==0 {delta=self.touchBeganLocation.y-currentLocation.y}
delta = delta * CGFloat(copysign(1.0, sensitivityFactorY)) delta = delta * CGFloat(copysign(1.0, sensitivityFactorY))
if tickFlag == 1, delta != 0 {LiSendScrollEvent(delta > 0 ? -3 : 3)} if tickFlag == 1, delta != 0 {LiSendScrollEvent(delta > 0 ? -3 : 3)}
// self.latestTouchLocation = currentLocation // self.latestTouchLocation = currentLocation
self.updateTouchLocation(touches) self.updateTouchLocation(touch: touches.first!)
default: default:
break break
} }
+13 -7
View File
@@ -230,19 +230,25 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2;
- (void)sendMouseMoveEvent:(CGPoint)currentLocation{ - (void)sendMouseMoveEvent:(CGPoint)currentLocation{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
CGVector vector = [UITouchUtil vectorOf:self->touchLockedForMouseMove in:self->streamView];
int deltaX = vector.dx * 1.35 * self->currentSettings.mousePointerVelocityFactor.floatValue;
int deltaY = vector.dy * 1.35 * self->currentSettings.mousePointerVelocityFactor.floatValue;
if(self->touchPointSpawnedAtUpperScreenEdge) return; // we're done here. this touch event will not be sent to the remote PC.
if(self->firstTouchMoved) LiSendMouseMoveEvent(deltaX, deltaY);
bool isAdjacentPoints = [self isAdjacentPoints:self->initialMousePointerLocation from:currentLocation tolerance:self->currentSettings.relativeTouchSlideThreshold.floatValue]; bool isAdjacentPoints = [self isAdjacentPoints:self->initialMousePointerLocation from:currentLocation tolerance:self->currentSettings.relativeTouchSlideThreshold.floatValue];
if (!self->firstTouchMoved && !isAdjacentPoints) { if (!self->firstTouchMoved && !isAdjacentPoints) {
self->latestMousePointerLocation = currentLocation; self->latestMousePointerLocation = currentLocation;
self->firstTouchMoved = true; self->firstTouchMoved = true;
} }
if (self->latestMousePointerLocation.x != currentLocation.x ||
self->latestMousePointerLocation.y != currentLocation.y)
{
int deltaX = (currentLocation.x - self->latestMousePointerLocation.x) * 1.35 * self->currentSettings.mousePointerVelocityFactor.floatValue;
int deltaY = (currentLocation.y - self->latestMousePointerLocation.y) * 1.35 * self->currentSettings.mousePointerVelocityFactor.floatValue;
if (deltaX != 0 || deltaY != 0) {
self->latestMousePointerLocation = currentLocation;
if(self->touchPointSpawnedAtUpperScreenEdge) return; // we're done here. this touch event will not be sent to the remote PC.
if(self->firstTouchMoved) LiSendMouseMoveEvent(deltaX, deltaY);
}
}
}); });
} }
+4 -2
View File
@@ -30,8 +30,10 @@ import UIKit
let currentDistance = UITouchUtil.distance(between: touch1, and: touch2, in: view) let currentDistance = UITouchUtil.distance(between: touch1, and: touch2, in: view)
let previousDistance = UITouchUtil.previousDistance(between: touch1, and: touch2, in: view) let previousDistance = UITouchUtil.previousDistance(between: touch1, and: touch2, in: view)
let midPointDeltaY = UITouchUtil.midPointDeltaY(between: touch1, and: touch2, in: view)
let midPointDeltaX = UITouchUtil.midPointDeltaX(between: touch1, and: touch2, in: view) let midPointVector = UITouchUtil.midPointVector(between: touch1, and: touch2, in: view)
let midPointDeltaX = midPointVector.dx
let midPointDeltaY = midPointVector.dy
let originalPinchDelta = currentDistance-previousDistance; let originalPinchDelta = currentDistance-previousDistance;
let pinchDelta = enablePinch ? originalPinchDelta*7*pinchSensitivity : 0; let pinchDelta = enablePinch ? originalPinchDelta*7*pinchSensitivity : 0;
+7 -23
View File
@@ -28,13 +28,6 @@ import UIKit
return hypot(p1.x - p2.x, p1.y - p2.y) return hypot(p1.x - p2.x, p1.y - p2.y)
} }
@objc public static func vector(from touch1: UITouch?, to touch2: UITouch?, in view: UIView?) -> CGVector {
guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return CGVectorMake(0,0) }
let p1 = touch1.location(in: view)
let p2 = touch2.location(in: view)
return CGVectorMake(p2.x - p1.x, p2.y - p1.y)
}
@objc public static func vector(of touch: UITouch?, in view: UIView?) -> CGVector { @objc public static func vector(of touch: UITouch?, in view: UIView?) -> CGVector {
guard let view = view, let touch = touch else { return CGVectorMake(0,0) } guard let view = view, let touch = touch else { return CGVectorMake(0,0) }
let p2 = touch.location(in: view) let p2 = touch.location(in: view)
@@ -42,24 +35,15 @@ import UIKit
return CGVectorMake(p2.x - p1.x, p2.y - p1.y) return CGVectorMake(p2.x - p1.x, p2.y - p1.y)
} }
@objc public static func getDeltaX(from touch: UITouch?, in view: UIView?) -> CGFloat { @objc public static func midPointVector(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGVector {
guard let view = view, let touch = touch else { return 0 } guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return CGVector(dx: 0, dy: 0)}
return touch.location(in: view).x - touch.previousLocation(in: view).x
}
@objc public static func getDeltaY(from touch: UITouch?, in view: UIView?) -> CGFloat { let vector1 = vector(of: touch1, in: view)
guard let view = view, let touch = touch else { return 0 } let vector2 = vector(of: touch2, in: view)
return touch.location(in: view).y - touch.previousLocation(in: view).y
}
@objc public static func midPointDeltaX(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGFloat { let deltaX = (vector1.dx+vector2.dx)/2
guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return 0 } let deltaY = (vector1.dy+vector2.dy)/2
return (touch1.location(in: view).x+touch2.location(in: view).x)/2 - (touch1.previousLocation(in: view).x+touch2.previousLocation(in: view).x)/2
}
@objc public static func midPointDeltaY(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGFloat { return CGVector(dx: deltaX, dy: deltaY)
guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return 0 }
return (touch1.location(in: view).y+touch2.location(in: view).y)/2 - (touch1.previousLocation(in: view).y+touch2.previousLocation(in: view).y)/2
} }
} }