Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: d801bd01eb61cf3c6404099d4ba07a56eb7daf26
      
https://github.com/WebKit/WebKit/commit/d801bd01eb61cf3c6404099d4ba07a56eb7daf26
  Author: Sammy Gill <[email protected]>
  Date:   2026-04-17 (Fri, 17 Apr 2026)

  Changed paths:
    M Source/WebCore/Headers.cmake
    M Source/WebCore/Sources.txt
    M Source/WebCore/WebCore.xcodeproj/project.pbxproj
    M Source/WebCore/rendering/LayoutScope.cpp
    M Source/WebCore/rendering/LayoutScope.h
    A Source/WebCore/rendering/RelayoutScopeForScrollbarChange.cpp
    A Source/WebCore/rendering/RelayoutScopeForScrollbarChange.h
    M Source/WebCore/rendering/RenderBlock.cpp
    M Source/WebCore/rendering/RenderBlock.h
    M Source/WebCore/rendering/RenderLayer.cpp
    M Source/WebCore/rendering/RenderLayer.h
    M Source/WebCore/rendering/RenderLayerScrollableArea.cpp
    M Source/WebCore/rendering/RenderLayerScrollableArea.h
    M Source/WebCore/rendering/RenderTheme.cpp
    A Source/WebCore/rendering/ScrollbarUpdateScope.cpp
    A Source/WebCore/rendering/ScrollbarUpdateScope.h

  Log Message:
  -----------
  Move RenderBlock overflow relayout logic out of RenderLayerScrollableArea.
https://bugs.webkit.org/show_bug.cgi?id=312392
rdar://problem/174850591

Reviewed by Alan Baradlay.

The way that RenderLayerScrollableArea::updateScrollInfoAfterLayout is
roughly organized, for the purposes of this change, is as follows:

1.) A preamble that computes the scroll dimensions and origin based off
the renderer's overflow rect and some styling information (e.g. writing
mode) along with some other state updates. This will have the side
effect of creating or destroying scrollbars.

2.) If there is a change in whether an automatic scrollbar is gained or
lost then we will rerun layout on the renderer. This is because a change
in the scrollbar may affect the available space for the content which
would result in a different layout.

3.) Some final updating like updating the scrollbar steps and notifying
the scroll anchoring controller.

All of this is currently done towards the end of a renderer's layout,
via the LayoutScope destructor, but this is a bit misleading since as
part of step two we may layout the renderer and its contents again. From
the perspective of the layout code this is pretty surprising since this
is very far away and hidden from the rest of layout. In this patch we
attempt to reconcile this by trying to move the logic contained within
step two outside of RenderLayerScrollableArea a bit.

This should be just a mechanical change with no changes in functional
behavior since it should be some shuffling of code that runs in the same
order but just via a couple of new mechanisms. Those two new mechanisms
are RelayoutScopeForScrollbarChange and ScrollbarUpdateScope.
The idea is that the former will hold the logic related to layout while
the latter does the work needed for RenderLayerScrollableArea. So, now
what happens is:

1.) Instead of calls to RenderBlock::updateScrollInfoAfterLayout, which
finds its way into the RenderLayerScrollableArea variant, we replace
those with a construction of RelayoutScopeForScrollbarChange.

2.) We will perform the preamble and return a ScrollbarUpdateScope
and will hold onto it in RelayoutScopeForScrollbarChange.

3.) When RelayoutScopeForScrollbarChange is destroyed we will do the work
that was included in step two of the original flow.

4.) When ScrollbarUpdateScope is destroyed it
will run the remaining work that is in step three of the original flow.

There are likely a number of ways we can improve on this but this should
hopefully be a good starting point to build off of.

* Source/WebCore/rendering/RenderLayerScrollableArea.cpp:
(WebCore::RenderLayerScrollableArea::updateScrollInfoAfterLayout):
1.) This function, including the variants that seem to be mostly
plumbing into this, needs to return an optional to match the various
early returns that could have been hit before. This will serve as the
indicator that we returned early somewhere in this stack so we should
not try to do any of the work that got moved into 
RelayoutScopeForScrollbarChange.

2.) Move the logic that was in updateScrollbarsAfterLayout into this
function. So now this function should contain all of the previous code
that ran up to the point we started to perform layout on the renderer
again.

* Source/WebCore/rendering/LayoutScope.cpp:
(WebCore::LayoutScope::LayoutScope):
RelayoutScopeForScrollbarChange will need to know if we are already in an
overflow relayout so that we avoid recursion. Previously, this was
tracked via a SetForScope when we entered the RenderLayerScrollableArea
code. Instead when we create a LayoutScope there we will let it know
that we are in overflow relayout, which will pass it into the
RelayoutScopeForScrollbarChange it creates in the destructor.

* Source/WebCore/rendering/RelayoutScopeForScrollbarChange.cpp: Added.
(WebCore::RelayoutScopeForScrollbarChange::RelayoutScopeForScrollbarChange):
In the constructor we will call updateScrollInfoAfterLayout which will
eventually reach RenderLayerScrollableArea. We hold onto the return
value because we want to make sure that the destructor for
ScrollbarUpdateScope only runs after we run the
code that potentially runs layout on the renderer again to make sure we
keep the same flow.

(WebCore::RelayoutScopeForScrollbarChange::~RelayoutScopeForScrollbarChange):
Contains the logic that was ripped out of RenderLayerScrollableArea
related to performing layout on the renderer. Note that the original
code contained an else layout() when the renderer was not a RenderBlock,
but that seems to have been dead code since we never called
updateScrollInfoAfterLayout on a renderer that was not a RenderBlock.

* Source/WebCore/rendering/RelayoutScopeForScrollbarChange.h: Added.
I deleted the copy constructor and assignment operator since it does not
seem like it would make sense to have copies of this object. That would
be like calling updateScrollInfoAfterLayout multiple times which I think
is a bug so this should hopefully make it harder to do accidentally.

* Source/WebCore/rendering/ScrollbarUpdateScope.cpp: Added.
(WebCore::ScrollbarUpdateScope::ScrollbarUpdateScope):
We create this at the end of 
RenderLayerScrollableArea::updateScrollInfoAfterLayout
right before we would run the code to layout the renderer again. This is
used mostly to hold onto some state that is needed after the renderer
has gone through layout.

(WebCore::ScrollbarUpdateScope::~ScrollbarUpdateScope):
Should just be the remaining code in updateScrollInfoAfterLayout after we
run layout on the renderer.

* Source/WebCore/rendering/ScrollbarUpdateScope.h: Added.
Same idea with the copy constructor and assignment as 
RelayoutScopeForScrollbarChange.

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



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

Reply via email to