From 90b66533d02ba1ee77140b2c89a6d6112dc6987d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 7 Oct 2022 11:51:56 +0200 Subject: [PATCH] LibWeb: Don't hit test all child stacking contexts twice We're supposed to hit test positive z-index stacking contexts first, and negative z-index stacking contexts later. Instead, we were hit testing all stacking contexts both times. This made hit testing unbearably slow on some websites. While we're here, also add an extra comment about why stacking contexts are traversed in reverse order. It tripped me up while looking at this, so I'm sure it could trip someone else up too. Regressed in 44057c94821ea5dbfa2747de7cd4053fd5fe0742. --- Userland/Libraries/LibWeb/Painting/StackingContext.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp index 48367aca63..60b84e43d0 100644 --- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp @@ -369,8 +369,6 @@ Optional StackingContext::hit_test(Gfx::FloatPoint const& positio { if (!m_box.is_visible()) return {}; - if (m_box.computed_values().z_index().value_or(0) < 0) - return {}; auto transform_origin = this->transform_origin(); auto transformed_position = affine_transform_matrix().inverse().value_or({}).map(position - transform_origin) + transform_origin; @@ -385,8 +383,11 @@ Optional StackingContext::hit_test(Gfx::FloatPoint const& positio // https://www.w3.org/TR/CSS22/visuren.html#z-index // 7. the child stacking contexts with positive stack levels (least positive first). + // NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed. for (ssize_t i = m_children.size() - 1; i >= 0; --i) { auto const& child = *m_children[i]; + if (child.m_box.computed_values().z_index().value_or(0) < 0) + break; auto result = child.hit_test(transformed_position, type); if (result.has_value()) return result; @@ -457,8 +458,11 @@ Optional StackingContext::hit_test(Gfx::FloatPoint const& positio } // 2. the child stacking contexts with negative stack levels (most negative first). + // NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed. for (ssize_t i = m_children.size() - 1; i >= 0; --i) { auto const& child = *m_children[i]; + if (child.m_box.computed_values().z_index().value_or(0) >= 0) + break; auto result = child.hit_test(transformed_position, type); if (result.has_value()) return result;