mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 15:43:20 +00:00
LibWeb: More thoroughly detach layout/paint trees from each other
Before committing a new layout (and thus building a new paint tree) we now go through both the old paint tree and the layout tree and detach them from each other. This is a little extra work, but it ensures that there are no lingering references across the trees, which we were apparently accumulating in some cases on Discord, causing GC leaks.
This commit is contained in:
parent
138eabcf0d
commit
3b63582068
Notes:
github-actions[bot]
2025-07-30 20:59:47 +00:00
Author: https://github.com/awesomekling
Commit: 3b63582068
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5657
Reviewed-by: https://github.com/kalenikaliaksandr
3 changed files with 20 additions and 3 deletions
|
@ -214,14 +214,23 @@ static void build_paint_tree(Node& node, Painting::Paintable* parent_paintable =
|
|||
|
||||
void LayoutState::commit(Box& root)
|
||||
{
|
||||
// NOTE: In case this is a relayout of an existing tree, we start by detaching the old paint tree
|
||||
// from the layout tree. This is done to ensure that we don't end up with any old-tree pointers
|
||||
// when text paintables shift around in the tree.
|
||||
// Go through the old paintable tree and detach everything from the layout tree.
|
||||
// The layout tree should only point to the new paintable tree which we're about to build.
|
||||
if (auto* old_paintable_root = root.first_paintable()) {
|
||||
old_paintable_root->for_each_in_inclusive_subtree([&](Painting::Paintable& paintable) {
|
||||
paintable.detach_from_layout_node();
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
// For completeness, also go through the layout tree and detach all paintables.
|
||||
root.for_each_in_inclusive_subtree([&](Layout::Node& node) {
|
||||
node.clear_paintables();
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
// After this point, we should have a clean slate to build the new paint tree.
|
||||
|
||||
HashTable<Layout::InlineNode*> inline_nodes;
|
||||
|
||||
root.document().for_each_shadow_including_inclusive_descendant([&](DOM::Node& node) {
|
||||
|
|
|
@ -36,6 +36,12 @@ Paintable::~Paintable()
|
|||
{
|
||||
}
|
||||
|
||||
void Paintable::detach_from_layout_node()
|
||||
{
|
||||
if (m_list_node.is_in_list())
|
||||
m_list_node.remove();
|
||||
}
|
||||
|
||||
void Paintable::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
|
|
@ -56,6 +56,8 @@ class Paintable
|
|||
public:
|
||||
virtual ~Paintable();
|
||||
|
||||
void detach_from_layout_node();
|
||||
|
||||
[[nodiscard]] bool is_visible() const { return m_visible; }
|
||||
[[nodiscard]] bool is_positioned() const { return m_positioned; }
|
||||
[[nodiscard]] bool is_fixed_position() const { return m_fixed_position; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue