resolve gesture competition in non-native touch modes

This commit is contained in:
True Zhuanjia committed 2024-06-18 02:12:35 +08:00
1 parent c3d44647f9
commit c3c7e670fc
5 files changed
+25 -5

No files matched your search

@@ -17,6 +17,7 @@
@property (nonatomic, assign) uint8_t numberOfTouchesRequired; @property (nonatomic, assign) uint8_t numberOfTouchesRequired;
@property (nonatomic, assign) bool immediateTriggering; // trigger the signal on touchesBegan stage if enabled.
@property (nonatomic, assign) double tapDownTimeThreshold; // tap down threshold in seconds. @property (nonatomic, assign) double tapDownTimeThreshold; // tap down threshold in seconds.
@property (nonatomic, readonly) CGFloat lowestTouchPointHeight; @property (nonatomic, readonly) CGFloat lowestTouchPointHeight;
@property (nonatomic, readonly) bool gestureCaptured; @property (nonatomic, readonly) bool gestureCaptured;
+15 -2
View File
@@ -10,8 +10,11 @@
#import <UIKit/UIGestureRecognizerSubclass.h> #import <UIKit/UIGestureRecognizerSubclass.h>
#import "CustomTapGestureRecognizer.h" #import "CustomTapGestureRecognizer.h"
// The most accurate & reliable tap gesture recognizer of iOS with almost 100% recoginition rate, instances of different numberOfTouchesRequired barely compete with each other. UITapGestureRecognizer of Apple API is just intractable. // The most accurate & reliable tap gesture recognizer of iOS:
// Known issue: not reliable in absolute touch mode, since it competes with 2 finger zoom-in & out gestures from original moonlight // - almost 100% recoginition rate. UITapGestureRecognizer of Apple API is just intractable.
// - instances of different numberOfTouchesRequired barely compete with each other, even when immediateTriggering is set to false.
// - set property immediateTriggering = true, ensures no competition with gestures of less fingers in non-native touch mode.
@implementation CustomTapGestureRecognizer @implementation CustomTapGestureRecognizer
static CGFloat screenHeightInPoints; static CGFloat screenHeightInPoints;
@@ -20,6 +23,10 @@ static CGFloat screenHeightInPoints;
self = [super initWithTarget:target action:action]; self = [super initWithTarget:target action:action];
screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]); screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]);
lowestTouchPointYCoord = 0.0; lowestTouchPointYCoord = 0.0;
_numberOfTouchesRequired = 3;
_immediateTriggering = false;
_tapDownTimeThreshold = 0.3;
_gestureCaptured = false;
return self; return self;
} }
@@ -32,6 +39,11 @@ static CGFloat screenHeightInPoints;
if(lowestTouchPointYCoord < [touch locationInView:self.view].y) lowestTouchPointYCoord = [touch locationInView:self.view].y; if(lowestTouchPointYCoord < [touch locationInView:self.view].y) lowestTouchPointYCoord = [touch locationInView:self.view].y;
} }
_lowestTouchPointHeight = screenHeightInPoints - lowestTouchPointYCoord; _lowestTouchPointHeight = screenHeightInPoints - lowestTouchPointYCoord;
if(_immediateTriggering){
lowestTouchPointYCoord = 0.0; //reset for next recoginition
self.state = UIGestureRecognizerStateRecognized;
return;
}
self.state = UIGestureRecognizerStatePossible; self.state = UIGestureRecognizerStatePossible;
} }
if ([[event allTouches] count] > _numberOfTouchesRequired) { if ([[event allTouches] count] > _numberOfTouchesRequired) {
@@ -42,6 +54,7 @@ static CGFloat screenHeightInPoints;
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// [super touchesEnded:touches withEvent:event]; // [super touchesEnded:touches withEvent:event];
if(_immediateTriggering) return;
if([[event allTouches] count] > _numberOfTouchesRequired) { if([[event allTouches] count] > _numberOfTouchesRequired) {
_gestureCaptured = false; _gestureCaptured = false;
self.state = UIGestureRecognizerStateFailed; self.state = UIGestureRecognizerStateFailed;
+1 -1
View File
@@ -10,7 +10,7 @@
#import "CustomTapGestureRecognizer.h" #import "CustomTapGestureRecognizer.h"
#include <Limelight.h> #include <Limelight.h>
#define RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S 0.1 #define RIGHTCLICK_TAP_DOWN_TIME_THRESHOLD_S 0.2
static const int REFERENCE_WIDTH = 1280; static const int REFERENCE_WIDTH = 1280;
+7 -2
View File
@@ -100,9 +100,14 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
case NATIVE_TOUCH_MODE: case NATIVE_TOUCH_MODE:
self->touchHandler = [[NativeTouchHandler alloc] initWith:self and:settings];break; self->touchHandler = [[NativeTouchHandler alloc] initWith:self and:settings];break;
case RELATIVE_TOUCH_MODE: case RELATIVE_TOUCH_MODE:
self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self]; break; self->touchHandler = [[RelativeTouchHandler alloc] initWithView:self];
keyboardToggleRecognizer.immediateTriggering = true; //triggers signal in touchesBegan callback stage
break;
case ABSOLUTE_TOUCH_MODE: case ABSOLUTE_TOUCH_MODE:
self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self]; break; self->touchHandler = [[AbsoluteTouchHandler alloc] initWithView:self];
keyboardToggleRecognizer.immediateTriggering = true; //triggers signal in touchesBegan callback stage
break;
default: default:
break; break;
} }
@@ -196,6 +196,7 @@
_scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame]; _scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
#if !TARGET_OS_TV #if !TARGET_OS_TV
[_scrollView.panGestureRecognizer setMinimumNumberOfTouches:2]; [_scrollView.panGestureRecognizer setMinimumNumberOfTouches:2];
[_scrollView.panGestureRecognizer setMaximumNumberOfTouches:2]; // reduce competing with keyboardToggleRecognizer in StreamView.
#endif #endif
[_scrollView setShowsHorizontalScrollIndicator:NO]; [_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO]; [_scrollView setShowsVerticalScrollIndicator:NO];