Bug 511163 Comment 10 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes (e.g. due to some child getting larger and overflowing it).

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (which is a reflow root), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repouplated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport.)

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which causes the scrollbars to be updated.
So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes (e.g. due to some child getting larger and overflowing it).

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (the reflow root in question), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repouplated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport.)

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which causes the scrollbars to be updated.
So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes during that reflow. (e.g. due to some child getting larger and overflowing)

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (the reflow root in question), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repouplated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport.)

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which causes the scrollbars to be updated.
So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes during that reflow. (e.g. due to some child getting larger and overflowing)

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (the reflow root in question), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repopulated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport.)

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which causes the scrollbars to be updated.
So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes during that reflow. (e.g. due to some child getting larger and overflowing)

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (the reflow root in question), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repopulated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport, or some other reflow root that is further towards the root of the frame tree than `target` is).

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which causes the scrollbars to be updated.
So, suppose we reflow inside some `target` frame which is a reflow root and is not the actual root of the tree; and suppose its scrollable overflow area changes during that reflow. (e.g. due to some child getting larger and overflowing)

Here's what happens, to ensure that scrollbars on ancestors get updated appropriately:
(0) `ProcessReflowCommands` calls `DoReflow` for this `target` frame (the reflow root in question), and passes in a temporary `OverflowChangedTracker` for it to use:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9298

(1) `DoReflow` saves a copy of the `target`'s overflow areas before it actually does the reflow. And then after it's finished reflowing, it checks whether the `target`'s overflow areas changed.  If they did change, it tells the caller's `OverflowChangedTracker` about it:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9169-9172

(2) We pop back up to `ProcessReflowCommands`, which flushes the temporary `OverflowChangedTracker`:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9307
...which causes us to propagate the overflow change upwards:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/OverflowChangedTracker.h#137-140,163-164

(3) During that upward propagation: when we reach the scrollable frame, the scrollable frame calls `nsIPresShell::FrameNeedsReflow` for itself, via this backtrace:
```
#0  0x00007fb29710dba8 in nsIPresShell::FrameNeedsReflow(...)
    at $SRC/layout/base/PresShell.cpp:2566
#1  0x00007fb29733d8ff in mozilla::ScrollFrameHelper::ComputeCustomOverflow(...)
    at $SRC/layout/generic/nsGfxScrollFrame.cpp:5899
#2  0x00007fb29739d826 in nsHTMLScrollFrame::ComputeCustomOverflow(...)
     at ../../../mozilla/layout/generic/nsGfxScrollFrame.h:852
#3  0x00007fb2972f69bc in nsIFrame::UpdateOverflow()
    at $SRC/layout/generic/nsFrame.cpp:7366
#4  0x00007fb297152631 in mozilla::OverflowChangedTracker::Flush()
    at ../../../mozilla/layout/base/OverflowChangedTracker.h:110
#5  0x00007fb297119efa in nsIPresShell::ProcessReflowCommands(bool)
    at $SRC/layout/base/PresShell.cpp:9331
```
This results in `mDirtyRoots` getting repopulated with a reflow root that is an ancestor of the scrollframe (e.g. the actual viewport, or some other reflow root that is further towards the root of the frame tree than `target` is).

(4) Once `OverflowChangedTracker::Flush` completes, we pop back up to where we'd left off near the end of `ProcessReflowCommands`.  We discover that our recent `FrameNeedsReflow` call has given us a dirty reflow root, so we schedule a reflow to handle that:
https://searchfox.org/mozilla-central/rev/6dab6dad9cc852011a14275a8b2c2c03ed7600a7/layout/base/PresShell.cpp#9325-9333

(5) On the next layout flush (the next refresh driver tick, in my case), we handle that queued reflow, which reflows the scrollable frame (the thing we called FrameNeedsReflow on), which causes its scrollbars to be updated.

Back to Bug 511163 Comment 10