diff --git a/Libraries/LibWeb/Layout/LayoutBlock.cpp b/Libraries/LibWeb/Layout/LayoutBlock.cpp index e1a2b66a30..fb5125a6c5 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.cpp +++ b/Libraries/LibWeb/Layout/LayoutBlock.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -67,10 +68,10 @@ void LayoutBlock::layout(LayoutMode layout_mode) compute_height(); if (layout_mode == LayoutMode::Default) - layout_absolute_descendants(); + layout_absolutely_positioned_descendants(); } -void LayoutBlock::layout_absolute_descendants() +void LayoutBlock::layout_absolutely_positioned_descendants() { for (auto& box : m_absolutely_positioned_descendants) { box->layout(LayoutMode::Default); @@ -441,9 +442,7 @@ void LayoutBlock::compute_width() void LayoutBlock::compute_position() { - // Absolutely positioned blocks are positioned by position_absolute_boxes() if (is_absolutely_positioned()) { - dbg() << "Is abspos, adding to containing block " << containing_block()->node()->tag_name(); const_cast(containing_block())->add_absolutely_positioned_descendant(*this); return; } diff --git a/Libraries/LibWeb/Layout/LayoutBlock.h b/Libraries/LibWeb/Layout/LayoutBlock.h index a55dff6fdb..52e45d5024 100644 --- a/Libraries/LibWeb/Layout/LayoutBlock.h +++ b/Libraries/LibWeb/Layout/LayoutBlock.h @@ -72,7 +72,7 @@ protected: void compute_width(); void compute_position(); void compute_height(); - void layout_absolute_descendants(); + void layout_absolutely_positioned_descendants(); private: virtual bool is_block() const override { return true; } diff --git a/Libraries/LibWeb/Layout/LayoutBox.cpp b/Libraries/LibWeb/Layout/LayoutBox.cpp index 3f6223da30..2f642b437b 100644 --- a/Libraries/LibWeb/Layout/LayoutBox.cpp +++ b/Libraries/LibWeb/Layout/LayoutBox.cpp @@ -194,6 +194,10 @@ void LayoutBox::render(RenderingContext& context) if (!is_visible()) return; + Gfx::PainterStateSaver saver(context.painter()); + if (is_fixed_position()) + context.painter().translate(context.scroll_offset()); + #ifdef DRAW_BOXES_AROUND_LAYOUT_NODES context.painter().draw_rect(m_rect, Color::Blue); #endif diff --git a/Libraries/LibWeb/Layout/LayoutDocument.cpp b/Libraries/LibWeb/Layout/LayoutDocument.cpp index 6bc016940f..646344b054 100644 --- a/Libraries/LibWeb/Layout/LayoutDocument.cpp +++ b/Libraries/LibWeb/Layout/LayoutDocument.cpp @@ -58,7 +58,7 @@ void LayoutDocument::layout(LayoutMode layout_mode) }); set_height(lowest_bottom); - layout_absolute_descendants(); + layout_absolutely_positioned_descendants(); // FIXME: This is a total hack. Make sure any GUI::Widgets are moved into place after layout. // We should stop embedding GUI::Widgets entirely, since that won't work out-of-process. diff --git a/Libraries/LibWeb/Layout/LayoutNode.cpp b/Libraries/LibWeb/Layout/LayoutNode.cpp index b19e064616..95c0ef3105 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.cpp +++ b/Libraries/LibWeb/Layout/LayoutNode.cpp @@ -72,7 +72,9 @@ const LayoutBlock* LayoutNode::containing_block() const if (is_text()) return nearest_block_ancestor(); - if (is_absolutely_positioned()) { + auto position = style().position(); + + if (position == CSS::Position::Absolute) { auto* ancestor = parent(); while (ancestor && !ancestor->can_contain_boxes_with_position_absolute()) ancestor = ancestor->parent(); @@ -81,7 +83,7 @@ const LayoutBlock* LayoutNode::containing_block() const return to(ancestor); } - if (style().position() == CSS::Position::Fixed) + if (position == CSS::Position::Fixed) return &root(); return nearest_block_ancestor(); @@ -189,7 +191,13 @@ Gfx::FloatPoint LayoutNode::box_type_agnostic_position() const bool LayoutNode::is_absolutely_positioned() const { - return style().position() == CSS::Position::Absolute; + auto position = style().position(); + return position == CSS::Position::Absolute || position == CSS::Position::Fixed; +} + +bool LayoutNode::is_fixed_position() const +{ + return style().position() == CSS::Position::Fixed; } } diff --git a/Libraries/LibWeb/Layout/LayoutNode.h b/Libraries/LibWeb/Layout/LayoutNode.h index 2c4357b9bc..4fb6b03076 100644 --- a/Libraries/LibWeb/Layout/LayoutNode.h +++ b/Libraries/LibWeb/Layout/LayoutNode.h @@ -171,6 +171,7 @@ public: virtual void render(RenderingContext&); bool is_absolutely_positioned() const; + bool is_fixed_position() const; const LayoutBlock* containing_block() const; diff --git a/Libraries/LibWeb/PageView.cpp b/Libraries/LibWeb/PageView.cpp index f660940c5e..273ad024b3 100644 --- a/Libraries/LibWeb/PageView.cpp +++ b/Libraries/LibWeb/PageView.cpp @@ -207,7 +207,7 @@ void PageView::paint_event(GUI::PaintEvent& event) painter.translate(frame_thickness(), frame_thickness()); painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value()); - RenderingContext context(painter, palette()); + RenderingContext context(painter, palette(), { horizontal_scrollbar().value(), vertical_scrollbar().value() }); context.set_should_show_line_box_borders(m_should_show_line_box_borders); context.set_viewport_rect(viewport_rect_in_content_coordinates()); layout_root()->render(context); diff --git a/Libraries/LibWeb/RenderingContext.h b/Libraries/LibWeb/RenderingContext.h index 2c6e69c9df..283b634fec 100644 --- a/Libraries/LibWeb/RenderingContext.h +++ b/Libraries/LibWeb/RenderingContext.h @@ -34,9 +34,10 @@ namespace Web { class RenderingContext { public: - explicit RenderingContext(GUI::Painter& painter, const Palette& palette) + explicit RenderingContext(GUI::Painter& painter, const Palette& palette, const Gfx::IntPoint& scroll_offset) : m_painter(painter) , m_palette(palette) + , m_scroll_offset(scroll_offset) { } @@ -49,10 +50,13 @@ public: Gfx::IntRect viewport_rect() const { return m_viewport_rect; } void set_viewport_rect(const Gfx::IntRect& rect) { m_viewport_rect = rect; } + const Gfx::IntPoint& scroll_offset() const { return m_scroll_offset; } + private: GUI::Painter& m_painter; Palette m_palette; Gfx::IntRect m_viewport_rect; + Gfx::IntPoint m_scroll_offset; bool m_should_show_line_box_borders { false }; };