From 450792018744299782c59ce400c9e03a7c361aeb Mon Sep 17 00:00:00 2001 From: MacDue Date: Mon, 10 Oct 2022 21:28:57 +0100 Subject: [PATCH] LibWeb: Fix position: fixed canvases/images disappearing when scrolling This fixes the Serenity logo vanishing after scrolling on the 4th birthday post. The previous check did not account for any translation in the painter. This now uses the painter's clip rect and translation to work out if a rect is visible. It also makes use of `absolute_paint_rect()` rather than `absolute_rect()` which can account for things like box-shadows. --- Userland/Libraries/LibWeb/Painting/CanvasPaintable.cpp | 4 ++-- Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp | 4 ++-- Userland/Libraries/LibWeb/Painting/PaintableBox.cpp | 7 +++++++ Userland/Libraries/LibWeb/Painting/PaintableBox.h | 2 ++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/Painting/CanvasPaintable.cpp b/Userland/Libraries/LibWeb/Painting/CanvasPaintable.cpp index 8e7977f501..82253eaa09 100644 --- a/Userland/Libraries/LibWeb/Painting/CanvasPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/CanvasPaintable.cpp @@ -34,8 +34,8 @@ void CanvasPaintable::paint(PaintContext& context, PaintPhase phase) const auto canvas_rect = absolute_rect().to_rounded(); ScopedCornerRadiusClip corner_clip { context.painter(), canvas_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) }; - // FIXME: This should be done at a different level. Also rect() does not include padding etc! - if (!context.viewport_rect().intersects(canvas_rect)) + // FIXME: This should be done at a different level. + if (is_out_of_view(context)) return; if (layout_box().dom_node().bitmap()) { diff --git a/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp b/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp index 31572e2807..3e46cc1cf5 100644 --- a/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/ImagePaintable.cpp @@ -33,8 +33,8 @@ void ImagePaintable::paint(PaintContext& context, PaintPhase phase) const if (!is_visible()) return; - // FIXME: This should be done at a different level. Also rect() does not include padding etc! - if (!context.viewport_rect().intersects(enclosing_int_rect(absolute_rect()))) + // FIXME: This should be done at a different level. + if (is_out_of_view(context)) return; PaintableBox::paint(context, phase); diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index c420cb485f..34d56620a0 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -37,6 +37,13 @@ void PaintableBox::invalidate_stacking_context() m_stacking_context = nullptr; } +bool PaintableBox::is_out_of_view(PaintContext& context) const +{ + return !enclosing_int_rect(absolute_paint_rect()) + .translated(context.painter().translation()) + .intersects(context.painter().clip_rect()); +} + PaintableWithLines::PaintableWithLines(Layout::BlockContainer const& layout_box) : PaintableBox(layout_box) { diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.h b/Userland/Libraries/LibWeb/Painting/PaintableBox.h index 0aeb132cf5..603f9ff7b3 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.h @@ -117,6 +117,8 @@ public: void invalidate_stacking_context(); + bool is_out_of_view(PaintContext&) const; + protected: explicit PaintableBox(Layout::Box const&);