1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:27:35 +00:00

LibWeb: Paint positioned descendants with z-index: auto

This "worked" before because all positioned elements would create their
own stacking context. When we stopped doing this, there was nobody to
actually paint positioned descendants with `z-index: auto`.

This patch splits up steps 8 and 9 of the paint order algorithm and
implements step 8 as a paint tree traversal. There's more to step 8 than
I've implemented here, so I've left a FIXME for our future selves.
This commit is contained in:
Andreas Kling 2022-10-23 18:18:58 +02:00
parent 8a0e40c5b0
commit 447519f678

View file

@ -153,11 +153,40 @@ void StackingContext::paint_internal(PaintContext& context) const
paint_descendants(context, m_box, StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced);
paint_node(m_box, context, PaintPhase::Foreground);
paint_descendants(context, m_box, StackingContextPaintPhase::Foreground);
// Draw other positioned descendants (steps 8, 9)
// Draw positioned descendants with z-index `0` or `auto` in tree order. (step 8)
// FIXME: There's more to this step that we have yet to understand and implement.
m_box.paint_box()->for_each_in_subtree_of_type<PaintableBox>([&](PaintableBox const& paint_box) {
if (!paint_box.layout_box().is_positioned())
return TraversalDecision::Continue;
auto const& z_index = paint_box.computed_values().z_index();
if (z_index.has_value() && z_index.value() != 0)
return TraversalDecision::Continue;
if (auto* child = paint_box.stacking_context()) {
paint_child(child);
return TraversalDecision::SkipChildrenAndContinue;
}
// At this point, `paint_box` is a positioned descendant with z-index: auto
// but no stacking context of its own.
// FIXME: This is basically duplicating logic found elsewhere in this same function. Find a way to make this more elegant.
paint_node(paint_box.layout_box(), context, PaintPhase::Background);
paint_node(paint_box.layout_box(), context, PaintPhase::Border);
paint_descendants(context, paint_box.layout_box(), StackingContextPaintPhase::BackgroundAndBorders);
paint_descendants(context, paint_box.layout_box(), StackingContextPaintPhase::Floats);
paint_descendants(context, paint_box.layout_box(), StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced);
paint_node(paint_box.layout_box(), context, PaintPhase::Foreground);
paint_descendants(context, paint_box.layout_box(), StackingContextPaintPhase::Foreground);
paint_node(paint_box.layout_box(), context, PaintPhase::FocusOutline);
paint_node(paint_box.layout_box(), context, PaintPhase::Overlay);
paint_descendants(context, paint_box.layout_box(), StackingContextPaintPhase::FocusAndOverlay);
return TraversalDecision::Continue;
});
// Draw other positioned descendants (step 9)
for (auto* child : m_children) {
if (child->m_box.computed_values().z_index().has_value() && child->m_box.computed_values().z_index().value() < 0)
continue;
paint_child(child);
if (child->m_box.computed_values().z_index().has_value() && child->m_box.computed_values().z_index().value() >= 1)
paint_child(child);
}
paint_node(m_box, context, PaintPhase::FocusOutline);