Changeset 247197 in webkit


Ignore:
Timestamp:
Jul 7, 2019 1:12:54 AM (5 years ago)
Author:
graouts@webkit.org
Message:

[Pointer Events] Use a gesture recognizer to prevent pinch-to-zoom behavior
https://bugs.webkit.org/show_bug.cgi?id=199543

Reviewed by Dean Jackson.

We used to set the "enabled" property on the main UIScrollView's UIPinchGestureRecognizer to disable pinch-to-zoom
behavior based on the "touch-action" CSS property. This was sub-optimal since this gesture recognizer can be publicly
accessible by third-party developers, but also because it set state instead of a run-time solution.

We now introduce a new WKTouchActionGestureRecognizer dedicated to preventing clearly identified gesture recognizers
from being recognized to disable some built-in behavior. As a new touch starts, we record the computed touch-action
property for the given touch identifier on the WKTouchActionGestureRecognizer, then WKTouchActionGestureRecognizer
determines, by implementing -[canPreventGestureRecognizer:], whether the possibly-prevented gesture recognizer
is known to lead to a pinch-to-zoom behavior and whether it contains a touch that should prevent it.

To support the WKTouchActionGestureRecognizer, WKContentViewInteraction implements the new WKTouchActionGestureRecognizerDelegate
protocol to indicate whether the possibly-prevented gesture recognizer is the main UIScrollView's UIPinchGestureRecognizer.

No new test since this changes the implementation of existing behavior.

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

(-[WKContentView setupInteraction]):
(-[WKContentView cleanupInteraction]):
(-[WKContentView _removeDefaultGestureRecognizers]):
(-[WKContentView _addDefaultGestureRecognizers]):
(-[WKContentView _handleTouchActionsForTouchEvent:]):
(-[WKContentView gestureRecognizerMayPinchToZoomWebView:]):
(-[WKContentView touchActionActiveTouches]):

  • UIProcess/ios/WKTouchActionGestureRecognizer.h: Added.
  • UIProcess/ios/WKTouchActionGestureRecognizer.mm: Added.

(-[WKTouchActionGestureRecognizer initWithTouchActionDelegate:]):
(-[WKTouchActionGestureRecognizer setTouchActions:forTouchIdentifier:]):
(-[WKTouchActionGestureRecognizer clearTouchActionsForTouchIdentifier:]):
(-[WKTouchActionGestureRecognizer touchesBegan:withEvent:]):
(-[WKTouchActionGestureRecognizer touchesMoved:withEvent:]):
(-[WKTouchActionGestureRecognizer touchesEnded:withEvent:]):
(-[WKTouchActionGestureRecognizer touchesCancelled:withEvent:]):
(-[WKTouchActionGestureRecognizer _updateState]):
(-[WKTouchActionGestureRecognizer canBePreventedByGestureRecognizer:]):
(-[WKTouchActionGestureRecognizer canPreventGestureRecognizer:]):

  • WebKit.xcodeproj/project.pbxproj:
Location:
trunk/Source/WebKit
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r247192 r247197  
     12019-07-06  Antoine Quint  <graouts@apple.com>
     2
     3        [Pointer Events] Use a gesture recognizer to prevent pinch-to-zoom behavior
     4        https://bugs.webkit.org/show_bug.cgi?id=199543
     5
     6        Reviewed by Dean Jackson.
     7
     8        We used to set the "enabled" property on the main UIScrollView's UIPinchGestureRecognizer to disable pinch-to-zoom
     9        behavior based on the "touch-action" CSS property. This was sub-optimal since this gesture recognizer can be publicly
     10        accessible by third-party developers, but also because it set state instead of a run-time solution.
     11
     12        We now introduce a new WKTouchActionGestureRecognizer dedicated to preventing clearly identified gesture recognizers
     13        from being recognized to disable some built-in behavior. As a new touch starts, we record the computed touch-action
     14        property for the given touch identifier on the WKTouchActionGestureRecognizer, then WKTouchActionGestureRecognizer
     15        determines, by implementing -[canPreventGestureRecognizer:], whether the possibly-prevented gesture recognizer
     16        is known to lead to a pinch-to-zoom behavior and whether it contains a touch that should prevent it.
     17
     18        To support the WKTouchActionGestureRecognizer, WKContentViewInteraction implements the new WKTouchActionGestureRecognizerDelegate
     19        protocol to indicate whether the possibly-prevented gesture recognizer is the main UIScrollView's UIPinchGestureRecognizer.
     20
     21        No new test since this changes the implementation of existing behavior.
     22
     23        * SourcesCocoa.txt:
     24        * UIProcess/ios/WKContentViewInteraction.h:
     25        * UIProcess/ios/WKContentViewInteraction.mm:
     26        (-[WKContentView setupInteraction]):
     27        (-[WKContentView cleanupInteraction]):
     28        (-[WKContentView _removeDefaultGestureRecognizers]):
     29        (-[WKContentView _addDefaultGestureRecognizers]):
     30        (-[WKContentView _handleTouchActionsForTouchEvent:]):
     31        (-[WKContentView gestureRecognizerMayPinchToZoomWebView:]):
     32        (-[WKContentView touchActionActiveTouches]):
     33        * UIProcess/ios/WKTouchActionGestureRecognizer.h: Added.
     34        * UIProcess/ios/WKTouchActionGestureRecognizer.mm: Added.
     35        (-[WKTouchActionGestureRecognizer initWithTouchActionDelegate:]):
     36        (-[WKTouchActionGestureRecognizer setTouchActions:forTouchIdentifier:]):
     37        (-[WKTouchActionGestureRecognizer clearTouchActionsForTouchIdentifier:]):
     38        (-[WKTouchActionGestureRecognizer touchesBegan:withEvent:]):
     39        (-[WKTouchActionGestureRecognizer touchesMoved:withEvent:]):
     40        (-[WKTouchActionGestureRecognizer touchesEnded:withEvent:]):
     41        (-[WKTouchActionGestureRecognizer touchesCancelled:withEvent:]):
     42        (-[WKTouchActionGestureRecognizer _updateState]):
     43        (-[WKTouchActionGestureRecognizer canBePreventedByGestureRecognizer:]):
     44        (-[WKTouchActionGestureRecognizer canPreventGestureRecognizer:]):
     45        * WebKit.xcodeproj/project.pbxproj:
     46
    1472019-07-06  Chris Fleizach  <cfleizach@apple.com>
    248
  • trunk/Source/WebKit/SourcesCocoa.txt

    r246514 r247197  
    431431UIProcess/ios/WKSyntheticTapGestureRecognizer.m
    432432UIProcess/ios/WKSystemPreviewView.mm
     433UIProcess/ios/WKTouchActionGestureRecognizer.m
    433434UIProcess/ios/WKWebEvent.mm
    434435
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r246931 r247197  
    4747#import "WKShareSheet.h"
    4848#import "WKSyntheticTapGestureRecognizer.h"
     49#import "WKTouchActionGestureRecognizer.h"
    4950#import "_WKFormInputSession.h"
    5051#import <UIKit/UIView.h>
     
    221222    RetainPtr<WKInspectorNodeSearchGestureRecognizer> _inspectorNodeSearchGestureRecognizer;
    222223
     224#if ENABLE(POINTER_EVENTS)
     225    RetainPtr<WKTouchActionGestureRecognizer> _touchActionGestureRecognizer;
     226#endif
     227
    223228#if PLATFORM(MACCATALYST)
    224229    RetainPtr<UIHoverGestureRecognizer> _hoverGestureRecognizer;
     
    384389#if ENABLE(DATA_INTERACTION)
    385390    , UIDragInteractionDelegate, UIDropInteractionDelegate
     391#endif
     392#if PLATFORM(IOS_FAMILY) && ENABLE(POINTER_EVENTS)
     393    , WKTouchActionGestureRecognizerDelegate
    386394#endif
    387395>
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r247161 r247197  
    796796    [self addGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
    797797
     798#if ENABLE(POINTER_EVENTS)
     799    _touchActionGestureRecognizer = adoptNS([[WKTouchActionGestureRecognizer alloc] initWithTouchActionDelegate:self]);
     800    [self addGestureRecognizer:_touchActionGestureRecognizer.get()];
     801#endif
     802
    798803#if HAVE(LINK_PREVIEW)
    799804    [self _registerPreview];
     
    907912    [self removeGestureRecognizer:_stylusSingleTapGestureRecognizer.get()];
    908913
     914#if ENABLE(POINTER_EVENTS)
     915    [self removeGestureRecognizer:_touchActionGestureRecognizer.get()];
     916#endif
     917
    909918    _layerTreeTransactionIdAtLastTouchStart = 0;
    910919
     
    977986    [self removeGestureRecognizer:_lookupGestureRecognizer.get()];
    978987#endif
     988#if ENABLE(POINTER_EVENTS)
     989    [self removeGestureRecognizer:_touchActionGestureRecognizer.get()];
     990#endif
    979991}
    980992
     
    9931005    [self addGestureRecognizer:_lookupGestureRecognizer.get()];
    9941006#endif
     1007#if ENABLE(POINTER_EVENTS)
     1008    [self addGestureRecognizer:_touchActionGestureRecognizer.get()];
     1009#endif
    9951010}
    9961011
     
    13631378            auto touchActions = WebKit::touchActionsForPoint(self, touchPoint.location());
    13641379            LOG_WITH_STREAM(UIHitTesting, stream << "touchActionsForPoint " << touchPoint.location() << " found " << touchActions);
    1365             if (!touchActions || touchActions.containsAny({ WebCore::TouchAction::Auto, WebCore::TouchAction::Manipulation }))
     1380            if (!touchActions || touchActions.contains(WebCore::TouchAction::Auto))
    13661381                continue;
    1367 
     1382            [_touchActionGestureRecognizer setTouchActions:touchActions forTouchIdentifier:touchPoint.identifier()];
    13681383            scrollingCoordinator->setTouchActionsForTouchIdentifier(touchActions, touchPoint.identifier());
    1369 
    1370             if (!touchActions.contains(WebCore::TouchAction::PinchZoom))
    1371                 _webView.scrollView.pinchGestureRecognizer.enabled = NO;
    1372             _preventsPanningInXAxis = !touchActions.contains(WebCore::TouchAction::PanX);
    1373             _preventsPanningInYAxis = !touchActions.contains(WebCore::TouchAction::PanY);
    1374 
    1375         } else if (phase == WebKit::WebPlatformTouchPoint::TouchReleased || phase == WebKit::WebPlatformTouchPoint::TouchCancelled)
     1384            _preventsPanningInXAxis = !touchActions.containsAny({ WebCore::TouchAction::PanX, WebCore::TouchAction::Manipulation });
     1385            _preventsPanningInYAxis = !touchActions.containsAny({ WebCore::TouchAction::PanY, WebCore::TouchAction::Manipulation });
     1386        } else if (phase == WebKit::WebPlatformTouchPoint::TouchReleased || phase == WebKit::WebPlatformTouchPoint::TouchCancelled) {
     1387            [_touchActionGestureRecognizer clearTouchActionsForTouchIdentifier:touchPoint.identifier()];
    13761388            scrollingCoordinator->clearTouchActionsForTouchIdentifier(touchPoint.identifier());
    1377     }
     1389        }
     1390    }
     1391}
     1392#endif
     1393
     1394#pragma mark - WKTouchActionGestureRecognizerDelegate implementation
     1395
     1396- (BOOL)gestureRecognizerMayPinchToZoomWebView:(UIGestureRecognizer *)gestureRecognizer
     1397{
     1398    // The gesture recognizer is the main UIScrollView's UIPinchGestureRecognizer.
     1399    return gestureRecognizer == [_webView scrollView].pinchGestureRecognizer;
     1400}
     1401
     1402#if HAVE(UI_WEB_TOUCH_EVENTS_GESTURE_RECOGNIZER_WITH_ACTIVE_TOUCHES_BY_ID)
     1403- (NSMapTable<NSNumber *, UITouch *> *)touchActionActiveTouches
     1404{
     1405    return [_touchEventGestureRecognizer activeTouchesByIdentifier];
    13781406}
    13791407#endif
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r247146 r247197  
    11401140                6EE849C81368D9390038D481 /* WKInspectorPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE849C61368D92D0038D481 /* WKInspectorPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
    11411141                711725A9228D564300018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 711725A8228D563A00018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h */; };
     1142                71A676A622C62325007D6295 /* WKTouchActionGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */; };
     1143                71A676A722C6232F007D6295 /* WKTouchActionGestureRecognizer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 71A676A522C62318007D6295 /* WKTouchActionGestureRecognizer.mm */; };
    11421144                71FB810B2260627E00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 71FB810A2260627A00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h */; };
    11431145                728E86F11795188C0087879E /* WebColorPickerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 728E86EF1795188C0087879E /* WebColorPickerMac.h */; };
     
    36613663                6EE849C61368D92D0038D481 /* WKInspectorPrivateMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKInspectorPrivateMac.h; path = mac/WKInspectorPrivateMac.h; sourceTree = "<group>"; };
    36623664                711725A8228D563A00018514 /* WebsiteLegacyOverflowScrollingTouchPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebsiteLegacyOverflowScrollingTouchPolicy.h; sourceTree = "<group>"; };
     3665                71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKTouchActionGestureRecognizer.h; path = ios/WKTouchActionGestureRecognizer.h; sourceTree = "<group>"; };
     3666                71A676A522C62318007D6295 /* WKTouchActionGestureRecognizer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKTouchActionGestureRecognizer.mm; path = ios/WKTouchActionGestureRecognizer.mm; sourceTree = "<group>"; };
    36633667                71FB810A2260627A00323677 /* WebsiteSimulatedMouseEventsDispatchPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebsiteSimulatedMouseEventsDispatchPolicy.h; sourceTree = "<group>"; };
    36643668                728E86EF1795188C0087879E /* WebColorPickerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebColorPickerMac.h; sourceTree = "<group>"; };
     
    60626066                                316B8B622054B55800BD4A62 /* WKSystemPreviewView.h */,
    60636067                                316B8B612054B55800BD4A62 /* WKSystemPreviewView.mm */,
     6068                                71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */,
     6069                                71A676A522C62318007D6295 /* WKTouchActionGestureRecognizer.mm */,
    60646070                                2D1E8221216FFF5000A15265 /* WKWebEvent.h */,
    60656071                                2D1E8222216FFF5100A15265 /* WKWebEvent.mm */,
     
    1022810234                                0FCB4E6818BBE3D9000FCFC9 /* WKTextInputWindowController.h in Headers */,
    1022910235                                2EB6FC01203021960017E619 /* WKTimePickerViewController.h in Headers */,
     10236                                71A676A622C62325007D6295 /* WKTouchActionGestureRecognizer.h in Headers */,
    1023010237                                BC407608124FF0270068F20A /* WKType.h in Headers */,
    1023110238                                7CD5EBBF1746B04C000C1C45 /* WKTypeRefWrapper.h in Headers */,
     
    1144811455                                7A78FF332241919B0096483E /* WKStorageAccessAlert.mm in Sources */,
    1144911456                                26F10BE919187E2E001D0E68 /* WKSyntheticTapGestureRecognizer.m in Sources */,
     11457                                71A676A722C6232F007D6295 /* WKTouchActionGestureRecognizer.mm in Sources */,
    1145011458                        );
    1145111459                        runOnlyForDeploymentPostprocessing = 0;
Note: See TracChangeset for help on using the changeset viewer.