Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: e8697834ad4b3d036032823f29b7d4329ffb45ec
      
https://github.com/WebKit/WebKit/commit/e8697834ad4b3d036032823f29b7d4329ffb45ec
  Author: Simon Fraser <[email protected]>
  Date:   2026-02-25 (Wed, 25 Feb 2026)

  Changed paths:
    A 
LayoutTests/fast/scrolling/mac/momentum-then-programmatic-hit-test-expected.txt
    A LayoutTests/fast/scrolling/mac/momentum-then-programmatic-hit-test.html
    A 
LayoutTests/fast/scrolling/mac/momentum-then-programmatic-missing-tiles-expected.html
    A 
LayoutTests/fast/scrolling/mac/momentum-then-programmatic-missing-tiles.html
    M 
LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-anchoring/dirty-contents-reselect-anchor.tentative-expected.txt
    M LayoutTests/platform/ios/TestExpectations
    M Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
    M Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
    M Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.cpp
    M Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h
    M Source/WebCore/page/scrolling/ScrollingTree.h
    M Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
    M Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
    M Source/WebCore/page/scrolling/ThreadedScrollingTree.h
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
    M 
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
    M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h
    M 
Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingCoordinatorProxyMac.h
    M 
Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingCoordinatorProxyMac.mm
    M Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.h
    M Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm
    M 
Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h
    M 
Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm
    M Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

  Log Message:
  -----------
  [Async scrolling] Programmatic scrolls can cause missing tiles and offset 
hit-testing
https://bugs.webkit.org/show_bug.cgi?id=262287
rdar://116205365

Reviewed by Alan Baradlay and Abrar Rahman Protyasha.

This change fixes some long-standing issues with asynchronous scrolling, where
UI and web processes could be left with different scroll positions when both
user and programmatic scrolling was happening at the same time. This could 
result
in bad tile coverage (missing content), and offset hit-testing.

The fundamental problem was that IPC message for programmatic scrolling, from
web to UI process, could overlap with messages in the other direction for user
scrolling; the messages would pass like ships in the night, with no final
reconciliation step.

307867@main introduced the concept of `ScrollRequestIdentifier`. This change
makes use of those identifiers to ensure that the web process is updated with
the correct scroll position via a message from the UI process back to the web
process. Every programmatic scroll IPC now triggers a response message, which
returns the originating identifier. This allows `RemoteScrollingCoordinator` in
the web process to know when there's programmatic scroll in flight. When there
is, we have to ignore user scrolls, because they will contain a scroll position
that is stale relative to the current web process scroll position. With multiple
programmatic scrolls in a row, we also have to ignore the response for the same
reason. We need to take care to fire `scrollend` when necessary.

ScrollUpdate now has a data member with two variants; one for responses to
programmatic scrolls (`ScrollRequestResponseData`) and one for other messages
from UI to web process.

We actually apply the scroll position in 
`RemoteScrollingCoordinator::scrollUpdateForNode()`,
to handle the case where the web process sent a "delta" scroll (e.g. for scroll
anchoring or `scrollBy`); the response will contain the most recent UI-side 
scroll
position with the delta applied.

There was already a `ProgrammaticScrollDidEnd` sent back to the web process; now
that we always send `ScrollRequestResponse` updates back, use that to trigger
`scrollend` via a `ShouldFireScrollEnd` member on ScrollUpdate.
`scrollingTreeNodeDidStopProgrammaticScroll` is no longer needed.

`scrollingTreeNodeRequestsScroll()` has to distinguish between "scrolling tree
handled it for animated scroll", and "scrolling tree delayed handling for
delegated scrolling" so add `RequestsScrollHandling` to indicate that.

The changes in `ScrollingTreeScrollingNode::handleScrollPositionRequest()` and
`RemoteScrollingCoordinatorProxy::adjustMainFrameDelegatedScrollPosition()` are
needed to handle the iOS-specific behavior, seen in 
`RemoteLayerTreeDrawingAreaProxy::commitLayerTreeTransaction()`,
where the application of the `requestedScroll` is delayed until after layer tree
commit; `didHandleScrollRequestForNode()` needs to be called once the final 
scroll
position has been computed (this is tested by existing tests).

Tests: fast/scrolling/mac/momentum-then-programmatic-hit-test.html
       fast/scrolling/mac/momentum-then-programmatic-missing-tiles.html

* 
LayoutTests/fast/scrolling/mac/momentum-then-programmatic-hit-test-expected.txt:
 Added.
* LayoutTests/fast/scrolling/mac/momentum-then-programmatic-hit-test.html: 
Added.
* 
LayoutTests/fast/scrolling/mac/momentum-then-programmatic-missing-tiles-expected.html:
 Added.
* LayoutTests/fast/scrolling/mac/momentum-then-programmatic-missing-tiles.html: 
Added.
* 
LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-anchoring/dirty-contents-reselect-anchor.tentative-expected.txt:
* LayoutTests/platform/ios/TestExpectations:
* Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::requestScrollToPosition):
(WebCore::AsyncScrollingCoordinator::synchronizeStateFromScrollingTree):
(WebCore::AsyncScrollingCoordinator::applyScrollPositionUpdate):
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
* Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h:
* Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.cpp:
(WebCore::ScrollUpdate::canMerge const):
(WebCore::ScrollUpdate::merge):
(WebCore::operator<<):
* Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h:
(WebCore::ScrollUpdate::canMerge const): Deleted.
(WebCore::ScrollUpdate::merge): Deleted.
* Source/WebCore/page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::scrollingTreeNodeDidStopWheelEventScroll):
(WebCore::ScrollingTree::scrollingTreeNodeRequestsScroll):
(WebCore::ScrollingTree::didHandleScrollRequestForNode):
(WebCore::ScrollingTree::scrollingTreeNodeDidStopProgrammaticScroll): Deleted.
* Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::handleScrollPositionRequest):
(WebCore::ScrollingTreeScrollingNode::didStopProgrammaticScroll): Deleted.
* Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::scrollingTreeNodeRequestsScroll):
(WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
(WebCore::ThreadedScrollingTree::didHandleScrollRequestForNode):
(WebCore::ThreadedScrollingTree::scrollingTreeNodeScrollUpdated):
* Source/WebCore/page/scrolling/ThreadedScrollingTree.h:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::adjustMainFrameDelegatedScrollPosition):
(WebKit::RemoteScrollingCoordinatorProxy::sendScrollingTreeNodeUpdate):
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll):
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidStopAnimatedScroll):
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidStopWheelEventScroll):
(WebKit::RemoteScrollingTree::scrollingTreeNodeRequestsScroll):
(WebKit::RemoteScrollingTree::didHandleScrollRequestForNode):
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidStopProgrammaticScroll): 
Deleted.
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
* 
Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingCoordinatorProxyMac.h:
* 
Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingCoordinatorProxyMac.mm:
(WebKit::RemoteScrollingCoordinatorProxyMac::scrollingTreeNodeRequestsScroll):
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.h:
* Source/WebKit/UIProcess/RemoteLayerTree/mac/RemoteScrollingTreeMac.mm:
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeDidScroll):
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeDidStopAnimatedScroll):
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeDidStopWheelEventScroll):
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeRequestsScroll):
(WebKit::RemoteScrollingTreeMac::scrollingTreeNodeDidStopProgrammaticScroll): 
Deleted.
* Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.h:
* 
Source/WebKit/WebProcess/WebPage/RemoteLayerTree/RemoteScrollingCoordinator.mm:
(WebKit::RemoteScrollingCoordinator::willSendScrollPositionRequest):
(WebKit::RemoteScrollingCoordinator::scrollUpdateForNode):
* Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateVisibleContentRects):

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



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to