mirror of
https://github.com/utmapp/UTM.git
synced 2026-10-12 02:24:01 +00:00
display(iOS): start pan gestures without waiting for swipes
Every pan and the pinch required the three finger keyboard swipes to fail first, and a swipe recognizer only fails once the touch has moved far enough to be judged or after about half a second. Moving the cursor with one finger, scrolling with two or pinching therefore did nothing for a quarter to half a second, and a short or slow two finger scroll was mostly lost. A swipe can only be confused with a pan that uses the same number of touches, so only the three finger pan still waits for the keyboard swipes. The pinch needs a guard instead: before iOS 18 it begins with two of three fingers and would take the touches from the swipe, so it is not allowed to begin while three fingers are down. That also stops three fingers from zooming the display on those versions. The two finger pan still waits for the two finger swipe when the two are bound to different actions. When both scroll the mouse wheel there is nothing to tell apart: the pan scrolls right away and a swipe adds its wheel tick on top, where before any steady two finger drag was taken for a swipe and scrolled a single tick. Because the two now scroll together, the swipe follows the "Invert Scroll" setting like the pan. Reworked from #7697. Assisted-by: Claude:claude-fable-5-1
This commit is contained in:
@@ -165,6 +165,11 @@ const CGFloat kScrollResistance = 10.0f;
|
||||
return [self gestureTypeForSetting:@"GestureTwoScroll"];
|
||||
}
|
||||
|
||||
/// A two finger swipe must be told apart from a two finger pan unless both scroll
|
||||
- (BOOL)isTwoFingerSwipeExclusive {
|
||||
return self.twoFingerScrollType != VMGestureTypeNone && self.twoFingerPanType != VMGestureTypeMouseWheel;
|
||||
}
|
||||
|
||||
- (VMGestureType)threeFingerPanType {
|
||||
return [self gestureTypeForSetting:@"GestureThreePan"];
|
||||
}
|
||||
@@ -499,10 +504,13 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
|
||||
- (IBAction)gestureSwipeScroll:(UISwipeGestureRecognizer *)sender {
|
||||
if (sender.state == UIGestureRecognizerStateEnded &&
|
||||
self.twoFingerScrollType == VMGestureTypeMouseWheel) {
|
||||
// same direction as the pan that may be scrolling along with the swipe
|
||||
CSInputScroll up = self.isInvertScroll ? kCSInputScrollDown : kCSInputScrollUp;
|
||||
CSInputScroll down = self.isInvertScroll ? kCSInputScrollUp : kCSInputScrollDown;
|
||||
if (sender == self.swipeScrollUp) {
|
||||
[self.vmInput sendMouseScroll:kCSInputScrollUp buttonMask:self.mouseButtonDown dy:0];
|
||||
[self.vmInput sendMouseScroll:up buttonMask:self.mouseButtonDown dy:0];
|
||||
} else if (sender == self.swipeScrollDown) {
|
||||
[self.vmInput sendMouseScroll:kCSInputScrollDown buttonMask:self.mouseButtonDown dy:0];
|
||||
[self.vmInput sendMouseScroll:down buttonMask:self.mouseButtonDown dy:0];
|
||||
} else {
|
||||
NSAssert(0, @"Invalid call to gestureSwipeScroll");
|
||||
}
|
||||
@@ -512,12 +520,6 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
|
||||
#pragma mark - UIGestureRecognizerDelegate
|
||||
|
||||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||||
if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeUp) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeDown) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.twoTap && otherGestureRecognizer == self.swipeDown) {
|
||||
return YES;
|
||||
}
|
||||
@@ -530,26 +532,14 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
|
||||
if (gestureRecognizer == self.tap && otherGestureRecognizer == self.longPress) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.pinch && otherGestureRecognizer == self.swipeDown) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.pinch && otherGestureRecognizer == self.swipeUp) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.pan && otherGestureRecognizer == self.swipeUp) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.pan && otherGestureRecognizer == self.swipeDown) {
|
||||
return YES;
|
||||
}
|
||||
// a swipe can take half a second to fail so a pan only waits for one that matches the same number of touches
|
||||
if (gestureRecognizer == self.threePan && otherGestureRecognizer == self.swipeUp) {
|
||||
return YES;
|
||||
}
|
||||
if (gestureRecognizer == self.threePan && otherGestureRecognizer == self.swipeDown) {
|
||||
return YES;
|
||||
}
|
||||
// only if we do not disable two finger swipe
|
||||
if (self.twoFingerScrollType != VMGestureTypeNone) {
|
||||
if (self.isTwoFingerSwipeExclusive) {
|
||||
if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeScrollUp) {
|
||||
return YES;
|
||||
}
|
||||
@@ -565,6 +555,10 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
|
||||
}
|
||||
|
||||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
|
||||
if (gestureRecognizer == self.pinch) {
|
||||
// before iOS 18 a pinch begins with two of three fingers and takes them from the three finger gestures
|
||||
return self.threePan.numberOfTouches < 3;
|
||||
}
|
||||
if (gestureRecognizer == self.longPress) {
|
||||
// otherwise a disabled long press would swallow the tap waiting on it
|
||||
return self.longPressType != VMGestureTypeNone;
|
||||
@@ -581,8 +575,7 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
|
||||
}
|
||||
} else if (gestureRecognizer == self.pan && otherGestureRecognizer == self.longPress) {
|
||||
return YES;
|
||||
} else if (self.twoFingerScrollType == VMGestureTypeNone && otherGestureRecognizer == self.twoPan) {
|
||||
// if two finger swipe is disabled, we can also recognize two finger pans
|
||||
} else if (!self.isTwoFingerSwipeExclusive && otherGestureRecognizer == self.twoPan) {
|
||||
if (gestureRecognizer == self.swipeScrollUp) {
|
||||
return YES;
|
||||
} else if (gestureRecognizer == self.swipeScrollDown) {
|
||||
|
||||
Reference in New Issue
Block a user