diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index 8a189f5d..5e120067 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -135,6 +135,9 @@ import UIKit @objc public var deltaX: CGFloat @objc public var deltaY: CGFloat + @objc private var weightedDeltaX: Int = 0 + @objc private var weightedDeltaY: Int = 0 + // for LSPAD, RSPAD @objc public var offSetX: CGFloat @objc public var offSetY: CGFloat @@ -1683,21 +1686,23 @@ import UIKit 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){ - 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) { // First move event self.latestTouchLocation = currentTouchLocation 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, with event: UIEvent?){ @@ -1706,24 +1711,30 @@ import UIKit switch self.touchPadString{ case "MOUSEPAD": DispatchQueue.global(qos: .userInteractive).async { - if self.firstTouchMoved {LiSendMouseMoveEvent(Int16(self.deltaX * 1.7 * self.sensitivityFactorX), Int16(self.deltaY * 1.7 * self.sensitivityFactorY))} - self.updateTouchLocation(touches) + self.weightedDeltaX = Int(self.deltaX * 1.7 * self.sensitivityFactorX) + 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 case "TRACKBALL": 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 { - LiSendMouseMoveEvent(Int16(self.deltaX * 1.7 * self.sensitivityFactorX), Int16(self.deltaY * 1.7 * self.sensitivityFactorY)) - self.trackballVelocity = CGPoint(x: self.deltaX * 1.7 * self.sensitivityFactorX, y: self.deltaY * 1.7 * self.sensitivityFactorY) + LiSendMouseMoveEvent(Int16(self.weightedDeltaX), Int16(self.weightedDeltaY)) + self.trackballVelocity = CGPoint(x: self.weightedDeltaX, y: self.weightedDeltaY) self.stopTrackballMomentum() } - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) } break 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.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 { self.handleMousePadButtonActionUp() self.absMousePaused = true @@ -1735,59 +1746,71 @@ import UIKit } } } - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) break case "LSPAD": DispatchQueue.global(qos: .userInteractive).async { + self.weightedDeltaX = 1 self.sendLeftStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY) } if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()} - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) case "RSPAD": DispatchQueue.global(qos: .userInteractive).async { + self.weightedDeltaX = 1 self.sendRightStickTouchPadEvent(inputX: self.offSetX * self.sensitivityFactorX, inputY: self.offSetY * self.sensitivityFactorY) } if widgetType == WidgetTypeEnum.touchPad {updateStickIndicator()} - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) case "LSVPAD": 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 { - 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": 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 { - 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": DispatchQueue.global(qos: .userInteractive).async { - self.sendLeftTriggerTouchPadEvent(inputY: (-self.offSetY*4.5*self.sensitivityFactorY)) - self.updateTouchLocation(touches) + self.weightedDeltaY = 1 + self.sendLeftTriggerTouchPadEvent(inputY: -self.offSetY*4.5*self.sensitivityFactorY) + self.updateTouchLocation(touch: touches.first!) } case "RTPAD": DispatchQueue.global(qos: .userInteractive).async { - self.sendRightTriggerTouchPadEvent(inputY: (-self.offSetY*4.5*self.sensitivityFactorY)) - self.updateTouchLocation(touches) + self.weightedDeltaY = 1 + self.sendRightTriggerTouchPadEvent(inputY: -self.offSetY*4.5*self.sensitivityFactorY) + self.updateTouchLocation(touch: touches.first!) } case "DPAD", "WASDPAD", "ARROWPAD": + self.weightedDeltaX = 1 handleLrudTouchMove() - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) case "MOUSEWHEEL","WHEEL": - if firstTouchMoved {LiSendHighResScrollEvent(Int16(self.deltaY*7.5*self.sensitivityFactorY))} - self.updateTouchLocation(touches) + self.weightedDeltaY = Int(self.deltaY*7.5*self.sensitivityFactorY) + if firstTouchMoved {LiSendHighResScrollEvent(Int16(self.weightedDeltaY))} + self.updateTouchLocation(touch: touches.first!) case "DISCRETEWHEEL", "DSWHEEL": let currentLocation = touches.first!.location(in: self) tickFlag = (tickFlag+1)%UInt8(CGFloat(tickCycle)/abs(sensitivityFactorY)) var delta = self.deltaY + self.weightedDeltaY = 1 + if delta==0 {self.weightedDeltaY = 0} if delta==0 {delta=self.touchBeganLocation.y-currentLocation.y} delta = delta * CGFloat(copysign(1.0, sensitivityFactorY)) if tickFlag == 1, delta != 0 {LiSendScrollEvent(delta > 0 ? -3 : 3)} // self.latestTouchLocation = currentLocation - self.updateTouchLocation(touches) + self.updateTouchLocation(touch: touches.first!) default: break } diff --git a/VoidLink/Input/RelativeTouchHandler.m b/VoidLink/Input/RelativeTouchHandler.m index 33d3b547..f72c20bd 100644 --- a/VoidLink/Input/RelativeTouchHandler.m +++ b/VoidLink/Input/RelativeTouchHandler.m @@ -230,19 +230,25 @@ static const float QUICK_TAP_TIME_INTERVAL = 0.2; - (void)sendMouseMoveEvent:(CGPoint)currentLocation{ 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]; if (!self->firstTouchMoved && !isAdjacentPoints) { self->latestMousePointerLocation = currentLocation; 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); + } + } }); } diff --git a/VoidLink/Input/TouchPadGestureHandler.swift b/VoidLink/Input/TouchPadGestureHandler.swift index b0e2e705..4f3eac9f 100644 --- a/VoidLink/Input/TouchPadGestureHandler.swift +++ b/VoidLink/Input/TouchPadGestureHandler.swift @@ -30,8 +30,10 @@ import UIKit let currentDistance = UITouchUtil.distance(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 pinchDelta = enablePinch ? originalPinchDelta*7*pinchSensitivity : 0; diff --git a/VoidLink/Input/UITouchUtil.swift b/VoidLink/Input/UITouchUtil.swift index 310b5b97..b0d61472 100644 --- a/VoidLink/Input/UITouchUtil.swift +++ b/VoidLink/Input/UITouchUtil.swift @@ -28,13 +28,6 @@ import UIKit 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 { guard let view = view, let touch = touch else { return CGVectorMake(0,0) } let p2 = touch.location(in: view) @@ -42,24 +35,15 @@ import UIKit return CGVectorMake(p2.x - p1.x, p2.y - p1.y) } - @objc public static func getDeltaX(from touch: UITouch?, in view: UIView?) -> CGFloat { - guard let view = view, let touch = touch else { return 0 } - return touch.location(in: view).x - touch.previousLocation(in: view).x - } - - @objc public static func getDeltaY(from touch: UITouch?, in view: UIView?) -> CGFloat { - guard let view = view, let touch = touch else { return 0 } - 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 { - guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return 0 } - 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 { - 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 - } + @objc public static func midPointVector(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGVector { + guard let view = view, let touch1 = touch1, let touch2 = touch2 else { return CGVector(dx: 0, dy: 0)} + + let vector1 = vector(of: touch1, in: view) + let vector2 = vector(of: touch2, in: view) + + let deltaX = (vector1.dx+vector2.dx)/2 + let deltaY = (vector1.dy+vector2.dy)/2 + return CGVector(dx: deltaX, dy: deltaY) + } }