From c846616d518500fc8cb15ba6e0524f59482fdeee Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 7 May 2025 19:06:57 -0400 Subject: [PATCH] LibWeb: Adjust positions by the scroll offset for scrollbar hit testing This ensures we scroll to the correct position when dragging a scrollbar or clicking its gutter. --- Libraries/LibWeb/Painting/PaintableBox.cpp | 13 +++++++++++-- Libraries/LibWeb/Painting/PaintableBox.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index 658b5c9cfbe..8a5746a17b7 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -911,6 +911,8 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const Paintable::DispatchEventOfSameName PaintableBox::handle_mousedown(Badge, CSSPixelPoint position, unsigned, unsigned) { + position = adjust_position_for_cumulative_scroll_offset(position); + auto handle_scrollbar = [&](auto direction) { auto scrollbar_data = compute_scrollbar_data(direction, AdjustThumbRectForScrollOffset::Yes); if (!scrollbar_data.has_value()) @@ -956,6 +958,8 @@ Paintable::DispatchEventOfSameName PaintableBox::handle_mouseup(Badge, CSSPixelPoint position, unsigned, unsigned) { + position = adjust_position_for_cumulative_scroll_offset(position); + if (m_last_mouse_tracking_position.has_value()) { scroll_to_mouse_postion(position); return Paintable::DispatchEventOfSameName::No; @@ -1060,12 +1064,17 @@ TraversalDecision PaintableBox::hit_test_scrollbars(CSSPixelPoint position, Func return TraversalDecision::Continue; } +CSSPixelPoint PaintableBox::adjust_position_for_cumulative_scroll_offset(CSSPixelPoint position) const +{ + return position.translated(-cumulative_offset_of_enclosing_scroll_frame()); +} + TraversalDecision PaintableBox::hit_test(CSSPixelPoint position, HitTestType type, Function const& callback) const { if (clip_rect_for_hit_testing().has_value() && !clip_rect_for_hit_testing()->contains(position)) return TraversalDecision::Continue; - auto position_adjusted_by_scroll_offset = position.translated(-cumulative_offset_of_enclosing_scroll_frame()); + auto position_adjusted_by_scroll_offset = adjust_position_for_cumulative_scroll_offset(position); if (computed_values().visibility() != CSS::Visibility::Visible) return TraversalDecision::Continue; @@ -1141,7 +1150,7 @@ TraversalDecision PaintableWithLines::hit_test(CSSPixelPoint position, HitTestTy if (clip_rect_for_hit_testing().has_value() && !clip_rect_for_hit_testing()->contains(position)) return TraversalDecision::Continue; - auto position_adjusted_by_scroll_offset = position.translated(-cumulative_offset_of_enclosing_scroll_frame()); + auto position_adjusted_by_scroll_offset = adjust_position_for_cumulative_scroll_offset(position); // TextCursor hit testing mode should be able to place cursor in contenteditable elements even if they are empty if (m_fragments.is_empty() diff --git a/Libraries/LibWeb/Painting/PaintableBox.h b/Libraries/LibWeb/Painting/PaintableBox.h index a21c790ec71..db31fde5604 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Libraries/LibWeb/Painting/PaintableBox.h @@ -274,6 +274,7 @@ protected: [[nodiscard]] bool could_be_scrolled_by_wheel_event(ScrollDirection) const; TraversalDecision hit_test_scrollbars(CSSPixelPoint position, Function const& callback) const; + CSSPixelPoint adjust_position_for_cumulative_scroll_offset(CSSPixelPoint) const; private: [[nodiscard]] virtual bool is_paintable_box() const final { return true; }