Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 4faf2f36c97b176fa72125a0c700e58e33d6bd7a
      
https://github.com/WebKit/WebKit/commit/4faf2f36c97b176fa72125a0c700e58e33d6bd7a
  Author: Wenson Hsieh <wenson_hs...@apple.com>
  Date:   2023-10-11 (Wed, 11 Oct 2023)

  Changed paths:
    M LayoutTests/fast/scrolling/ios/key-command-scroll-to-bottom.html
    M LayoutTests/fast/scrolling/ios/key-command-scroll-to-top-expected.html
    M LayoutTests/fast/scrolling/ios/key-command-scroll-to-top.html
    M Source/WebKit/Platform/spi/ios/UIKitSPI.h
    M Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h
    M Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
    M Source/WebKit/UIProcess/ios/WKKeyboardScrollingAnimator.mm
    M Tools/WebKitTestRunner/TestOptions.cpp
    M Tools/WebKitTestRunner/TestOptions.h
    M Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm
    M Tools/WebKitTestRunner/ios/TestControllerIOS.mm

  Log Message:
  -----------
  Stop using -[UIScrollView _setContentOffsetWithDecelerationAnimation:]
https://bugs.webkit.org/show_bug.cgi?id=262997
rdar://112474966

Reviewed by Tim Horton.

Refactor `WKKeyboardScrollingAnimator` to stop using 
`-_setContentOffsetWithDecelerationAnimation:`.
This is currently used to scroll to the start or end of the webpage using a 
spring animation that
loosely resembes exponential decay (i.e. the same animation that drives 
scrolling to the top when
tapping near the top of a `UIScrollView`).

This pulls that same `CASpringAnimation` into WebKit, and scrolls the scroll 
view using that
animation. Since it's not currently possible to directly drive animated 
scrolling in a `UIScrollView`
with a custom `CAAnimation`, we instead:

1.  Create a hidden, 0 by 0 `UIView` and add it to the view hierarchy under the 
scroll view.
2.  Add our spring animation to the `UIView`'s layer, and use it to animate the 
`position` property.
    The animation starts the `position` off at the scroll view's content 
offset, and ends with the
    `position` at the target content offset. This allows us to...
3.  Use the existing `CADisplayLink` that drives normal smooth keyboard 
scrolling to synchronize
    the `position` as it animates, such that the scroll view scrolls using the 
same animation curve
    as it would when using `-_setContentOffsetWithDecelerationAnimation:`.

* LayoutTests/fast/scrolling/ios/key-command-scroll-to-bottom.html:
* LayoutTests/fast/scrolling/ios/key-command-scroll-to-top-expected.html:
* LayoutTests/fast/scrolling/ios/key-command-scroll-to-top.html:

Adjust a couple of layout tests to continue passing after these changes:

•   We need to suppress scroll view indicators for this test, so that they 
don't show up in the ref
    image. Currently, we flash scrollbars at the beginning of the scroll, such 
that they fade out by
    the time keyboard scrolling is complete. After this change, we'll start the 
fade animation only
    after scrolling finishes, which causes the scroll bar to linger around for 
longer than the hard-
    coded 1000 ms timeout.

•   We also need to actually wait for the keyboard scrolling animation to 
complete. Currently, this
    Just Works because the hard-coded 1000 ms delay that waits for the scroll 
indicators to fade out
    also ensures that the scrolling animation completes. Removing this timeout 
while suppressing
    scrollbars therefore causes the test to still fail, due to subpixel 
differences since the scroll
    position is rounded to 0, when the scroll view is actually < 0.5 pt away 
from the top. Fix this
    by teaching `UIHelper.waitForZoomingOrScrollingToEnd()` about keyboard 
scrolling animations, via
    a new testing-only SPI hook on `WKWebView`, and then adjusting the layout 
tests to complete only
    after the `waitForZoomingOrScrollingToEnd()` promise resolves.

* Source/WebKit/Platform/spi/ios/UIKitSPI.h:

Remove now-unused SPI declarations. Also clean up a couple of existing SPI 
declarations, by moving
them to the SPI section (out of the IPI section).

* Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
* Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _isKeyboardScrollingAnimationRunning]):

Add a new test-only SPI property to return whether or not a keyboard scrolling 
animation is running.

* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView keyboardScrollViewAnimatorWillScroll:]):
(-[WKContentView keyboardScrollViewAnimatorDidFinishScrolling:]):
(-[WKContentView isKeyboardScrollingAnimationRunning]):
* Source/WebKit/UIProcess/ios/WKKeyboardScrollingAnimator.mm:
(-[WKKeyboardScrollingAnimator invalidate]):
(-[WKKeyboardScrollingAnimator beginWithEvent:]):

Instead of delegating document granularity scrolling to 
`WKKeyboardScrollViewAnimator`, drive this
(mostly) in `WKKeyboardScrollingAnimator` using the above strategy.

(-[WKKeyboardScrollingAnimator willStartInteractiveScroll]):
(-[WKKeyboardScrollingAnimator resetViewForScrollToExtentAnimation]):
(-[WKKeyboardScrollingAnimator stopScrollingImmediately]):
(-[WKKeyboardScrollingAnimator displayLinkFired:]):

Drive the animation by setting the scroller's content offset based on the 
animation tracking view's
position. Note that we need a null check for the `presentationLayer` here, 
since the first
`CADisplayLink` tick after starting the animation sometimes fires when the 
`presentationLayer` is
still `nil`, which would otherwise cause us to stutter to (0, 0) before 
animating.

(-[WKKeyboardScrollViewAnimator 
willBeginScrollingToExtentWithAnimationInTrackingView:]):

Since the `WKKeyboardScrollViewAnimator` no longer drives the "scroll to 
extent" animation, rename
this method and have it simply install the tracking view in the view hierarchy, 
under the
`UIScrollView`.

(-[WKKeyboardScrollViewAnimator scrollWithScrollToExtentAnimationTo:]): Deleted.
* Tools/WebKitTestRunner/TestOptions.cpp:
(WTR::TestOptions::defaults):
(WTR::TestOptions::keyTypeMapping):
* Tools/WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::showsScrollIndicators const):

Add a new test option to set whether or not scroll indicators should be shown 
during the test
(defaults to true, to match behavior of a normal `WKWebView`).

* Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView isZoomingOrScrolling]):

Teach this to take animated keyboard scrolling into account by using the new
`-_isKeyboardScrollingAnimationRunning` test hook.

* Tools/WebKitTestRunner/ios/TestControllerIOS.mm:
(WTR::TestController::platformResetStateToConsistentValues):

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


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

Reply via email to