From 8a0e40c5b0c39f4c03ec3f5fe432b2bfa02c9f12 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 23 Oct 2022 18:15:14 +0200 Subject: [PATCH] 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. --- .../LibWeb/Painting/StackingContext.cpp | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index ce8f51501b..d28929c41e 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -81,37 +81,31 @@ void StackingContext::paint_descendants(PaintContext& context, Layout::Node cons bool child_is_inline_or_replaced = child.is_inline() || is(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()) {