Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 4faf2f36c97b176fa72125a0c700e58e33d6bd7a
https://github.com/WebKit/WebKit/commit/4faf2f36c97b176fa72125a0c700e58e33d6bd7a
Author: Wenson Hsieh <[email protected]>
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
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes