Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: a13640cea30b69809a8ad998a5ccf27420a94a1f
https://github.com/WebKit/WebKit/commit/a13640cea30b69809a8ad998a5ccf27420a94a1f
Author: Wenson Hsieh <[email protected]>
Date: 2025-07-07 (Mon, 07 Jul 2025)
Changed paths:
A
LayoutTests/compositing/scrolling/async-overflow-scrolling/sticky-in-overflow-scroller-expected.html
A
LayoutTests/compositing/scrolling/async-overflow-scrolling/sticky-in-overflow-scroller.html
M Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp
M Source/WebCore/page/scrolling/ScrollingTreeStickyNode.cpp
M Source/WebCore/page/scrolling/ScrollingTreeStickyNode.h
M Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNodeCocoa.h
M Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNodeCocoa.mm
M
Source/WebCore/page/scrolling/coordinated/ScrollingTreeStickyNodeCoordinated.cpp
M Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
M
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
M Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h
M Source/WebKit/UIProcess/WebPageProxy.cpp
M Source/WebKit/UIProcess/WebPageProxyInternals.h
Log Message:
-----------
REGRESSION (296901@main): Debug assertion under
`ScrollingTreeStickyNode::findConstrainingRect` when opening Web Inspector
https://bugs.webkit.org/show_bug.cgi?id=295533
rdar://155225837
Reviewed by Abrar Rahman Protyasha.
After the changes in 296901@main, opening Web Inspector with a debug macOS
build of WebKit causes an
instant debug assertion to be hit under `findConstrainingRect()`. This happens
because:
1. The logic to `updateIsSticking` currently resides in
`commitStateBeforeChildren`.
2. `updateIsSticking` indirectly calls into `findConstrainingRect`, which may
need to look up
enclosing UI-side scrolling tree scrolling nodes by ID. If the enclosing
scrolling node ID fails
to map to its corresponding scrolling node in the tree, we end up hitting
this debug assert.
3. Scrolling tree scrolling nodes are registered (by ID) with the UI-side
scrolling tree when
committing tree state.
…so in the case where we've already visited (i.e. committed state for) the
enclosing scroller of a
sticky node by the time we visit the sticky node, the lookup in (2) succeeds,
and we don't assert.
However, in the case where the sticky node is *before* the enclosing scrolling
node in tree order,
we'll crash with the debug assert because (3) hasn't happened by the time we
attempt to commit state
for the sticky node.
To fix this, we move logic to update the "sticking" state out of
`commitStateBeforeChildren`, and
instead move it into `applyLayerPositions` (the same codepath that handles
UI-side layer blitting
when scrolling). We also ensure that at most 1 IPC message is sent back to the
web page per main-
frame rendering update, by moving the batching mechanism onto `WebPageProxy`.
*
LayoutTests/compositing/scrolling/async-overflow-scrolling/sticky-in-overflow-scroller-expected.html:
Added.
*
LayoutTests/compositing/scrolling/async-overflow-scrolling/sticky-in-overflow-scroller.html:
Added.
Add a layout test to exercise the assertion; the key piece here is to have
sticky nodes with a
negative initial `z-index` relative to its parent overflow scroller. This
ensures that when
traversing the scrolling tree during the scroll commit, we'll visit the sticky
node *before*
visiting its enclosing overflow scroller.
* Source/WebCore/page/scrolling/ScrollingStateStickyNode.cpp:
(WebCore::ScrollingStateStickyNode::computeAnchorLayerPosition const):
* Source/WebCore/page/scrolling/ScrollingTreeStickyNode.cpp:
(WebCore::ScrollingTreeStickyNode::commitStateBeforeChildren):
(WebCore::ScrollingTreeStickyNode::computeConstrainingRectAndAnchorLayerPosition
const):
Rename `computeAnchorLayerPosition` to
`computeConstrainingRectAndAnchorLayerPosition`, and make it
return both the constraining rect as well as the anchor layer position. The
call site in
(WebCore::ScrollingTreeStickyNode::scrollDeltaSinceLastCommit const):
(WebCore::ScrollingTreeStickyNode::isCurrentlySticking const):
Split this into a second method that takes a precomputed `constrainingRect`,
which we can call from
`applyLayerPositions()` below to avoid redundant work to compute the
constraining rect.
(WebCore::ScrollingTreeStickyNode::updateIsSticking): Deleted.
Move this into `ScrollingTreeStickyNodeCocoa` as `setIsSticking`, and make it
take a `bool`; see
below.
(WebCore::ScrollingTreeStickyNode::computeAnchorLayerPosition const): Deleted.
* Source/WebCore/page/scrolling/ScrollingTreeStickyNode.h:
* Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNodeCocoa.h:
* Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNodeCocoa.mm:
(WebCore::ScrollingTreeStickyNodeCocoa::applyLayerPositions):
Move logic to notify the scrolling tree when a sticky scrolling node has begun
to stick out of
`commitStateBeforeChildren` and into `applyLayerPositions` instead. This allows
us to:
1. Fix the bug by ensuring that `findConstrainingRect()` is only called when
the scrolling tree
nodes have already finished attaching.
2. Avoid having to recompute the constraining rect, since
`applyLayerPositions` already computes it
in the process of repositioning the anchor/clipping layer.
3. Ensure that we still observe that sticky scrolling nodes begin sticking
during UI-side
scrolling, without having to wait for layout in the web process to
reconcile layer positions for
scrolling state nodes.
(WebCore::ScrollingTreeStickyNodeCocoa::setIsSticking):
Use `ensureOnMainRunLoop` here to make sure we don't try to mutate any state
downstream on the
scrolling thread, and instead hop to the main thread if needed.
*
Source/WebCore/page/scrolling/coordinated/ScrollingTreeStickyNodeCoordinated.cpp:
(WebCore::ScrollingTreeStickyNodeCoordinated::applyLayerPositions):
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::didCommitLayerTree):
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::commitScrollingTreeState):
(WebKit::RemoteScrollingCoordinatorProxy::stickyScrollingTreeNodeBeganSticking):
Remove `m_stickyScrollingTreeNodesBeganSticking` here, and instead add a flag
to `WebPageProxy`
(below) to send at most one IPC message to invalidate
`m_needsFixedContainerEdgesUpdate`, even if
a large number of sticky scrolling nodes begin sticking during the same
rendering update.
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::resetState):
(WebKit::WebPageProxy::stickyScrollingTreeNodeBeganSticking):
* Source/WebKit/UIProcess/WebPageProxyInternals.h:
Canonical link: https://commits.webkit.org/297097@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