Title: [196679] trunk/Source/WebKit2
Revision
196679
Author
[email protected]
Date
2016-02-16 19:27:05 -0800 (Tue, 16 Feb 2016)

Log Message

Allow double tap to zoom in fast-click pages
https://bugs.webkit.org/show_bug.cgi?id=154318
<rdar://problem/24223767>

Reviewed by Simon Fraser and Benjamin Poulain.

Most of the patch comes from Jon Lee.

Our fast-click algorithm exposed a number of cases where
people missed the double-tap-to-zoom behaviour. In particular,
when you double tap on a large body of text, typical in
blogs and articles.

This patch enhances the algorithm to have a parallel
double-tap gesture recognizer in the situations where
fast-click is enabled. This new gesture recongizer does
not cause the single tap to block for 350ms, so clicks
are still dispatched fast. If it fires, we already have
some information about whether we have a pending double
tap, based on the first tap.

* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary): Remove the optimization
that only told the content view to disable on pages that allowed double taps. We now allow
them even on fast click pages.

* UIProcess/ios/WKContentViewInteraction.h: Add the new UITapGestureRecognizer for double taps
in fast click pages. This is called nonBlockingDoubleTapGestureRecognizer because, unlike
the existing DoubleTapGestureRecognizer, this one does not force the singleTapRecognizer
to wait.
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]): Set up the new UITapGestureRecognizer.
(-[WKContentView cleanupInteraction]): And remove it when we're done.
(-[WKContentView _removeDefaultGestureRecognizers]): Ditto.
(-[WKContentView _addDefaultGestureRecognizers]):
(-[WKContentView _inspectorNodeSearchRecognized:]): Something happened, we are no longer in
a potential double tap situation.
(-[WKContentView _disableDoubleTapGesturesDuringTapIfNecessary:]): Remove the check
for potential tap in progress.
(-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKContentView gestureRecognizerShouldBegin:]):
(-[WKContentView _highlightLongPressRecognized:]): Again, something happened, so we are
no longer in a double tap situation.
(-[WKContentView _longPressRecognized:]): Ditto.
(-[WKContentView _singleTapRecognized:]): Ditto.
(-[WKContentView _doubleTapRecognized:]): Ditto.
(-[WKContentView _resetIsDoubleTapPending]):
(-[WKContentView _fastDoubleTapRecognized:]): We're now pending a double tap.
(-[WKContentView _twoFingerDoubleTapRecognized:]):
(-[WKContentView _didNotHandleTapAsClick:]): If we get here and we have a pending
double tap, then trigger a zoom operation.
(-[WKContentView _setDoubleTapGesturesEnabled:]):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (196678 => 196679)


--- trunk/Source/WebKit2/ChangeLog	2016-02-17 02:34:36 UTC (rev 196678)
+++ trunk/Source/WebKit2/ChangeLog	2016-02-17 03:27:05 UTC (rev 196679)
@@ -1,3 +1,58 @@
+2016-02-16  Dean Jackson  <[email protected]>
+
+        Allow double tap to zoom in fast-click pages
+        https://bugs.webkit.org/show_bug.cgi?id=154318
+        <rdar://problem/24223767>
+
+        Reviewed by Simon Fraser and Benjamin Poulain.
+        
+        Most of the patch comes from Jon Lee.
+
+        Our fast-click algorithm exposed a number of cases where
+        people missed the double-tap-to-zoom behaviour. In particular,
+        when you double tap on a large body of text, typical in
+        blogs and articles.
+
+        This patch enhances the algorithm to have a parallel
+        double-tap gesture recognizer in the situations where
+        fast-click is enabled. This new gesture recongizer does
+        not cause the single tap to block for 350ms, so clicks
+        are still dispatched fast. If it fires, we already have
+        some information about whether we have a pending double
+        tap, based on the first tap.
+
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary): Remove the optimization
+        that only told the content view to disable on pages that allowed double taps. We now allow
+        them even on fast click pages.
+
+        * UIProcess/ios/WKContentViewInteraction.h: Add the new UITapGestureRecognizer for double taps
+        in fast click pages. This is called nonBlockingDoubleTapGestureRecognizer because, unlike
+        the existing DoubleTapGestureRecognizer, this one does not force the singleTapRecognizer
+        to wait.
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView setupInteraction]): Set up the new UITapGestureRecognizer.
+        (-[WKContentView cleanupInteraction]): And remove it when we're done.
+        (-[WKContentView _removeDefaultGestureRecognizers]): Ditto.
+        (-[WKContentView _addDefaultGestureRecognizers]):
+        (-[WKContentView _inspectorNodeSearchRecognized:]): Something happened, we are no longer in
+        a potential double tap situation.
+        (-[WKContentView _disableDoubleTapGesturesDuringTapIfNecessary:]): Remove the check
+        for potential tap in progress.
+        (-[WKContentView gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
+        (-[WKContentView gestureRecognizerShouldBegin:]):
+        (-[WKContentView _highlightLongPressRecognized:]): Again, something happened, so we are
+        no longer in a double tap situation.
+        (-[WKContentView _longPressRecognized:]): Ditto.
+        (-[WKContentView _singleTapRecognized:]): Ditto.
+        (-[WKContentView _doubleTapRecognized:]): Ditto.
+        (-[WKContentView _resetIsDoubleTapPending]):
+        (-[WKContentView _fastDoubleTapRecognized:]): We're now pending a double tap.
+        (-[WKContentView _twoFingerDoubleTapRecognized:]):
+        (-[WKContentView _didNotHandleTapAsClick:]): If we get here and we have a pending
+        double tap, then trigger a zoom operation.
+        (-[WKContentView _setDoubleTapGesturesEnabled:]):
+
 2016-02-16  Alex Christensen  <[email protected]>
 
         CMake build fix.

Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (196678 => 196679)


--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm	2016-02-17 02:34:36 UTC (rev 196678)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm	2016-02-17 03:27:05 UTC (rev 196679)
@@ -261,9 +261,6 @@
 
 void PageClientImpl::disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
 {
-    if (!m_webView._allowsDoubleTapGestures)
-        return;
-
     [m_contentView _disableDoubleTapGesturesDuringTapIfNecessary:requestID];
 }
 

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (196678 => 196679)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2016-02-17 02:34:36 UTC (rev 196678)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2016-02-17 03:27:05 UTC (rev 196679)
@@ -102,6 +102,7 @@
     RetainPtr<_UIWebHighlightLongPressGestureRecognizer> _highlightLongPressGestureRecognizer;
     RetainPtr<UILongPressGestureRecognizer> _longPressGestureRecognizer;
     RetainPtr<UITapGestureRecognizer> _doubleTapGestureRecognizer;
+    RetainPtr<UITapGestureRecognizer> _nonBlockingDoubleTapGestureRecognizer;
     RetainPtr<UITapGestureRecognizer> _twoFingerDoubleTapGestureRecognizer;
     RetainPtr<WKInspectorNodeSearchGestureRecognizer> _inspectorNodeSearchGestureRecognizer;
 
@@ -154,6 +155,7 @@
     BOOL _hasValidPositionInformation;
     BOOL _isTapHighlightIDValid;
     BOOL _potentialTapInProgress;
+    BOOL _isDoubleTapPending;
     BOOL _highlightLongPressCanClick;
     BOOL _hasTapHighlightForPotentialTap;
     BOOL _selectionNeedsUpdate;

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (196678 => 196679)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2016-02-17 02:34:36 UTC (rev 196678)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2016-02-17 03:27:05 UTC (rev 196679)
@@ -461,6 +461,12 @@
     [_singleTapGestureRecognizer setResetTarget:self action:@selector(_singleTapDidReset:)];
     [self addGestureRecognizer:_singleTapGestureRecognizer.get()];
 
+    _nonBlockingDoubleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_nonBlockingDoubleTapRecognized:)]);
+    [_nonBlockingDoubleTapGestureRecognizer setNumberOfTapsRequired:2];
+    [_nonBlockingDoubleTapGestureRecognizer setDelegate:self];
+    [_nonBlockingDoubleTapGestureRecognizer setEnabled:NO];
+    [self addGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
+
     [self _createAndConfigureDoubleTapGestureRecognizer];
 
     _twoFingerDoubleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_twoFingerDoubleTapRecognized:)]);
@@ -494,6 +500,8 @@
     [_actionSheetAssistant setDelegate:self];
     _smartMagnificationController = std::make_unique<SmartMagnificationController>(self);
     _isExpectingFastSingleTapCommit = NO;
+    _potentialTapInProgress = NO;
+    _isDoubleTapPending = NO;
     _showDebugTapHighlightsForFastClicking = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitShowFastClickDebugTapHighlights"];
 }
 
@@ -532,6 +540,9 @@
     [_doubleTapGestureRecognizer setDelegate:nil];
     [self removeGestureRecognizer:_doubleTapGestureRecognizer.get()];
 
+    [_nonBlockingDoubleTapGestureRecognizer setDelegate:nil];
+    [self removeGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
+
     [_twoFingerDoubleTapGestureRecognizer setDelegate:nil];
     [self removeGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
 
@@ -559,6 +570,7 @@
     [self removeGestureRecognizer:_singleTapGestureRecognizer.get()];
     [self removeGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
     [self removeGestureRecognizer:_doubleTapGestureRecognizer.get()];
+    [self removeGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
     [self removeGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
 }
 
@@ -568,6 +580,7 @@
     [self addGestureRecognizer:_singleTapGestureRecognizer.get()];
     [self addGestureRecognizer:_highlightLongPressGestureRecognizer.get()];
     [self addGestureRecognizer:_doubleTapGestureRecognizer.get()];
+    [self addGestureRecognizer:_nonBlockingDoubleTapGestureRecognizer.get()];
     [self addGestureRecognizer:_twoFingerDoubleTapGestureRecognizer.get()];
 }
 
@@ -732,6 +745,7 @@
 - (void)_inspectorNodeSearchRecognized:(UIGestureRecognizer *)gestureRecognizer
 {
     ASSERT(_inspectorNodeSearchEnabled);
+    [self _resetIsDoubleTapPending];
 
     CGPoint point = [gestureRecognizer locationInView:self];
 
@@ -920,7 +934,7 @@
 
 - (void)_disableDoubleTapGesturesDuringTapIfNecessary:(uint64_t)requestID
 {
-    if (!_potentialTapInProgress || _latestTapID != requestID)
+    if (_latestTapID != requestID)
         return;
 
     [self _setDoubleTapGesturesEnabled:NO];
@@ -1049,6 +1063,12 @@
     if (isSamePair(gestureRecognizer, otherGestureRecognizer, _singleTapGestureRecognizer.get(), _textSelectionAssistant.get().singleTapGesture))
         return YES;
 
+    if (isSamePair(gestureRecognizer, otherGestureRecognizer, _singleTapGestureRecognizer.get(), _nonBlockingDoubleTapGestureRecognizer.get()))
+        return YES;
+
+    if (isSamePair(gestureRecognizer, otherGestureRecognizer, _highlightLongPressGestureRecognizer.get(), _nonBlockingDoubleTapGestureRecognizer.get()))
+        return YES;
+
     if (isSamePair(gestureRecognizer, otherGestureRecognizer, _highlightLongPressGestureRecognizer.get(), _previewSecondaryGestureRecognizer.get()))
         return YES;
 
@@ -1112,6 +1132,7 @@
 
     if (gestureRecognizer == _highlightLongPressGestureRecognizer
         || gestureRecognizer == _doubleTapGestureRecognizer
+        || gestureRecognizer == _nonBlockingDoubleTapGestureRecognizer
         || gestureRecognizer == _twoFingerDoubleTapGestureRecognizer
         || gestureRecognizer == _singleTapGestureRecognizer) {
 
@@ -1233,6 +1254,7 @@
 - (void)_highlightLongPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _highlightLongPressGestureRecognizer);
+    [self _resetIsDoubleTapPending];
 
     _lastInteractionLocation = gestureRecognizer.startPoint;
 
@@ -1263,6 +1285,7 @@
 - (void)_longPressRecognized:(UILongPressGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _longPressGestureRecognizer);
+    [self _resetIsDoubleTapPending];
 
     _lastInteractionLocation = gestureRecognizer.startPoint;
 
@@ -1287,6 +1310,7 @@
 {
     ASSERT(gestureRecognizer == _singleTapGestureRecognizer);
     ASSERT(!_potentialTapInProgress);
+    [self _resetIsDoubleTapPending];
 
     _page->potentialTapAtPosition(gestureRecognizer.location, ++_latestTapID);
     _potentialTapInProgress = YES;
@@ -1314,6 +1338,22 @@
     [self _cancelInteraction];
 }
 
+- (void)_didNotHandleTapAsClick:(const WebCore::IntPoint&)point
+{
+    // FIXME: we should also take into account whether or not the UI delegate
+    // has handled this notification.
+    if (_hasValidPositionInformation && point == _positionInformation.point && _positionInformation.isDataDetectorLink) {
+        [self _showDataDetectorsSheet];
+        return;
+    }
+
+    if (!_isDoubleTapPending)
+        return;
+
+    _smartMagnificationController->handleSmartMagnificationGesture(_lastInteractionLocation);
+    _isDoubleTapPending = NO;
+}
+
 - (void)_singleTapCommited:(UITapGestureRecognizer *)gestureRecognizer
 {
     ASSERT(gestureRecognizer == _singleTapGestureRecognizer);
@@ -1351,13 +1391,26 @@
 
 - (void)_doubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
 {
+    [self _resetIsDoubleTapPending];
     _lastInteractionLocation = gestureRecognizer.location;
 
     _smartMagnificationController->handleSmartMagnificationGesture(gestureRecognizer.location);
 }
 
+- (void)_resetIsDoubleTapPending
+{
+    _isDoubleTapPending = NO;
+}
+
+- (void)_nonBlockingDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
+{
+    _lastInteractionLocation = gestureRecognizer.location;
+    _isDoubleTapPending = YES;
+}
+
 - (void)_twoFingerDoubleTapRecognized:(UITapGestureRecognizer *)gestureRecognizer
 {
+    [self _resetIsDoubleTapPending];
     _lastInteractionLocation = gestureRecognizer.location;
 
     _smartMagnificationController->handleResetMagnificationGesture(gestureRecognizer.location);
@@ -1401,14 +1454,6 @@
     _page->clearSelection();
 }
 
-- (void)_didNotHandleTapAsClick:(const WebCore::IntPoint&)point
-{
-    // FIXME: we should also take into account whether or not the UI delegate
-    // has handled this notification.
-    if (_hasValidPositionInformation && point == _positionInformation.point && _positionInformation.isDataDetectorLink)
-        [self _showDataDetectorsSheet];
-}
-
 - (void)_positionInformationDidChange:(const InteractionInformationAtPosition&)info
 {
     _positionInformation = info;
@@ -2460,6 +2505,8 @@
         _tapHighlightInformation.color = [self _tapHighlightColorForFastClick:YES];
 
     [_doubleTapGestureRecognizer setEnabled:enabled];
+    [_nonBlockingDoubleTapGestureRecognizer setEnabled:!enabled];
+    [self _resetIsDoubleTapPending];
 }
 
 - (void)accessoryAutoFill
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to