diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
index b81996d7a63..4f5d630dac4 100644
--- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp
@@ -2012,8 +2012,11 @@ void Navigable::perform_scroll_of_viewport(CSSPixelPoint new_position)
scroll_offset_did_change();
set_needs_display();
- if (auto document = active_document())
+ if (auto document = active_document()) {
+ document->set_needs_to_refresh_scroll_state(true);
+ document->set_needs_to_refresh_clip_state(true);
document->inform_all_viewport_clients_about_the_current_viewport_rect();
+ }
}
// Schedule the HTML event loop to ensure that a `resize` event gets fired.
diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
index 189b9a0a7a9..f9c944404d7 100644
--- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp
+++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp
@@ -166,8 +166,7 @@ bool EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSSPixelPo
if (!m_navigable->active_document()->is_fully_active())
return false;
- auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
- auto position = viewport_position.translated(scroll_offset);
+ auto position = viewport_position;
m_navigable->active_document()->update_layout();
@@ -232,8 +231,7 @@ bool EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPixelPoint
if (!m_navigable->active_document()->is_fully_active())
return false;
- auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
- auto position = viewport_position.translated(scroll_offset);
+ auto position = viewport_position;
m_navigable->active_document()->update_layout();
@@ -359,8 +357,7 @@ bool EventHandler::handle_mousedown(CSSPixelPoint viewport_position, CSSPixelPoi
if (!m_navigable->active_document()->is_fully_active())
return false;
- auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
- auto position = viewport_position.translated(scroll_offset);
+ auto position = viewport_position;
m_navigable->active_document()->update_layout();
@@ -467,8 +464,7 @@ bool EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSPixelPoi
if (!m_navigable->active_document()->is_fully_active())
return false;
- auto scroll_offset = m_navigable->active_document()->navigable()->viewport_scroll_offset();
- auto position = viewport_position.translated(scroll_offset);
+ auto position = viewport_position;
m_navigable->active_document()->update_layout();
diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
index f21e1e39464..3e7cc968ea4 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
+++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
@@ -294,9 +294,6 @@ Optional PaintableBox::scroll_thumb_rect(ScrollDirection direction
};
}
- if (is_viewport())
- thumb_rect.translate_by(this->scroll_offset());
-
return thumb_rect;
}
@@ -751,14 +748,10 @@ Paintable::DispatchEventOfSameName PaintableBox::handle_mousedown(Badge(*navigable()).event_handler().set_mouse_event_tracking_paintable(this);
} else if (horizontal_scroll_thumb_rect.has_value() && horizontal_scroll_thumb_rect.value().contains(position)) {
- if (is_viewport())
- position.translate_by(-scroll_offset());
m_last_mouse_tracking_position = position;
m_scroll_thumb_dragging_direction = ScrollDirection::Horizontal;
const_cast(*navigable()).event_handler().set_mouse_event_tracking_paintable(this);
@@ -779,9 +772,6 @@ Paintable::DispatchEventOfSameName PaintableBox::handle_mouseup(Badge, CSSPixelPoint position, unsigned, unsigned)
{
if (m_last_mouse_tracking_position.has_value()) {
- if (is_viewport())
- position.translate_by(-scroll_offset());
-
Gfx::Point scroll_delta;
if (m_scroll_thumb_dragging_direction == ScrollDirection::Horizontal)
scroll_delta.set_x((position.x() - m_last_mouse_tracking_position->x()).to_double());
diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
index f47904cd78f..22998250060 100644
--- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
+++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
@@ -345,11 +345,6 @@ TraversalDecision StackingContext::hit_test(CSSPixelPoint position, HitTestType
};
auto transformed_position = affine_transform_matrix().inverse().value_or({}).map(offset_position).to_type() + transform_origin;
- if (paintable().is_fixed_position()) {
- auto scroll_offset = paintable().document().navigable()->viewport_scroll_offset();
- transformed_position.translate_by(-scroll_offset);
- }
-
// NOTE: Hit testing basically happens in reverse painting order.
// https://www.w3.org/TR/CSS22/visuren.html#z-index
diff --git a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp
index cc0be41a4cd..4a312f53e3e 100644
--- a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp
@@ -61,13 +61,16 @@ void ViewportPaintable::build_stacking_context_tree()
void ViewportPaintable::paint_all_phases(PaintContext& context)
{
build_stacking_context_tree_if_needed();
- context.display_list_recorder().translate(-context.device_viewport_rect().location().to_type());
stacking_context()->paint(context);
}
void ViewportPaintable::assign_scroll_frames()
{
- int next_id = 0;
+ auto viewport_scroll_frame = adopt_ref(*new ScrollFrame());
+ viewport_scroll_frame->id = 0;
+ scroll_state.set(this, move(viewport_scroll_frame));
+
+ int next_id = 1;
for_each_in_subtree_of_type([&](auto const& paintable_box) {
if (paintable_box.has_scrollable_overflow()) {
auto scroll_frame = adopt_ref(*new ScrollFrame());
@@ -78,7 +81,10 @@ void ViewportPaintable::assign_scroll_frames()
});
for_each_in_subtree([&](auto const& paintable) {
- for (auto block = paintable.containing_block(); !block->is_viewport(); block = block->containing_block()) {
+ if (paintable.is_fixed_position()) {
+ return TraversalDecision::Continue;
+ }
+ for (auto block = paintable.containing_block(); block; block = block->containing_block()) {
if (auto scroll_frame = scroll_state.get(block); scroll_frame.has_value()) {
if (paintable.is_paintable_box()) {
auto const& paintable_box = static_cast(paintable);
@@ -87,10 +93,13 @@ void ViewportPaintable::assign_scroll_frames()
auto const& inline_paintable = static_cast(paintable);
const_cast(inline_paintable).set_enclosing_scroll_frame(scroll_frame.value());
}
- break;
+ return TraversalDecision::Continue;
+ }
+ if (block->is_fixed_position()) {
+ return TraversalDecision::Continue;
}
}
- return TraversalDecision::Continue;
+ VERIFY_NOT_REACHED();
});
}
@@ -137,9 +146,11 @@ void ViewportPaintable::refresh_scroll_state()
auto const& paintable_box = *it.key;
auto& scroll_frame = *it.value;
CSSPixelPoint offset;
- for (auto const* block = &paintable_box.layout_box(); !block->is_viewport(); block = block->containing_block()) {
+ for (auto const* block = &paintable_box.layout_box(); block; block = block->containing_block()) {
auto const& block_paintable_box = *block->paintable_box();
offset.translate_by(block_paintable_box.scroll_offset());
+ if (block->is_fixed_position())
+ break;
}
scroll_frame.offset = -offset;
}