feat: track point for native touch

This commit is contained in:
True Zhuanjia
2026-02-11 22:56:50 +08:00
parent 8d54ed9316
commit bb6f2f0c0d
3 changed files with 125 additions and 29 deletions
+62 -15
View File
@@ -15,7 +15,6 @@
#include <Limelight.h>
@implementation NativeTouchHandler {
TemporarySettings* currentSettings;
__weak StreamView* streamView;
bool activateCoordSelector;
bool singleTouchDisabled;
@@ -34,6 +33,9 @@
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
NSMutableSet<NSNumber *> *unassignedPointerIds;
NSMutableSet *blacklistedTouches;
bool trackPointEnabled;
NSMutableArray<CAShapeLayer *> * trackPointPool; //pre-defined pool of pointerIds.
NSMutableDictionary *pointerObjDict;
@@ -49,16 +51,19 @@
- (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings{
self = [super init];
self->streamView = view;
self->currentSettings = settings;
self->activateCoordSelector = currentSettings.pointerVelocityModeDivider.floatValue != 1.0;
self->moveEventIntervalNSec = (int64_t)(currentSettings.touchMoveEventInterval.intValue * 1000);;
self->activateCoordSelector = settings.pointerVelocityModeDivider.floatValue != 1.0;
self->moveEventIntervalNSec = (int64_t)(settings.touchMoveEventInterval.intValue * 1000);;
self->streamViewBounds = view.bounds;
self->pointerIdDict = [NSMutableDictionary dictionary];
self->pointerIdPool = [NSMutableSet set];
self->trackPointEnabled = settings.touchPointTracking;
self->trackPointPool = [NSMutableArray array];
for (uint8_t i = 0; i <= 10; i++) { //ipadOS supports upto 11 finger touches
[self->pointerIdPool addObject:@(i)];
[self->trackPointPool addObject:[GraphicUtils makeTouchTrackpointIn:streamView]];
}
self->activePointerIds = [NSMutableSet set];
self->blacklistedTouches = [NSMutableSet set];
@@ -219,7 +224,7 @@
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (asyncNativeTouch) dispatch_async(dispatch_get_global_queue(touchDownQos, 0), ^{
dispatch_async(dispatch_get_global_queue(touchDownQos, 0), ^{
for (UITouch* touch in touches){
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
if([OnScreenControls.touchesCapturedByOnScreenControls containsObject:touch]) continue;
@@ -227,16 +232,21 @@
if(self->activateCoordSelector) [self populatePointerObjIntoDict:touch];
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_DOWN withEvent:event];
}
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.position = [touch locationInView:self->streamView];
trackPoint.hidden = false;
}
[CATransaction commit];
}
});
});
else{
for (UITouch* touch in touches){
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
if([OnScreenControls.touchesCapturedByOnScreenControls containsObject:touch]) continue;
[self handleTouchDown:touch]; //generate & populate pointerId
if(self->activateCoordSelector) [self populatePointerObjIntoDict:touch];
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_DOWN withEvent:event];
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -248,6 +258,19 @@
[[self getPointerObjFromDict:touch] doesNeedResetCoords];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.position = [touch locationInView:self->streamView];
}
[CATransaction commit];
}
});
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -263,6 +286,19 @@
[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.hidden = true;
}
[CATransaction commit];
}
});
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -302,4 +338,15 @@
singleTouchDisabled = !enabled;
}
- (void)dealloc{
NSLog(@"dealloc nativeTouchHanlder %f", CACurrentMediaTime());
pointerIdDict = nil;
activePointerIds = nil;
pointerIdPool= nil;
unassignedPointerIds = nil;
blacklistedTouches = nil;
trackPointPool = nil;
pointerObjDict = nil;
}
@end
+2 -1
View File
@@ -470,9 +470,10 @@ import SVGKit
self.hasL3R3Indicator = !self.isStickWheel && !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
self.hasTrackPoint = (CommandManager.vectorTouchPads.contains(self.touchPadString)
|| self.isStickWheel
|| (self.widgetType == WidgetTypeEnum.button
&& (buttonMode == .slideAndHold || buttonMode == .slideToToggle)))
}
}
// ======================================================================================================
@objc public func setupAutoTapTimer() {
+61 -13
View File
@@ -15,7 +15,6 @@
#include <Limelight.h>
@implementation PureNativeTouchHandler {
TemporarySettings* currentSettings;
__weak StreamView* streamView;
bool activateCoordSelector;
CGFloat pointerVelocityDividerLocationByPoints;
@@ -33,6 +32,9 @@
NSMutableSet<NSNumber *> *pointerIdPool; //pre-defined pool of pointerIds.
NSMutableSet<NSNumber *> *unassignedPointerIds;
NSMutableSet *blacklistedTouches;
bool trackPointEnabled;
NSMutableArray<CAShapeLayer *> * trackPointPool;
NSMutableDictionary *pointerObjDict;
@@ -48,16 +50,20 @@
- (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings{
self = [super init];
self->streamView = view;
self->currentSettings = settings;
self->activateCoordSelector = currentSettings.pointerVelocityModeDivider.floatValue != 1.0;
self->moveEventIntervalNSec = (int64_t)(currentSettings.touchMoveEventInterval.intValue * 1000);;
self->activateCoordSelector = settings.pointerVelocityModeDivider.floatValue != 1.0;
self->moveEventIntervalNSec = (int64_t)(settings.touchMoveEventInterval.intValue * 1000);;
self->streamViewBounds = view.bounds;
self->pointerIdDict = [NSMutableDictionary dictionary];
self->pointerIdPool = [NSMutableSet set];
self->trackPointEnabled = settings.touchPointTracking;
self->trackPointPool = [NSMutableArray array];
for (uint8_t i = 0; i <= 10; i++) { //ipadOS supports upto 11 finger touches
[self->pointerIdPool addObject:@(i)];
[self->trackPointPool addObject:[GraphicUtils makeTouchTrackpointIn:streamView]];
}
self->activePointerIds = [NSMutableSet set];
self->blacklistedTouches = [NSMutableSet set];
@@ -209,22 +215,27 @@
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (asyncNativeTouch) dispatch_async(dispatch_get_global_queue(touchDownQos, 0), ^{
dispatch_async(dispatch_get_global_queue(touchDownQos, 0), ^{
for (UITouch* touch in touches){
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
[self handleTouchDown:touch]; //generate & populate pointerId
if(self->activateCoordSelector) [self populatePointerObjIntoDict:touch];
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_DOWN];
}
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.position = [touch locationInView:self->streamView];
trackPoint.hidden = false;
}
[CATransaction commit];
}
});
});
else{
for (UITouch* touch in touches){
// continue to the next loop if current touch is already captured by OSC. works only in regular native touch
[self handleTouchDown:touch]; //generate & populate pointerId
if(self->activateCoordSelector) [self populatePointerObjIntoDict:touch];
[self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_DOWN];
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -235,6 +246,19 @@
[[self getPointerObjFromDict:touch] doesNeedResetCoords];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.position = [touch locationInView:self->streamView];
}
[CATransaction commit];
}
});
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -246,6 +270,19 @@
[self->blacklistedTouches removeObject:@((uintptr_t)touch)];
}
});
dispatch_async(dispatch_get_main_queue(), ^{
if(self->trackPointEnabled){
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (UITouch* touch in touches){
uint8_t pointerId = [self retrievePointerIdFromDict:touch];
CAShapeLayer* trackPoint = self->trackPointPool[pointerId];
trackPoint.hidden = true;
}
[CATransaction commit];
}
});
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
@@ -281,5 +318,16 @@
return pointer.useRelativeCoords ? pointer.latestRelativePoint : pointer.latestPoint;
}
- (void)dealloc{
NSLog(@"dealloc purePativeTouchHanlder %f", CACurrentMediaTime());
pointerIdDict = nil;
activePointerIds = nil;
pointerIdPool= nil;
unassignedPointerIds = nil;
blacklistedTouches = nil;
trackPointPool = nil;
pointerObjDict = nil;
}
@end