⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 271193 in webkit


Ignore:
Timestamp:
Jan 5, 2021, 9:59:24 PM (6 years ago)
Author:
Wenson Hsieh
Message:

Refactor some logic around touch event deferring gesture recognizers
https://bugs.webkit.org/show_bug.cgi?id=220345

Reviewed by Tim Horton.

Rename _deferringGestureRecognizerForFoo to _touchStartDeferringGestureRecognizerForFoo, to make it clear
that these deferring gestures are only intended to defer native gestures until the "touchstart" event has been
handled.

This distinction becomes important once I introduce deferring gesture recognizers that defer the "touchend"
event, and prevent gestures that activate upon touch end (i.e. various types of tap gesture recognizers).

See below for more details.

  • UIProcess/PageClient.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::handlePreventableTouchEvent):

  • UIProcess/ios/PageClientImplIOS.h:
  • UIProcess/ios/PageClientImplIOS.mm:

(WebKit::PageClientImpl::doneDeferringTouchStart):
(WebKit::PageClientImpl::doneDeferringNativeGestures): Deleted.

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView setUpInteraction]):
(-[WKContentView cleanUpInteraction]):
(-[WKContentView _removeDefaultGestureRecognizers]):
(-[WKContentView _addDefaultGestureRecognizers]):
(-[WKContentView _webTouchEventsRecognized:]):
(-[WKContentView _touchStartDeferringGestures]):
(-[WKContentView _doneDeferringTouchStart:]):
(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
(-[WKContentView _deferringGestureRecognizers]): Deleted.
(-[WKContentView _doneDeferringNativeGestures:]): Deleted.

Rename this to -_doneDeferringTouchStart:.

(-[WKContentView deferringGestureRecognizer:shouldDeferGesturesAfterEndingTouchesWithEvent:]):

Deleted. This logic has been moved to WKContentView (see below).

  • UIProcess/ios/WKDeferringGestureRecognizer.h:
  • UIProcess/ios/WKDeferringGestureRecognizer.mm:

(-[WKDeferringGestureRecognizer touchesEnded:withEvent:]): Deleted.

Additionally refactor this code so that this fallback logic for lifting the gesture gate exists inside
WKContentView (after ending all touches), rather than inside the deferring gesture recognizer. While this
doesn't affect the extant touch start deferring gestures, it will ensure that touch end deferring gestures won't
get reset prematurely due to the web touch events gesture recognizer ending before the touch end deferring
gesture.

Location:
trunk/Source/WebKit
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r271192 r271193  
     12021-01-05  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Refactor some logic around touch event deferring gesture recognizers
     4        https://bugs.webkit.org/show_bug.cgi?id=220345
     5
     6        Reviewed by Tim Horton.
     7
     8        Rename `_deferringGestureRecognizerForFoo` to `_touchStartDeferringGestureRecognizerForFoo`, to make it clear
     9        that these deferring gestures are only intended to defer native gestures until the "touchstart" event has been
     10        handled.
     11
     12        This distinction becomes important once I introduce deferring gesture recognizers that defer the "touchend"
     13        event, and prevent gestures that activate upon touch end (i.e. various types of tap gesture recognizers).
     14
     15        See below for more details.
     16
     17        * UIProcess/PageClient.h:
     18        * UIProcess/WebPageProxy.cpp:
     19        (WebKit::WebPageProxy::handlePreventableTouchEvent):
     20        * UIProcess/ios/PageClientImplIOS.h:
     21        * UIProcess/ios/PageClientImplIOS.mm:
     22        (WebKit::PageClientImpl::doneDeferringTouchStart):
     23        (WebKit::PageClientImpl::doneDeferringNativeGestures): Deleted.
     24        * UIProcess/ios/WKContentViewInteraction.h:
     25        * UIProcess/ios/WKContentViewInteraction.mm:
     26        (-[WKContentView setUpInteraction]):
     27        (-[WKContentView cleanUpInteraction]):
     28        (-[WKContentView _removeDefaultGestureRecognizers]):
     29        (-[WKContentView _addDefaultGestureRecognizers]):
     30        (-[WKContentView _webTouchEventsRecognized:]):
     31        (-[WKContentView _touchStartDeferringGestures]):
     32        (-[WKContentView _doneDeferringTouchStart:]):
     33        (-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
     34        (-[WKContentView deferringGestureRecognizer:shouldDeferOtherGestureRecognizer:]):
     35        (-[WKContentView _deferringGestureRecognizers]): Deleted.
     36        (-[WKContentView _doneDeferringNativeGestures:]): Deleted.
     37
     38        Rename this to `-_doneDeferringTouchStart:`.
     39
     40        (-[WKContentView deferringGestureRecognizer:shouldDeferGesturesAfterEndingTouchesWithEvent:]):
     41
     42        Deleted. This logic has been moved to WKContentView (see below).
     43
     44        * UIProcess/ios/WKDeferringGestureRecognizer.h:
     45        * UIProcess/ios/WKDeferringGestureRecognizer.mm:
     46        (-[WKDeferringGestureRecognizer touchesEnded:withEvent:]): Deleted.
     47
     48        Additionally refactor this code so that this fallback logic for lifting the gesture gate exists inside
     49        `WKContentView` (after ending all touches), rather than inside the deferring gesture recognizer. While this
     50        doesn't affect the extant touch start deferring gestures, it will ensure that touch end deferring gestures won't
     51        get reset prematurely due to the web touch events gesture recognizer ending before the touch end deferring
     52        gesture.
     53
    1542021-01-05  Kate Cheney  <katherine_cheney@apple.com>
    255
  • trunk/Source/WebKit/UIProcess/PageClient.h

    r270712 r271193  
    340340#endif
    341341#if ENABLE(IOS_TOUCH_EVENTS)
    342     virtual void doneDeferringNativeGestures(bool preventNativeGestures) = 0;
     342    virtual void doneDeferringTouchStart(bool preventNativeGestures) = 0;
    343343#endif
    344344
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r271174 r271193  
    28922892    if (touchEventsTrackingType == TrackingType::NotTracking) {
    28932893        if (!isHandlingPreventableTouchStart())
    2894             pageClient().doneDeferringNativeGestures(false);
     2894            pageClient().doneDeferringTouchStart(false);
    28952895        return;
    28962896    }
     
    29072907        didReceiveEvent(event.type(), false);
    29082908        if (!isHandlingPreventableTouchStart())
    2909             pageClient().doneDeferringNativeGestures(false);
     2909            pageClient().doneDeferringTouchStart(false);
    29102910        return;
    29112911    }
     
    29142914        ++m_handlingPreventableTouchStartCount;
    29152915        Function<void(bool, CallbackBase::Error)> completionHandler = [this, protectedThis = makeRef(*this), event](bool handled, CallbackBase::Error error) {
    2916             ASSERT(m_handlingPreventableTouchStartCount);
    2917             if (m_handlingPreventableTouchStartCount)
    2918                 --m_handlingPreventableTouchStartCount;
     2916            bool didFinishDeferringTouchStart = false;
     2917            ASSERT_IMPLIES(event.type() == WebEvent::TouchStart, m_handlingPreventableTouchStartCount);
     2918            if (event.type() == WebEvent::TouchStart && m_handlingPreventableTouchStartCount)
     2919                didFinishDeferringTouchStart = !--m_handlingPreventableTouchStartCount;
    29192920
    29202921            bool handledOrFailedWithError = handled || error != CallbackBase::Error::None || m_handledSynchronousTouchEventWhileDispatchingPreventableTouchStart;
     
    29272928            didReceiveEvent(event.type(), handledOrFailedWithError);
    29282929            pageClient().doneWithTouchEvent(event, handledOrFailedWithError);
    2929             if (!isHandlingPreventableTouchStart())
    2930                 pageClient().doneDeferringNativeGestures(handledOrFailedWithError);
     2930
     2931            if (didFinishDeferringTouchStart)
     2932                pageClient().doneDeferringTouchStart(handledOrFailedWithError);
    29312933        };
    29322934
     
    29452947    pageClient().doneWithTouchEvent(event, handled);
    29462948    if (!isHandlingPreventableTouchStart())
    2947         pageClient().doneDeferringNativeGestures(handled);
     2949        pageClient().doneDeferringTouchStart(handled);
    29482950    else if (handled)
    29492951        m_handledSynchronousTouchEventWhileDispatchingPreventableTouchStart = true;
  • trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h

    r270712 r271193  
    113113#endif
    114114#if ENABLE(IOS_TOUCH_EVENTS)
    115     void doneDeferringNativeGestures(bool preventNativeGestures) override;
     115    void doneDeferringTouchStart(bool preventNativeGestures) override;
    116116#endif
    117117    RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override;
  • trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm

    r270712 r271193  
    448448#if ENABLE(IOS_TOUCH_EVENTS)
    449449
    450 void PageClientImpl::doneDeferringNativeGestures(bool preventNativeGestures)
    451 {
    452     [m_contentView _doneDeferringNativeGestures:preventNativeGestures];
     450void PageClientImpl::doneDeferringTouchStart(bool preventNativeGestures)
     451{
     452    [m_contentView _doneDeferringTouchStart:preventNativeGestures];
    453453}
    454454
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r270901 r271193  
    243243@interface WKContentView () {
    244244#if ENABLE(IOS_TOUCH_EVENTS)
    245     RetainPtr<WKDeferringGestureRecognizer> _deferringGestureRecognizerForImmediatelyResettableGestures;
    246     RetainPtr<WKDeferringGestureRecognizer> _deferringGestureRecognizerForDelayedResettableGestures;
    247     RetainPtr<WKDeferringGestureRecognizer> _deferringGestureRecognizerForSyntheticTapGestures;
     245    RetainPtr<WKDeferringGestureRecognizer> _touchStartDeferringGestureRecognizerForImmediatelyResettableGestures;
     246    RetainPtr<WKDeferringGestureRecognizer> _touchStartDeferringGestureRecognizerForDelayedResettableGestures;
     247    RetainPtr<WKDeferringGestureRecognizer> _touchStartDeferringGestureRecognizerForSyntheticTapGestures;
    248248#endif
    249249    RetainPtr<UIWebTouchEventsGestureRecognizer> _touchEventGestureRecognizer;
     
    540540#endif
    541541#if ENABLE(IOS_TOUCH_EVENTS)
    542 - (void)_doneDeferringNativeGestures:(BOOL)preventNativeGestures;
     542- (void)_doneDeferringTouchStart:(BOOL)preventNativeGestures;
    543543#endif
    544544- (void)_commitPotentialTapFailed;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r271149 r271193  
    765765
    766766#if ENABLE(IOS_TOUCH_EVENTS)
    767     _deferringGestureRecognizerForImmediatelyResettableGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
    768     [_deferringGestureRecognizerForImmediatelyResettableGestures setName:@"Touch event deferrer (immediate reset)"];
    769 
    770     _deferringGestureRecognizerForDelayedResettableGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
    771     [_deferringGestureRecognizerForDelayedResettableGestures setName:@"Touch event deferrer (delayed reset)"];
    772 
    773     _deferringGestureRecognizerForSyntheticTapGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
    774     [_deferringGestureRecognizerForSyntheticTapGestures setName:@"Touch event deferrer (synthetic tap)"];
    775 
    776     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers) {
     767    _touchStartDeferringGestureRecognizerForImmediatelyResettableGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
     768    [_touchStartDeferringGestureRecognizerForImmediatelyResettableGestures setName:@"Touch start deferrer (immediate reset)"];
     769
     770    _touchStartDeferringGestureRecognizerForDelayedResettableGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
     771    [_touchStartDeferringGestureRecognizerForDelayedResettableGestures setName:@"Touch start deferrer (delayed reset)"];
     772
     773    _touchStartDeferringGestureRecognizerForSyntheticTapGestures = adoptNS([[WKDeferringGestureRecognizer alloc] initWithDeferringGestureDelegate:self]);
     774    [_touchStartDeferringGestureRecognizerForSyntheticTapGestures setName:@"Touch start deferrer (synthetic tap)"];
     775
     776    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures) {
    777777        gesture.delegate = self;
    778778        [self addGestureRecognizer:gesture];
    779779    }
    780 #endif
     780#endif // ENABLE(IOS_TOUCH_EVENTS)
    781781
    782782    _touchEventGestureRecognizer = adoptNS([[UIWebTouchEventsGestureRecognizer alloc] initWithTarget:self action:@selector(_webTouchEventsRecognized:) touchDelegate:self]);
     
    954954
    955955#if ENABLE(IOS_TOUCH_EVENTS)
    956     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers) {
     956    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures) {
    957957        gesture.delegate = nil;
    958958        [self removeGestureRecognizer:gesture];
     
    10851085{
    10861086#if ENABLE(IOS_TOUCH_EVENTS)
    1087     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers)
     1087    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures)
    10881088        [self removeGestureRecognizer:gesture];
    10891089#endif
     
    11121112{
    11131113#if ENABLE(IOS_TOUCH_EVENTS)
    1114     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers)
     1114    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures)
    11151115        [self addGestureRecognizer:gesture];
    11161116#endif
     
    15491549        if (nativeWebTouchEvent.isPotentialTap() && self.hasHiddenContentEditable && self._hasFocusedElement && !self.window.keyWindow)
    15501550            [self.window makeKeyWindow];
    1551     }
    1552 #endif
     1551
     1552#if ENABLE(IOS_TOUCH_EVENTS)
     1553        if (!_page->isHandlingPreventableTouchStart()) {
     1554            for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures) {
     1555                if (gesture.state == UIGestureRecognizerStatePossible)
     1556                    gesture.state = UIGestureRecognizerStateFailed;
     1557            }
     1558        }
     1559#endif // ENABLE(IOS_TOUCH_EVENTS)
     1560    }
     1561#endif // ENABLE(TOUCH_EVENTS)
    15531562}
    15541563
     
    17281737#if ENABLE(IOS_TOUCH_EVENTS)
    17291738
    1730 - (NSArray<WKDeferringGestureRecognizer *> *)_deferringGestureRecognizers
     1739- (NSArray<WKDeferringGestureRecognizer *> *)_touchStartDeferringGestures
    17311740{
    17321741    WKDeferringGestureRecognizer *recognizers[3];
     
    17361745            recognizers[count++] = recognizer.get();
    17371746    };
    1738     add(_deferringGestureRecognizerForImmediatelyResettableGestures);
    1739     add(_deferringGestureRecognizerForDelayedResettableGestures);
    1740     add(_deferringGestureRecognizerForSyntheticTapGestures);
     1747    add(_touchStartDeferringGestureRecognizerForImmediatelyResettableGestures);
     1748    add(_touchStartDeferringGestureRecognizerForDelayedResettableGestures);
     1749    add(_touchStartDeferringGestureRecognizerForSyntheticTapGestures);
    17411750    return [NSArray arrayWithObjects:recognizers count:count];
    17421751}
    17431752
    1744 - (void)_doneDeferringNativeGestures:(BOOL)preventNativeGestures
    1745 {
    1746     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers)
     1753- (void)_doneDeferringTouchStart:(BOOL)preventNativeGestures
     1754{
     1755    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures)
    17471756        [gesture setDefaultPrevented:preventNativeGestures];
    17481757}
     
    21292138{
    21302139#if ENABLE(IOS_TOUCH_EVENTS)
    2131     for (WKDeferringGestureRecognizer *gesture in self._deferringGestureRecognizers) {
     2140    for (WKDeferringGestureRecognizer *gesture in self._touchStartDeferringGestures) {
    21322141        if (isSamePair(gestureRecognizer, otherGestureRecognizer, _touchEventGestureRecognizer.get(), gesture))
    21332142            return YES;
     
    73027311}
    73037312
    7304 - (BOOL)deferringGestureRecognizer:(WKDeferringGestureRecognizer *)deferringGestureRecognizer shouldDeferGesturesAfterEndingTouchesWithEvent:(UIEvent *)event
    7305 {
    7306     return _page->isHandlingPreventableTouchStart();
    7307 }
    7308 
    73097313- (BOOL)deferringGestureRecognizer:(WKDeferringGestureRecognizer *)deferringGestureRecognizer shouldDeferOtherGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
    73107314{
     
    73587362    };
    73597363
    7360     if (gestureRecognizer == _doubleTapGestureRecognizer || gestureRecognizer == _singleTapGestureRecognizer)
    7361         return deferringGestureRecognizer == _deferringGestureRecognizerForSyntheticTapGestures;
     7364    if ([gestureRecognizer isKindOfClass:WKSyntheticTapGestureRecognizer.class])
     7365        return deferringGestureRecognizer == _touchStartDeferringGestureRecognizerForSyntheticTapGestures;
    73627366
    73637367    if (mayDelayResetOfContainingSubgraph(gestureRecognizer))
    7364         return deferringGestureRecognizer == _deferringGestureRecognizerForDelayedResettableGestures;
    7365 
    7366     return deferringGestureRecognizer == _deferringGestureRecognizerForImmediatelyResettableGestures;
     7368        return deferringGestureRecognizer == _touchStartDeferringGestureRecognizerForDelayedResettableGestures;
     7369
     7370    return deferringGestureRecognizer == _touchStartDeferringGestureRecognizerForImmediatelyResettableGestures;
    73677371#else
    73687372    UNUSED_PARAM(deferringGestureRecognizer);
  • trunk/Source/WebKit/UIProcess/ios/WKDeferringGestureRecognizer.h

    r260366 r271193  
    3131
    3232@protocol WKDeferringGestureRecognizerDelegate
    33 - (BOOL)deferringGestureRecognizer:(WKDeferringGestureRecognizer *)deferringGestureRecognizer shouldDeferGesturesAfterEndingTouchesWithEvent:(UIEvent *)event;
    3433- (BOOL)deferringGestureRecognizer:(WKDeferringGestureRecognizer *)deferringGestureRecognizer shouldDeferGesturesAfterBeginningTouchesWithEvent:(UIEvent *)event;
    3534- (BOOL)deferringGestureRecognizer:(WKDeferringGestureRecognizer *)deferringGestureRecognizer shouldDeferOtherGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer;
  • trunk/Source/WebKit/UIProcess/ios/WKDeferringGestureRecognizer.mm

    r253267 r271193  
    5656}
    5757
    58 - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    59 {
    60     [super touchesEnded:touches withEvent:event];
    61 
    62     if (self.state != UIGestureRecognizerStatePossible)
    63         return;
    64 
    65     if ([_deferringGestureDelegate deferringGestureRecognizer:self shouldDeferGesturesAfterEndingTouchesWithEvent:event])
    66         return;
    67 
    68     self.state = UIGestureRecognizerStateFailed;
    69 }
    70 
    7158- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    7259{
Note: See TracChangeset for help on using the changeset viewer.