LibWeb: Move adjustmust of scrollbar offset into compute_scrollbar_data

Currently, compute_scrollbar_data does not adjust the position of the
scrollbar thumb based on the actual scroll offset. This is because we
perform this offset in most cases inside the display list executor, in
order to allow us to avoid recomputing the display list.

However, there are cases where we do want the thumb rect with an offset
inside PaintableBox. We currently use scroll_thumb_rect to perform that
computation.

In an upcoming patch, we will need both this offset thumb rect and the
scrollbar gutter rect. So this patch moves the computation of the offset
to compute_scrollbar_data, performed behind an optional parameter.
This commit is contained in:
Timothy Flynn 2025-04-21 10:15:13 -04:00 committed by Tim Flynn
commit a135ce528e
Notes: github-actions[bot] 2025-04-22 15:30:08 +00:00
2 changed files with 24 additions and 27 deletions

View file

@ -310,9 +310,9 @@ Optional<CSSPixelRect> PaintableBox::get_clip_rect() const
bool PaintableBox::wants_mouse_events() const
{
if (scroll_thumb_rect(ScrollDirection::Vertical).has_value())
if (compute_scrollbar_data(ScrollDirection::Vertical).has_value())
return true;
if (scroll_thumb_rect(ScrollDirection::Horizontal).has_value())
if (compute_scrollbar_data(ScrollDirection::Horizontal).has_value())
return true;
return false;
}
@ -361,25 +361,7 @@ bool PaintableBox::could_be_scrolled_by_wheel_event() const
static constexpr CSSPixels SCROLLBAR_THUMB_NORMAL_THICKNESS = 5;
static constexpr CSSPixels SCROLLBAR_THUMB_WIDENED_THICKNESS = 10;
Optional<CSSPixelRect> PaintableBox::scroll_thumb_rect(ScrollDirection direction) const
{
auto maybe_scrollbar_data = compute_scrollbar_data(direction);
if (!maybe_scrollbar_data.has_value())
return {};
auto scroll_offset = direction == ScrollDirection::Horizontal ? -own_scroll_frame_offset().x() : -own_scroll_frame_offset().y();
auto thumb_offset = scroll_offset * maybe_scrollbar_data->scroll_length;
CSSPixelRect thumb_rect = maybe_scrollbar_data->thumb_rect;
if (direction == ScrollDirection::Horizontal) {
thumb_rect.translate_by(thumb_offset, 0);
} else {
thumb_rect.translate_by(0, thumb_offset);
}
return thumb_rect;
}
Optional<PaintableBox::ScrollbarData> PaintableBox::compute_scrollbar_data(ScrollDirection direction) const
Optional<PaintableBox::ScrollbarData> PaintableBox::compute_scrollbar_data(ScrollDirection direction, AdjustThumbRectForScrollOffset adjust_thumb_rect_for_scroll_offset) const
{
bool is_horizontal = direction == ScrollDirection::Horizontal;
bool display_scrollbar = could_be_scrolled_by_wheel_event(direction);
@ -429,6 +411,16 @@ Optional<PaintableBox::ScrollbarData> PaintableBox::compute_scrollbar_data(Scrol
scrollbar_data.thumb_rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, thumb_length };
}
if (adjust_thumb_rect_for_scroll_offset == AdjustThumbRectForScrollOffset::Yes) {
auto scroll_offset = is_horizontal ? -own_scroll_frame_offset().x() : -own_scroll_frame_offset().y();
auto thumb_offset = scroll_offset * scrollbar_data.scroll_length;
if (is_horizontal)
scrollbar_data.thumb_rect.translate_by(thumb_offset, 0);
else
scrollbar_data.thumb_rect.translate_by(0, thumb_offset);
}
return scrollbar_data;
}
@ -920,17 +912,19 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
Paintable::DispatchEventOfSameName PaintableBox::handle_mousedown(Badge<EventHandler>, CSSPixelPoint position, unsigned, unsigned)
{
auto vertical_scroll_thumb_rect = scroll_thumb_rect(ScrollDirection::Vertical);
auto horizontal_scroll_thumb_rect = scroll_thumb_rect(ScrollDirection::Horizontal);
if (vertical_scroll_thumb_rect.has_value() && vertical_scroll_thumb_rect.value().contains(position)) {
auto vertical_scroll_data = compute_scrollbar_data(ScrollDirection::Vertical, AdjustThumbRectForScrollOffset::Yes);
auto horizontal_scroll_data = compute_scrollbar_data(ScrollDirection::Horizontal, AdjustThumbRectForScrollOffset::Yes);
if (vertical_scroll_data.has_value() && vertical_scroll_data->thumb_rect.contains(position)) {
m_last_mouse_tracking_position = position;
m_scroll_thumb_dragging_direction = ScrollDirection::Vertical;
const_cast<HTML::Navigable&>(*navigable()).event_handler().set_mouse_event_tracking_paintable(this);
} else if (horizontal_scroll_thumb_rect.has_value() && horizontal_scroll_thumb_rect.value().contains(position)) {
} else if (horizontal_scroll_data.has_value() && horizontal_scroll_data->thumb_rect.contains(position)) {
m_last_mouse_tracking_position = position;
m_scroll_thumb_dragging_direction = ScrollDirection::Horizontal;
const_cast<HTML::Navigable&>(*navigable()).event_handler().set_mouse_event_tracking_paintable(this);
}
return Paintable::DispatchEventOfSameName::Yes;
}

View file

@ -266,8 +266,11 @@ protected:
Horizontal,
Vertical,
};
Optional<ScrollbarData> compute_scrollbar_data(ScrollDirection) const;
[[nodiscard]] Optional<CSSPixelRect> scroll_thumb_rect(ScrollDirection) const;
enum class AdjustThumbRectForScrollOffset {
No,
Yes,
};
Optional<ScrollbarData> compute_scrollbar_data(ScrollDirection, AdjustThumbRectForScrollOffset = AdjustThumbRectForScrollOffset::No) const;
[[nodiscard]] bool could_be_scrolled_by_wheel_event(ScrollDirection) const;
TraversalDecision hit_test_scrollbars(CSSPixelPoint position, Function<TraversalDecision(HitTestResult)> const& callback) const;