Skip to content

Commit

Permalink
REGRESSION (262853@main): [iOS] 2 fast/scrolling/ios/click-events-dur…
Browse files Browse the repository at this point in the history
…ing-momentum-scroll-* tests consistently failing

https://bugs.webkit.org/show_bug.cgi?id=255415
rdar://108011669

Reviewed by Tim Horton.

A couple of iOS layout tests began failing consistently after 262853@main; these two tests:

1. Scroll in a web page (either in the mainframe or an overflow scroller).
2. Tap the page while the scroll is decelerating.
3. Verify that the tap in step (2) did not trigger any click events.

While I'm only able to rarely reproduce this on device, it appears to readily reproduce when using
the simulator; I suspect this is because the touch point doesn't change at all when using the
trackpad or synthesizing taps in the simulator/testing environment, which causes the scroll view pan
gesture to never receive any touch moves.

We can fix this by only allowing simultaneous gesture recognition between the single tap and pan
gesture, in the case where the touch isn't interrupting scroll view deceleration.

* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKContentView _isInterruptingDecelerationForScrollViewOrAncestor:]):

Move this logic out of a local C++ lambda function inside of `-gestureRecognizerShouldBegin:`, and
into a separate helper method so that we can use it above as well, in
`-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:`.

(-[WKContentView gestureRecognizerShouldBegin:]):

Canonical link: https://commits.webkit.org/262963@main
  • Loading branch information
whsieh committed Apr 14, 2023
1 parent c22ea94 commit c3c2a30
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Expand Up @@ -2566,7 +2566,8 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
return ![self shouldDeferGestureDueToImageAnalysis:gestureRecognizer];
#endif

if (gestureRecognizer == _singleTapGestureRecognizer && [otherGestureRecognizer isKindOfClass:UIPanGestureRecognizer.class])
if (gestureRecognizer == _singleTapGestureRecognizer && [otherGestureRecognizer isKindOfClass:UIPanGestureRecognizer.class]
&& ![self _isInterruptingDecelerationForScrollViewOrAncestor:[_singleTapGestureRecognizer lastTouchedScrollView]])
return YES;

if (isSamePair(gestureRecognizer, otherGestureRecognizer, _highlightLongPressGestureRecognizer.get(), _longPressGestureRecognizer.get()))
Expand Down Expand Up @@ -2868,29 +2869,30 @@ - (BOOL)_shouldToggleSelectionCommandsAfterTapAt:(CGPoint)point
return pointIsInSelectionRect;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
- (BOOL)_isInterruptingDecelerationForScrollViewOrAncestor:(UIScrollView *)scrollView
{
CGPoint point = [gestureRecognizer locationInView:self];
UIScrollView *mainScroller = self.webView.scrollView;
UIView *view = scrollView ?: mainScroller;
while (view) {
if (dynamic_objc_cast<UIScrollView>(view)._isInterruptingDeceleration)
return YES;

auto isInterruptingDecelerationForScrollViewOrAncestor = [&] (UIScrollView *scrollView) {
UIScrollView *mainScroller = self.webView.scrollView;
UIView *view = scrollView ?: mainScroller;
while (view) {
if ([view isKindOfClass:UIScrollView.class] && [(UIScrollView *)view _isInterruptingDeceleration])
return YES;
if (mainScroller == view)
break;

if (mainScroller == view)
break;
view = view.superview;
}
return NO;
}

view = view.superview;
}
return NO;
};
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
CGPoint point = [gestureRecognizer locationInView:self];

if (gestureRecognizer == _singleTapGestureRecognizer) {
if ([self _shouldToggleSelectionCommandsAfterTapAt:point])
return NO;
return !isInterruptingDecelerationForScrollViewOrAncestor([_singleTapGestureRecognizer lastTouchedScrollView]);
return ![self _isInterruptingDecelerationForScrollViewOrAncestor:[_singleTapGestureRecognizer lastTouchedScrollView]];
}

if (gestureRecognizer == _doubleTapGestureRecognizerForDoubleClick) {
Expand Down Expand Up @@ -2919,7 +2921,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
}

if (gestureRecognizer == _highlightLongPressGestureRecognizer) {
if (isInterruptingDecelerationForScrollViewOrAncestor([_highlightLongPressGestureRecognizer lastTouchedScrollView]))
if ([self _isInterruptingDecelerationForScrollViewOrAncestor:[_highlightLongPressGestureRecognizer lastTouchedScrollView]])
return NO;

if (self._hasFocusedElement) {
Expand Down

0 comments on commit c3c2a30

Please sign in to comment.