diff --git a/Libraries/LibWeb/Painting/Command.h b/Libraries/LibWeb/Painting/Command.h index cc55a5b0505..d35945ab5ef 100644 --- a/Libraries/LibWeb/Painting/Command.h +++ b/Libraries/LibWeb/Painting/Command.h @@ -403,14 +403,15 @@ struct PaintNestedDisplayList { }; struct PaintScrollBar { - int scroll_frame_id; - Gfx::IntRect rect; + int scroll_frame_id { 0 }; + Gfx::IntRect gutter_rect; + Gfx::IntRect thumb_rect; CSSPixelFraction scroll_size; bool vertical; void translate_by(Gfx::IntPoint const& offset) { - rect.translate_by(offset); + thumb_rect.translate_by(offset); } }; diff --git a/Libraries/LibWeb/Painting/DisplayList.cpp b/Libraries/LibWeb/Painting/DisplayList.cpp index 36ef0073c2f..67f538c4985 100644 --- a/Libraries/LibWeb/Painting/DisplayList.cpp +++ b/Libraries/LibWeb/Painting/DisplayList.cpp @@ -69,10 +69,10 @@ void DisplayListPlayer::execute_impl(DisplayList& display_list, ScrollStateSnaps auto scroll_offset = scroll_state.own_offset_for_frame_with_id(paint_scroll_bar.scroll_frame_id); if (paint_scroll_bar.vertical) { auto offset = scroll_offset.y() * paint_scroll_bar.scroll_size; - paint_scroll_bar.rect.translate_by(0, -offset.to_int() * device_pixels_per_css_pixel); + paint_scroll_bar.thumb_rect.translate_by(0, -offset.to_int() * device_pixels_per_css_pixel); } else { auto offset = scroll_offset.x() * paint_scroll_bar.scroll_size; - paint_scroll_bar.rect.translate_by(-offset.to_int() * device_pixels_per_css_pixel, 0); + paint_scroll_bar.thumb_rect.translate_by(-offset.to_int() * device_pixels_per_css_pixel, 0); } } diff --git a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp index 8b8f5549446..caaf96dbb70 100644 --- a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp +++ b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp @@ -993,16 +993,23 @@ void DisplayListPlayerSkia::paint_nested_display_list(PaintNestedDisplayList con void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command) { - auto rect = to_skia_rect(command.rect); - auto radius = rect.width() / 2; - auto rrect = SkRRect::MakeRectXY(rect, radius, radius); + auto gutter_rect = to_skia_rect(command.gutter_rect); + + auto thumb_rect = to_skia_rect(command.thumb_rect); + auto radius = thumb_rect.width() / 2; + auto thumb_rrect = SkRRect::MakeRectXY(thumb_rect, radius, radius); auto& canvas = surface().canvas(); - auto fill_color = Color(Color::NamedColor::DarkGray).with_alpha(128); - SkPaint fill_paint; - fill_paint.setColor(to_skia_color(fill_color)); - canvas.drawRRect(rrect, fill_paint); + auto gutter_fill_color = Color(Color::NamedColor::WarmGray).with_alpha(192); + SkPaint gutter_fill_paint; + gutter_fill_paint.setColor(to_skia_color(gutter_fill_color)); + canvas.drawRect(gutter_rect, gutter_fill_paint); + + auto thumb_fill_color = Color(Color::NamedColor::DarkGray).with_alpha(gutter_rect.isEmpty() ? 128 : 192); + SkPaint thumb_fill_paint; + thumb_fill_paint.setColor(to_skia_color(thumb_fill_color)); + canvas.drawRRect(thumb_rrect, thumb_fill_paint); auto stroke_color = Color(Color::NamedColor::LightGray).with_alpha(128); SkPaint stroke_paint; @@ -1010,7 +1017,7 @@ void DisplayListPlayerSkia::paint_scrollbar(PaintScrollBar const& command) stroke_paint.setStrokeWidth(1); stroke_paint.setAntiAlias(true); stroke_paint.setColor(to_skia_color(stroke_color)); - canvas.drawRRect(rrect, stroke_paint); + canvas.drawRRect(thumb_rrect, stroke_paint); } void DisplayListPlayerSkia::apply_opacity(ApplyOpacity const& command) diff --git a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp index 48ee97345f0..84c92c85e1f 100644 --- a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp +++ b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp @@ -404,11 +404,12 @@ void DisplayListRecorder::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a .thickness = thickness }); } -void DisplayListRecorder::paint_scrollbar(int scroll_frame_id, Gfx::IntRect rect, CSSPixelFraction scroll_size, bool vertical) +void DisplayListRecorder::paint_scrollbar(int scroll_frame_id, Gfx::IntRect gutter_rect, Gfx::IntRect thumb_rect, CSSPixelFraction scroll_size, bool vertical) { append(PaintScrollBar { .scroll_frame_id = scroll_frame_id, - .rect = rect, + .gutter_rect = gutter_rect, + .thumb_rect = thumb_rect, .scroll_size = scroll_size, .vertical = vertical }); } diff --git a/Libraries/LibWeb/Painting/DisplayListRecorder.h b/Libraries/LibWeb/Painting/DisplayListRecorder.h index 5689eb9d038..f7c8c029e0d 100644 --- a/Libraries/LibWeb/Painting/DisplayListRecorder.h +++ b/Libraries/LibWeb/Painting/DisplayListRecorder.h @@ -146,7 +146,7 @@ public: void draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2, Color color, int amplitude, int thickness); - void paint_scrollbar(int scroll_frame_id, Gfx::IntRect, CSSPixelFraction scroll_size, bool vertical); + void paint_scrollbar(int scroll_frame_id, Gfx::IntRect gutter_rect, Gfx::IntRect thumb_rect, CSSPixelFraction scroll_size, bool vertical); void apply_opacity(float opacity); void apply_compositing_and_blending_operator(Gfx::CompositingAndBlendingOperator compositing_and_blending_operator); diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index 864beb73e34..a362e950524 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -414,16 +414,22 @@ Optional PaintableBox::compute_scrollbar_data(Scrol auto min_thumb_length = min(scrollbar_rect_length, 24); auto thumb_length = max(scrollbar_rect_length * (scrollport_size / scroll_overflow_size), min_thumb_length); - CSSPixelFraction scroll_size = 0; - if (scroll_overflow_size > scrollport_size) - scroll_size = (scrollbar_rect_length - thumb_length) / (scroll_overflow_size - scrollport_size); - CSSPixelRect rect; - if (is_horizontal) - rect = { padding_rect.left(), padding_rect.bottom() - thickness, thumb_length, thickness }; - else - rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, thumb_length }; + ScrollbarData scrollbar_data; - return PaintableBox::ScrollbarData { rect, scroll_size }; + if (scroll_overflow_size > scrollport_size) + scrollbar_data.scroll_length = (scrollbar_rect_length - thumb_length) / (scroll_overflow_size - scrollport_size); + + if (is_horizontal) { + if (m_draw_enlarged_horizontal_scrollbar) + scrollbar_data.gutter_rect = { padding_rect.left(), padding_rect.bottom() - thickness, padding_rect.width(), thickness }; + scrollbar_data.thumb_rect = { padding_rect.left(), padding_rect.bottom() - thickness, thumb_length, thickness }; + } else { + if (m_draw_enlarged_vertical_scrollbar) + scrollbar_data.gutter_rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, padding_rect.height() }; + scrollbar_data.thumb_rect = { padding_rect.right() - thickness, padding_rect.top(), thickness, thumb_length }; + } + + return scrollbar_data; } void PaintableBox::paint(PaintContext& context, PaintPhase phase) const @@ -473,15 +479,17 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const } } - if (g_paint_viewport_scrollbars || !is_viewport()) { - auto scrollbar_width = computed_values().scrollbar_width(); - if (phase == PaintPhase::Overlay && scrollbar_width != CSS::ScrollbarWidth::None) { - if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Vertical); scrollbar_data.has_value()) { - context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), context.rounded_device_rect(scrollbar_data->thumb_rect).to_type(), scrollbar_data->scroll_length, true); - } - if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Horizontal); scrollbar_data.has_value()) { - context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), context.rounded_device_rect(scrollbar_data->thumb_rect).to_type(), scrollbar_data->scroll_length, false); - } + if (phase == PaintPhase::Overlay && (g_paint_viewport_scrollbars || !is_viewport()) && computed_values().scrollbar_width() != CSS::ScrollbarWidth::None) { + if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Vertical); scrollbar_data.has_value()) { + auto gutter_rect = context.rounded_device_rect(scrollbar_data->gutter_rect).to_type(); + auto thumb_rect = context.rounded_device_rect(scrollbar_data->thumb_rect).to_type(); + context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), gutter_rect, thumb_rect, scrollbar_data->scroll_length, true); + } + + if (auto scrollbar_data = compute_scrollbar_data(ScrollDirection::Horizontal); scrollbar_data.has_value()) { + auto gutter_rect = context.rounded_device_rect(scrollbar_data->gutter_rect).to_type(); + auto thumb_rect = context.rounded_device_rect(scrollbar_data->thumb_rect).to_type(); + context.display_list_recorder().paint_scrollbar(own_scroll_frame_id().value(), gutter_rect, thumb_rect, scrollbar_data->scroll_length, false); } } diff --git a/Libraries/LibWeb/Painting/PaintableBox.h b/Libraries/LibWeb/Painting/PaintableBox.h index 11c589b259e..7145ffd8e79 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Libraries/LibWeb/Painting/PaintableBox.h @@ -258,8 +258,9 @@ protected: virtual CSSPixelRect compute_absolute_paint_rect() const; struct ScrollbarData { + CSSPixelRect gutter_rect; CSSPixelRect thumb_rect; - CSSPixelFraction scroll_length; + CSSPixelFraction scroll_length { 0 }; }; enum class ScrollDirection { Horizontal,