1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:47:44 +00:00

LibWeb: Update StackingContext::paint_descendants() for new rule

Since positioned elements no longer automatically create stacking
contexts, we can't rely on this assumption when painting descendants of
a stacking context.

In this commit, we fix an issue that manifested as a failure to
Gfx::Painter::restore() in the "Overlay" paint phase. What happened was
that a CSS clip was being applied in the "Background" paint phase, and
then unapplied in the "Overlay" phase. Due to bogus checks in
paint_descendants(), the "Background" phase never ran for positioned
elements, but the "Overlay" phase did.

The check for positioned elements was bogus in the first place and had
never actually worked before, since we would always skip over positioned
descendants due to them having stacking contexts.
This commit is contained in:
Andreas Kling 2022-10-23 18:15:14 +02:00
parent 055a1998c1
commit 8a0e40c5b0

View file

@ -81,37 +81,31 @@ void StackingContext::paint_descendants(PaintContext& context, Layout::Node cons
bool child_is_inline_or_replaced = child.is_inline() || is<Layout::ReplacedBox>(child);
switch (phase) {
case StackingContextPaintPhase::BackgroundAndBorders:
if (!child_is_inline_or_replaced && !child.is_floating() && !child.is_positioned()) {
if (!child_is_inline_or_replaced && !child.is_floating()) {
paint_node(child, context, PaintPhase::Background);
paint_node(child, context, PaintPhase::Border);
paint_descendants(context, child, phase);
}
break;
case StackingContextPaintPhase::Floats:
if (!child.is_positioned()) {
if (child.is_floating()) {
paint_node(child, context, PaintPhase::Background);
paint_node(child, context, PaintPhase::Border);
paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders);
}
paint_descendants(context, child, phase);
if (child.is_floating()) {
paint_node(child, context, PaintPhase::Background);
paint_node(child, context, PaintPhase::Border);
paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders);
}
paint_descendants(context, child, phase);
break;
case StackingContextPaintPhase::BackgroundAndBordersForInlineLevelAndReplaced:
if (!child.is_positioned()) {
if (child_is_inline_or_replaced) {
paint_node(child, context, PaintPhase::Background);
paint_node(child, context, PaintPhase::Border);
paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders);
}
paint_descendants(context, child, phase);
if (child_is_inline_or_replaced) {
paint_node(child, context, PaintPhase::Background);
paint_node(child, context, PaintPhase::Border);
paint_descendants(context, child, StackingContextPaintPhase::BackgroundAndBorders);
}
paint_descendants(context, child, phase);
break;
case StackingContextPaintPhase::Foreground:
if (!child.is_positioned()) {
paint_node(child, context, PaintPhase::Foreground);
paint_descendants(context, child, phase);
}
paint_node(child, context, PaintPhase::Foreground);
paint_descendants(context, child, phase);
break;
case StackingContextPaintPhase::FocusAndOverlay:
if (context.has_focus()) {