Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: e8b8f75b41b3d873fb5aadda2df4da3f1d744f8d
      
https://github.com/WebKit/WebKit/commit/e8b8f75b41b3d873fb5aadda2df4da3f1d744f8d
  Author: Wenson Hsieh <wenson_hs...@apple.com>
  Date:   2023-11-27 (Mon, 27 Nov 2023)

  Changed paths:
    M Source/WebKit/SourcesCocoa.txt
    M Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h
    M Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm
    M Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h
    M 
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm
    A Source/WebKit/UIProcess/ios/WKAxisLockingScrollView.h
    A Source/WebKit/UIProcess/ios/WKAxisLockingScrollView.mm
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
    M Source/WebKit/UIProcess/ios/WKVelocityTrackingScrollView.h
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj

  Log Message:
  -----------
  Stop using SPI: 
-_scrollView:adjustedOffsetForOffset:translation:startPoint:horizontalVelocity:verticalVelocity:
https://bugs.webkit.org/show_bug.cgi?id=265215
rdar://118696702

Reviewed by Megan Gardner.

Move off of the private `UIScrollViewDelegate` method 
`-_scrollView:adjustedOffsetForOffset:…:`,
which allows clients to retarget the would-be target content offset right 
before a pan gesture (or
pan-gesture-induced momentum scrolling). We currently use this to implement 
`touch-action: pan-x|y`
by retargeting the content offset such that the `x` or `y` offsets are locked 
to their initial
values at the start of scrolling, which has the effect of locking 
pan-gesture-based scrolling to a
single axis.

To achieve the same effect without adopting any scroll view SPI, we can instead 
create and deploy a
new scroll view subclass, `WKAxisLockingScrollView`, which allows clients, in 
the form of a
`WKAxisLockingScrollViewDelegate`, to choose which axis to prevent scrolling 
during a pan gesture by
returning `UIAxisHorizontal` and/or `UIAxisVertical` in a new internal delegate 
method. For example,
we return `UIAxisVertical` to prevent scrolling in the y-axis, when `pan-x` is 
specified (and vice-
versa for `pan-y`).

To implement this subclass, we:

1.  Add our own pan gesture recognizer (the "axis locking pan gesture") to the 
scroll view, right as
    UIKit is about to add the built-in `UIScrollViewPanGestureRecognizer`. The 
order in which these
    two gestures are added to the scroll view is important, since this 
guarantees that the gesture
    action for the axis locking pan gesture will always fire right before the 
scroll view's default
    scrolling pan gesture.

2.  We build on this by calling out to the axis locking delegate to get the set 
of axes to prevent
    scrolling and use this information to call `-[UIPanGestureRecognizer 
setTranslation:inView:]` on
    the scroll view's built-in pan gesture recognizer, zeroing out either the 
`x` or `y` component
    of the translation (depending on what the delegate method returned). This 
allows us to make
    UIKit behave as if the user was scrolling perfectly along the x or y axis 
upon converting the
    pan gesture translation amount into scroll deltas, using the built-in pan 
gesture recognizer.

* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h:
* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _setupScrollAndContentViews]):
(-[WKWebView scrollViewWillEndDragging:withVelocity:targetContentOffset:]):
(-[WKWebView axesToPreventScrollingForPanGestureInScrollView:]):
(-[WKWebView 
_scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]):
 Deleted.

Delete this SPI delegate method implementation, and instead move the 
corresponding logic into the
new `-axesToPreventScrollingForPanGestureInScrollView:` delegate method.

* Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:

Make `WKChildScrollView` subclass the new `WKAxisLockingScrollView`.

* 
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm:
(-[WKScrollingNodeScrollViewDelegate 
scrollViewWillEndDragging:withVelocity:targetContentOffset:]):

Because the new `-axesToPreventScrollingForPanGestureInScrollView:` delegate 
method isn't called
after scrolling ends, we need a separate mechanism in order to limit momentum 
scrolling to the
locked scrolling axis. Achieve this by keeping track of the axes where we 
prevented scrolling in the
`WKAxisLockingScrollView` during the pan gesutre, and then use public scroll 
view delegate API to
retarget the default scrolling destination to the current offset value, 
effectively canceling out
any momentum scrolling in that axis.

(-[WKScrollingNodeScrollViewDelegate 
axesToPreventScrollingForPanGestureInScrollView:]):
(WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren):
(-[WKScrollingNodeScrollViewDelegate 
_scrollView:adjustedOffsetForOffset:translation:startPoint:locationInView:horizontalVelocity:verticalVelocity:]):
 Deleted.

Same as above; move this logic into 
`-axesToPreventScrollingForPanGestureInScrollView:` to service
the overflow scrolling case.

* Source/WebKit/UIProcess/ios/WKAxisLockingScrollView.h: Copied from 
Source/WebKit/UIProcess/ios/WKVelocityTrackingScrollView.h.
* Source/WebKit/UIProcess/ios/WKAxisLockingScrollView.mm: Added.
(-[WKAxisLockingScrollView initWithFrame:]):
(-[WKAxisLockingScrollView addGestureRecognizer:]):
(-[WKAxisLockingScrollView removeGestureRecognizer:]):
(-[WKAxisLockingScrollView _updatePanGestureToPreventScrolling]):
(-[WKAxisLockingScrollView _axesToPreventScrollingFromDelegate]):
(-[WKAxisLockingScrollView 
gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:]):
(-[WKAxisLockingScrollView gestureRecognizerShouldBegin:]):

Add the new internal scroll view subclass; see above for more details.

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

(Drive-by): give these `_touchAction*SwipeGestureRecognizer`s human-readable 
names, so that they're
easier to identify and debug.

* Source/WebKit/UIProcess/ios/WKVelocityTrackingScrollView.h:

Make the velocity tracking scroll view subclass `WKAxisLockingScrollView` 
(`WKScrollView`, in turn,
subclasses this).

* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/271171@main


_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to