Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 8612f9f7a3cda362a6280a9ef0e0e687f4d360c1
https://github.com/WebKit/WebKit/commit/8612f9f7a3cda362a6280a9ef0e0e687f4d360c1
Author: Wenson Hsieh <[email protected]>
Date: 2024-11-11 (Mon, 11 Nov 2024)
Changed paths:
A
LayoutTests/fast/events/touch/ios/programmatic-scrolling-on-touchmove-expected.txt
A LayoutTests/fast/events/touch/ios/programmatic-scrolling-on-touchmove.html
M Source/WebCore/dom/ios/MouseEventIOS.cpp
M Source/WebCore/dom/ios/PointerEventIOS.cpp
M Source/WebCore/page/PointerCaptureController.cpp
M Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm
M Source/WebCore/platform/ios/ScrollAnimatorIOS.mm
M Source/WebKit/Shared/WebEvent.serialization.in
M Source/WebKit/Shared/WebEventConversion.cpp
M Source/WebKit/Shared/WebTouchEvent.h
M Source/WebKit/Shared/ios/NativeWebTouchEventIOS.mm
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
M Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.h
M Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm
M Tools/TestWebKitAPI/Tests/ios/TouchEventTests.mm
Log Message:
-----------
REGRESSION (265825@main): [iOS] europa.eu: Scroll position jitters when
scrolling over interactive map
https://bugs.webkit.org/show_bug.cgi?id=282933
rdar://112427506
Reviewed by Abrar Rahman Protyasha.
The changes in 265825@main exacerbated an existing bug, regarding how our touch
event handling logic
propagates the location of the user's touches from the UI process to the web
process; this results
in scrolling on the immigration portal on europa.eu becoming extremely jittery
(bouncing between the
minimum and maximum scroll positions in the main document) as the user performs
an upwards swipe
over the interactive map to scroll down.
The interactive map on europa.eu intercepts and prevents all `touchstart` and
`touchmove` events
that are dispatched over it. When the user attempts to scroll the page by
swiping over the element
and `touchmove` is dispatched, their script attempts to adjust `pageYOffset`
such that the location
of the user's touch relative to the document remains the same, before and after
handling the
`touchmove` delta. In other words, the `touchmove` event listener simulates
scrolling by keeping a
point in content coordinates fixed underneath the user's finger as they pan.
However, this doesn't quite work well in practice, especially after the changes
in 265825@main
elided an extra CA commit that would otherwise more aggressively sync
programmatic scrolling to UI-
side scroll content offset. That's because touch locations are computed in
`WKContentView`
coordinates in the UI process (when receiving gesture recognizer subclass
method calls from UIKit),
and then dispatched to the web process where they're asynchronously queued and
delivered to event
listeners for processing. Throughout this process, the root view location of
the touch remains
unchanged since it was computed in the UI process, which means that it ignores
any changes to the
scroll position of the page that happened after the gesture was recognized.
This is particularly
disastrous when combined with europa.eu's touch event handling logic, which
constantly shifts the
scroll position when receiving `touchmove` events — the result is that the page
can be scrolled
programmatically, but the root view coordinates of subsequent `touchmove` touch
locations don't
reflect this scrolling at all, causing the event listener to try and move the
`pageYOffset` in the
*opposite* direction to compensate. This error then compounds very quickly,
causing the scroll
position to jump between min and max scroll positions on the page.
To fix this, we make some adjustments to propagate the user's touch location
relative to the
viewport (unobscured content rect), and only map from the viewport back to root
view coordinates at
the last possible moment before dispatching the event by shifting the touch
delta back up, using the
main frame's current `contentsScrollPosition()`.
See below for more details.
*
LayoutTests/fast/events/touch/ios/programmatic-scrolling-on-touchmove-expected.txt:
Added.
* LayoutTests/fast/events/touch/ios/programmatic-scrolling-on-touchmove.html:
Added.
Add a layout test to exercise the change, by swiping up in a reduced test case
that emulates
europa.eu's logic for scrolling in response to `touchmove`, and verifying that
the scroll position
always stays within reasonable limits. Without the fixes in this bug, the
`pageYOffset` ends up
bouncing between negative values and values of up to 2000-3000.
* Source/WebCore/dom/ios/MouseEventIOS.cpp:
(WebCore::MouseEvent::create):
* Source/WebCore/dom/ios/PointerEventIOS.cpp:
(WebCore::PointerEvent::PointerEvent):
* Source/WebCore/page/PointerCaptureController.cpp:
(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
* Source/WebCore/platform/ios/PlatformEventFactoryIOS.mm:
(WebCore::PlatformTouchPointBuilder::PlatformTouchPointBuilder):
(WebCore::PlatformTouchEventBuilder::PlatformTouchEventBuilder):
Pass `locationInViewport` through to `PlatformTouchPoint` on construction. This
is optional since
we currently don't compute this for `UIWebView` (WebKitLegacy).
* Source/WebCore/platform/ios/ScrollAnimatorIOS.mm:
Adjust call sites, since `touchLocationAtIndex` is now renamed to
`touchLocationInRootViewAtIndex`.
(WebCore::ScrollAnimatorIOS::handleTouchEvent):
* Source/WebKit/Shared/WebEvent.serialization.in:
* Source/WebKit/Shared/WebEventConversion.cpp:
(WebKit::WebKit2PlatformTouchPoint::WebKit2PlatformTouchPoint):
* Source/WebKit/Shared/WebTouchEvent.h:
(WebKit::WebPlatformTouchPoint::WebPlatformTouchPoint):
(WebKit::WebPlatformTouchPoint::locationInRootView const):
(WebKit::WebPlatformTouchPoint::locationInViewport const):
(WebKit::WebPlatformTouchPoint::location const): Deleted.
Rename `location` to `locationInRootView` (along with other related members),
and plumb a new
`locationInViewport` point alongside the touch point.
* Source/WebKit/Shared/ios/NativeWebTouchEventIOS.mm:
(WebKit::NativeWebTouchEvent::extractWebTouchPoints):
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::updateTouchEventTracking):
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
Refactor `WKTouchEventsGestureRecognizer` to just directly take a
`WKContentView`. Now that the
touch events gesture no longer needs to be generic for both WebKitLegacy and
modern WebKit, there's
no benefit to maintaining a separate, WebKit-internal
`WKTouchEventsGestureRecognizerDelegate` that
is only implemented by the content view.
This allows us to remove some unused code and unnecessary logic (such as the
touch target and action
selector, as well as `-isAnyTouchOverActiveArea:`), but importantly allows us
to call into the web
view to compute the unobscured content offset when determining the
viewport-relative location for
each `WKTouchPoint`.
(-[WKContentView setUpInteraction]):
(-[WKContentView _touchEventsRecognized]):
(-[WKContentView _handleTouchActionsForTouchEvent:]):
(-[WKContentView _shouldIgnoreTouchEvent:]):
(-[WKContentView _touchEventsRecognized:]): Deleted.
(-[WKContentView gestureRecognizer:shouldIgnoreTouchEvent:]): Deleted.
(-[WKContentView isAnyTouchOverActiveArea:]): Deleted.
* Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.h:
* Source/WebKit/UIProcess/ios/WKTouchEventsGestureRecognizer.mm:
(-[WKTouchEventsGestureRecognizer initWithContentView:]):
(mapRootViewToViewport):
Add a helper function to unadjust the given point in root view coordinates by
the current unobscured
content offset.
(-[WKTouchEventsGestureRecognizer _touchEventForTouch:]):
(-[WKTouchEventsGestureRecognizer
_recordTouches:type:coalescedTouches:predictedTouches:]):
Populate the new `locationInViewport` member on each touch point.
(-[WKTouchEventsGestureRecognizer performAction]):
(-[WKTouchEventsGestureRecognizer touchesBegan:withEvent:]):
(-[WKTouchEventsGestureRecognizer initWithTarget:action:touchDelegate:]):
Deleted.
* Tools/TestWebKitAPI/Tests/ios/TouchEventTests.mm:
Canonical link: https://commits.webkit.org/286448@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes