Changeset 250315 in webkit


Ignore:
Timestamp:
Sep 24, 2019 1:06:48 PM (5 years ago)
Author:
Alan Bujtas
Message:

[iPadOs] The second click event is missing on double tap when dblclick handler is not present
https://bugs.webkit.org/show_bug.cgi?id=202006
<rdar://problem/51706828>

Reviewed by Wenson Hsieh.

Source/WebKit:

While double tapping,

  1. the first tap triggers a click event through the normal _singleTapIdentified/_singleTapRecognized codepath.
  2. and the second tap should trigger either a second single click event or a second single click followed by a dblclick event when dblclick handler is present.

However the second click is dropped on the floor when the node under the cursor does not have a dblclick handler (see handleDoubleTapForDoubleClickAtPoint()) -so we end up sending one click event.

This patch fixes this case by sending the second tap through the normal single tap flow when the dblclick handler is not present.

  • Shared/ios/InteractionInformationAtPosition.h:
  • Shared/ios/InteractionInformationAtPosition.mm:

(WebKit::InteractionInformationAtPosition::encode const):
(WebKit::InteractionInformationAtPosition::decode):

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

(-[WKContentView setupInteraction]):
(-[WKContentView gestureRecognizerShouldBegin:]):
(WebKit::WebPage::positionInformation):
(WebKit::WebPage::requestPositionInformation):

LayoutTests:

  • fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks1.html: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks2.html: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks3.html: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt: Added.
  • fast/events/touch/ios/double-tap-for-two-clicks4.html: Added.
  • fast/events/touch/ios/doubleclick.html: Added.
  • fast/events/touch/resources/doubleClickContent.html: Added.
Location:
trunk
Files:
9 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r250303 r250315  
     12019-09-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        [iPadOs] The second click event is missing on double tap when dblclick handler is not present
     4        https://bugs.webkit.org/show_bug.cgi?id=202006
     5        <rdar://problem/51706828>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * fast/events/touch/ios/double-tap-for-two-clicks1-expected.txt: Added.
     10        * fast/events/touch/ios/double-tap-for-two-clicks1.html: Added.
     11        * fast/events/touch/ios/double-tap-for-two-clicks2-expected.txt: Added.
     12        * fast/events/touch/ios/double-tap-for-two-clicks2.html: Added.
     13        * fast/events/touch/ios/double-tap-for-two-clicks3-expected.txt: Added.
     14        * fast/events/touch/ios/double-tap-for-two-clicks3.html: Added.
     15        * fast/events/touch/ios/double-tap-for-two-clicks4-expected.txt: Added.
     16        * fast/events/touch/ios/double-tap-for-two-clicks4.html: Added.
     17        * fast/events/touch/ios/doubleclick.html: Added.
     18        * fast/events/touch/resources/doubleClickContent.html: Added.
     19
    1202019-09-24  Antoine Quint  <graouts@apple.com>
    221
  • trunk/Source/WebKit/ChangeLog

    r250312 r250315  
     12019-09-24  Zalan Bujtas  <zalan@apple.com>
     2
     3        [iPadOs] The second click event is missing on double tap when dblclick handler is not present
     4        https://bugs.webkit.org/show_bug.cgi?id=202006
     5        <rdar://problem/51706828>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        While double tapping,
     10        1. the first tap triggers a click event through the normal _singleTapIdentified/_singleTapRecognized codepath.
     11        2. and the second tap should trigger either
     12          a second single click event or
     13          a second single click followed by a dblclick event when dblclick handler is present.
     14        However the second click is dropped on the floor when the node under the cursor does not have a dblclick handler (see handleDoubleTapForDoubleClickAtPoint()) -so we end up sending one click event.
     15
     16        This patch fixes this case by sending the second tap through the normal single tap flow when the dblclick handler is not present.
     17
     18        * Shared/ios/InteractionInformationAtPosition.h:
     19        * Shared/ios/InteractionInformationAtPosition.mm:
     20        (WebKit::InteractionInformationAtPosition::encode const):
     21        (WebKit::InteractionInformationAtPosition::decode):
     22        * UIProcess/ios/WKContentViewInteraction.h:
     23        * UIProcess/ios/WKContentViewInteraction.mm:
     24        (-[WKContentView setupInteraction]):
     25        (-[WKContentView gestureRecognizerShouldBegin:]):
     26        (WebKit::WebPage::positionInformation):
     27        (WebKit::WebPage::requestPositionInformation):
     28
    1292019-09-24  Alex Christensen  <achristensen@webkit.org>
    230
  • trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h

    r248447 r250315  
    5252    bool canBeValid { true };
    5353    bool nodeAtPositionIsFocusedElement { false };
     54    bool nodeAtPositionHasDoubleClickHandler { false };
    5455#if ENABLE(DATA_INTERACTION)
    5556    bool hasSelectionAtPosition { false };
  • trunk/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm

    r248447 r250315  
    4646    encoder << canBeValid;
    4747    encoder << nodeAtPositionIsFocusedElement;
     48    encoder << nodeAtPositionHasDoubleClickHandler;
    4849#if ENABLE(DATA_INTERACTION)
    4950    encoder << hasSelectionAtPosition;
     
    9899        return false;
    99100
     101    if (!decoder.decode(result.nodeAtPositionHasDoubleClickHandler))
     102        return false;
     103
    100104#if ENABLE(DATA_INTERACTION)
    101105    if (!decoder.decode(result.hasSelectionAtPosition))
  • trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.cpp

    r246757 r250315  
    5959}
    6060
    61 bool InteractionInformationRequest::isValidForRequest(const InteractionInformationRequest& other)
     61bool InteractionInformationRequest::isValidForRequest(const InteractionInformationRequest& other, int radius)
    6262{
    63     if (other.point != point)
    64         return false;
    65 
    6663    if (other.includeSnapshot && !includeSnapshot)
    6764        return false;
     
    7370        return false;
    7471
    75     return true;
     72    return (other.point - point).diagonalLengthSquared() <= radius * radius;
    7673}
    7774   
    78 bool InteractionInformationRequest::isApproximatelyValidForRequest(const InteractionInformationRequest& other)
     75bool InteractionInformationRequest::isApproximatelyValidForRequest(const InteractionInformationRequest& other, int radius)
    7976{
    80     if (other.includeSnapshot && !includeSnapshot)
    81         return false;
    82    
    83     if (other.includeLinkIndicator && !includeLinkIndicator)
    84         return false;
    85 
    86     if (other.linkIndicatorShouldHaveLegacyMargins != linkIndicatorShouldHaveLegacyMargins)
    87         return false;
    88    
    89     return (other.point - point).diagonalLengthSquared() <= 4;
     77    return isValidForRequest(other, radius);
    9078}
    9179
  • trunk/Source/WebKit/Shared/ios/InteractionInformationRequest.h

    r246757 r250315  
    5151    }
    5252
    53     bool isValidForRequest(const InteractionInformationRequest&);
    54     bool isApproximatelyValidForRequest(const InteractionInformationRequest& other);
     53    bool isValidForRequest(const InteractionInformationRequest&, int radius = 0);
     54    bool isApproximatelyValidForRequest(const InteractionInformationRequest&, int radius);
    5555
    5656    void encode(IPC::Encoder&) const;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r250256 r250315  
    21132113}
    21142114
    2115 - (BOOL)_currentPositionInformationIsApproximatelyValidForRequest:(const WebKit::InteractionInformationRequest&)request
    2116 {
    2117     return _hasValidPositionInformation && _positionInformation.request.isApproximatelyValidForRequest(request);
     2115- (BOOL)_currentPositionInformationIsApproximatelyValidForRequest:(const WebKit::InteractionInformationRequest&)request radiusForApproximation:(int)radius
     2116{
     2117    return _hasValidPositionInformation && _positionInformation.request.isApproximatelyValidForRequest(request, radius);
    21182118}
    21192119
     
    21922192        return !isInterruptingDecelerationForScrollViewOrAncestor([_singleTapGestureRecognizer lastTouchedScrollView]);
    21932193
     2194    if (gestureRecognizer == _doubleTapGestureRecognizerForDoubleClick) {
     2195        // Do not start the double-tap-for-double-click gesture recognizer unless we've got a dblclick event handler on the node at the tap location.
     2196        WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point));
     2197        if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:[_doubleTapGestureRecognizerForDoubleClick allowableMovement]])
     2198            return _positionInformation.nodeAtPositionHasDoubleClickHandler;
     2199        if (![self ensurePositionInformationIsUpToDate:request])
     2200            return NO;
     2201        return _positionInformation.nodeAtPositionHasDoubleClickHandler;
     2202    }
     2203
    21942204    if (gestureRecognizer == _highlightLongPressGestureRecognizer
    21952205        || gestureRecognizer == _doubleTapGestureRecognizer
    21962206        || gestureRecognizer == _nonBlockingDoubleTapGestureRecognizer
    2197         || gestureRecognizer == _doubleTapGestureRecognizerForDoubleClick
    21982207        || gestureRecognizer == _twoFingerDoubleTapGestureRecognizer) {
    21992208
     
    44724481    WebKit::InteractionInformationRequest request(WebCore::roundedIntPoint(point));
    44734482    [self requestAsynchronousPositionInformationUpdate:request];
    4474     if ([self _currentPositionInformationIsApproximatelyValidForRequest:request] && _positionInformation.isSelectable)
     4483    if ([self _currentPositionInformationIsApproximatelyValidForRequest:request radiusForApproximation:2] && _positionInformation.isSelectable)
    44754484        return [WKTextPosition textPositionWithRect:_positionInformation.caretRect];
    44764485#endif
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r250256 r250315  
    27682768
    27692769    FloatPoint adjustedPoint;
    2770     Node* hitNode = m_page->mainFrame().nodeRespondingToClickEvents(request.point, adjustedPoint);
    2771 
    2772     info.nodeAtPositionIsFocusedElement = hitNode == m_focusedElement;
     2770    auto* nodeRespondingToClickEvents = m_page->mainFrame().nodeRespondingToClickEvents(request.point, adjustedPoint);
     2771
     2772    info.nodeAtPositionIsFocusedElement = nodeRespondingToClickEvents == m_focusedElement;
    27732773    info.adjustedPointForNodeRespondingToClickEvents = adjustedPoint;
     2774    info.nodeAtPositionHasDoubleClickHandler = m_page->mainFrame().nodeRespondingToDoubleClickEvent(request.point, adjustedPoint);
    27742775
    27752776#if ENABLE(DATA_INTERACTION)
     
    27802781        focusedElementPositionInformation(*this, *m_focusedElement, request, info);
    27812782
    2782     if (is<Element>(hitNode)) {
    2783         Element& element = downcast<Element>(*hitNode);
     2783    if (is<Element>(nodeRespondingToClickEvents)) {
     2784        auto& element = downcast<Element>(*nodeRespondingToClickEvents);
    27842785        elementPositionInformation(*this, element, request, info);
    27852786
     
    27932794    // Prevent the callout bar from showing when tapping on the datalist button.
    27942795#if ENABLE(DATALIST_ELEMENT)
    2795     if (is<HTMLInputElement>(hitNode)) {
    2796         const HTMLInputElement& input = downcast<HTMLInputElement>(*hitNode);
    2797         textInteractionPositionInformation(*this, input, request, info);
    2798     }
     2796    if (is<HTMLInputElement>(nodeRespondingToClickEvents))
     2797        textInteractionPositionInformation(*this, downcast<HTMLInputElement>(*nodeRespondingToClickEvents), request, info);
    27992798#endif
    28002799
Note: See TracChangeset for help on using the changeset viewer.