display(iOS): recognize long press without waiting for tap

The long press recognizer required the tap recognizers to fail first. A
tap only fails once the finger has been held for well over a second, so
a normal long press was delivered as a tap when the finger lifted: the
"Right Click" action produced a left click (or nothing in touch mode)
and "Click & Hold" never pressed the button.

Reverse the dependency so the tap waits for the long press, which fails
as soon as a short touch ends and so adds no delay to taps. When the
long press action is disabled the recognizer is not allowed to begin,
otherwise holding before lifting would no longer click.

Reworked from #7697.

Assisted-by: Claude:claude-fable-5-1
This commit is contained in:
osy
2026-09-20 04:29:46 -05:00
parent 9d00a54833
commit 8304154849
@@ -527,10 +527,7 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
if (gestureRecognizer == self.tap && otherGestureRecognizer == self.twoTap) {
return YES;
}
if (gestureRecognizer == self.longPress && otherGestureRecognizer == self.tap) {
return YES;
}
if (gestureRecognizer == self.longPress && otherGestureRecognizer == self.twoTap) {
if (gestureRecognizer == self.tap && otherGestureRecognizer == self.longPress) {
return YES;
}
if (gestureRecognizer == self.pinch && otherGestureRecognizer == self.swipeDown) {
@@ -567,6 +564,14 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
#endif
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.longPress) {
// otherwise a disabled long press would swallow the tap waiting on it
return self.longPressType != VMGestureTypeNone;
}
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.pinch) {
if (self.twoFingerPanType == VMGestureTypeMoveScreen) {