Skip to content

Commit

Permalink
LibWeb: Move page scrollbar painting into WebContent
Browse files Browse the repository at this point in the history
  • Loading branch information
kalenikaliaksandr committed Jun 2, 2024
1 parent 29bc40b commit 92882a3
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 126 deletions.
16 changes: 0 additions & 16 deletions Ladybird/AppKit/UI/LadybirdWebView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -335,22 +335,6 @@ - (void)setWebViewCallbacks
self.event_being_redispatched = nil;
};

m_web_view_bridge->on_scroll = [self](auto position) {
auto content_rect = [self frame];
auto document_rect = [[self documentView] frame];
auto ns_position = Ladybird::gfx_point_to_ns_point(position);

ns_position.x = max(ns_position.x, document_rect.origin.x);
ns_position.x = min(ns_position.x, document_rect.size.width - content_rect.size.width);

ns_position.y = max(ns_position.y, document_rect.origin.y);
ns_position.y = min(ns_position.y, document_rect.size.height - content_rect.size.height);

[self scrollToPoint:ns_position];
[[self scrollView] reflectScrolledClipView:self];
[self updateViewportRect:Ladybird::WebViewBridge::ForResize::No];
};

m_web_view_bridge->on_cursor_change = [self](auto cursor) {
if (cursor == Gfx::StandardCursor::Hidden) {
if (!m_hidden_cursor.has_value()) {
Expand Down
22 changes: 4 additions & 18 deletions Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,6 @@ WebViewBridge::WebViewBridge(Vector<Web::DevicePixelRect> screen_rects, float de
, m_preferred_color_scheme(preferred_color_scheme)
{
m_device_pixel_ratio = device_pixel_ratio;

on_scroll_by_delta = [this](auto x_delta, auto y_delta) {
auto position = m_viewport_rect.location();
position.set_x(position.x() + x_delta);
position.set_y(position.y() + y_delta);

if (on_scroll_to_point)
on_scroll_to_point(position);
};

on_scroll_to_point = [this](auto position) {
if (on_scroll)
on_scroll(to_widget_position(position));
};
}

WebViewBridge::~WebViewBridge() = default;
Expand All @@ -67,9 +53,9 @@ void WebViewBridge::set_system_visibility_state(bool is_visible)
void WebViewBridge::set_viewport_rect(Gfx::IntRect viewport_rect, ForResize for_resize)
{
viewport_rect.set_size(scale_for_device(viewport_rect.size(), m_device_pixel_ratio));
m_viewport_rect = viewport_rect;
m_viewport_size = viewport_rect.size();

client().async_set_viewport_rect(m_client_state.page_index, m_viewport_rect.to_type<Web::DevicePixels>());
client().async_set_viewport_rect(m_client_state.page_index, { { 0, 0 }, m_viewport_size.to_type<Web::DevicePixels>() });

if (for_resize == ForResize::Yes) {
handle_resize();
Expand Down Expand Up @@ -126,9 +112,9 @@ void WebViewBridge::update_zoom()
on_zoom_level_changed();
}

Web::DevicePixelRect WebViewBridge::viewport_rect() const
Web::DevicePixelSize WebViewBridge::viewport_size() const
{
return m_viewport_rect.to_type<Web::DevicePixels>();
return m_viewport_size.to_type<Web::DevicePixels>();
}

Gfx::IntPoint WebViewBridge::to_content_position(Gfx::IntPoint widget_position) const
Expand Down
5 changes: 2 additions & 3 deletions Ladybird/AppKit/UI/LadybirdWebViewBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,17 @@ class WebViewBridge final : public WebView::ViewImplementation {

Function<NonnullRefPtr<WebView::WebContentClient>()> on_request_web_content;
Function<void()> on_zoom_level_changed;
Function<void(Gfx::IntPoint)> on_scroll;

private:
WebViewBridge(Vector<Web::DevicePixelRect> screen_rects, float device_pixel_ratio, WebContentOptions const&, Optional<StringView> webdriver_content_ipc_path, Web::CSS::PreferredColorScheme);

virtual void update_zoom() override;
virtual Web::DevicePixelRect viewport_rect() const override;
virtual Web::DevicePixelSize viewport_size() const override;
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const override;
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint content_position) const override;

Vector<Web::DevicePixelRect> m_screen_rects;
Gfx::IntRect m_viewport_rect;
Gfx::IntSize m_viewport_size;

WebContentOptions m_web_content_options;
Optional<StringView> m_webdriver_content_ipc_path;
Expand Down
53 changes: 15 additions & 38 deletions Ladybird/Qt/WebContentView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con
, m_web_content_options(web_content_options)
, m_webdriver_content_ipc_path(webdriver_content_ipc_path)
{
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

m_client_state.client = parent_client;
m_client_state.page_index = page_index;

Expand All @@ -67,13 +70,6 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con
verticalScrollBar()->setSingleStep(24);
horizontalScrollBar()->setSingleStep(24);

QObject::connect(verticalScrollBar(), &QScrollBar::valueChanged, [this](int) {
update_viewport_rect();
});
QObject::connect(horizontalScrollBar(), &QScrollBar::valueChanged, [this](int) {
update_viewport_rect();
});

QObject::connect(qGuiApp, &QGuiApplication::screenRemoved, [this](QScreen*) {
update_screen_rects();
});
Expand All @@ -84,29 +80,10 @@ WebContentView::WebContentView(QWidget* window, WebContentOptions const& web_con

initialize_client((parent_client == nullptr) ? CreateNewClient::Yes : CreateNewClient::No);

on_did_layout = [this](auto content_size) {
verticalScrollBar()->setMinimum(0);
verticalScrollBar()->setMaximum(content_size.height() - m_viewport_rect.height());
verticalScrollBar()->setPageStep(m_viewport_rect.height());
horizontalScrollBar()->setMinimum(0);
horizontalScrollBar()->setMaximum(content_size.width() - m_viewport_rect.width());
horizontalScrollBar()->setPageStep(m_viewport_rect.width());
};

on_ready_to_paint = [this]() {
viewport()->update();
};

on_scroll_by_delta = [this](auto x_delta, auto y_delta) {
horizontalScrollBar()->setValue(max(0, horizontalScrollBar()->value() + x_delta));
verticalScrollBar()->setValue(max(0, verticalScrollBar()->value() + y_delta));
};

on_scroll_to_point = [this](auto position) {
horizontalScrollBar()->setValue(position.x());
verticalScrollBar()->setValue(position.y());
};

on_cursor_change = [this](auto cursor) {
update_cursor(cursor);
};
Expand Down Expand Up @@ -444,13 +421,13 @@ void WebContentView::paintEvent(QPaintEvent*)
void WebContentView::resizeEvent(QResizeEvent* event)
{
QAbstractScrollArea::resizeEvent(event);
update_viewport_rect();
update_viewport_size();
handle_resize();
}

void WebContentView::set_viewport_rect(Gfx::IntRect rect)
{
m_viewport_rect = rect;
m_viewport_size = rect.size();
client().async_set_viewport_rect(m_client_state.page_index, rect.to_type<Web::DevicePixels>());
}

Expand All @@ -468,23 +445,23 @@ void WebContentView::set_device_pixel_ratio(double device_pixel_ratio)
{
m_device_pixel_ratio = device_pixel_ratio;
client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio * m_zoom_level);
update_viewport_rect();
update_viewport_size();
handle_resize();
}

void WebContentView::update_viewport_rect()
void WebContentView::update_viewport_size()
{
auto scaled_width = int(viewport()->width() * m_device_pixel_ratio);
auto scaled_height = int(viewport()->height() * m_device_pixel_ratio);
Gfx::IntRect rect(max(0, horizontalScrollBar()->value()), max(0, verticalScrollBar()->value()), scaled_width, scaled_height);
Gfx::IntRect rect(0, 0, scaled_width, scaled_height);

set_viewport_rect(rect);
}

void WebContentView::update_zoom()
{
client().async_set_device_pixels_per_css_pixel(m_client_state.page_index, m_device_pixel_ratio * m_zoom_level);
update_viewport_rect();
update_viewport_size();
}

void WebContentView::showEvent(QShowEvent* event)
Expand Down Expand Up @@ -661,9 +638,9 @@ void WebContentView::update_cursor(Gfx::StandardCursor cursor)
}
}

Web::DevicePixelRect WebContentView::viewport_rect() const
Web::DevicePixelSize WebContentView::viewport_size() const
{
return m_viewport_rect.to_type<Web::DevicePixels>();
return m_viewport_size.to_type<Web::DevicePixels>();
}

QPoint WebContentView::map_point_to_global_position(Gfx::IntPoint position) const
Expand All @@ -673,12 +650,12 @@ QPoint WebContentView::map_point_to_global_position(Gfx::IntPoint position) cons

Gfx::IntPoint WebContentView::to_content_position(Gfx::IntPoint widget_position) const
{
return widget_position.translated(max(0, horizontalScrollBar()->value()), max(0, verticalScrollBar()->value()));
return widget_position;
}

Gfx::IntPoint WebContentView::to_widget_position(Gfx::IntPoint content_position) const
{
return content_position.translated(-(max(0, horizontalScrollBar()->value())), -(max(0, verticalScrollBar()->value())));
return content_position;
}

bool WebContentView::event(QEvent* event)
Expand Down Expand Up @@ -715,7 +692,7 @@ ErrorOr<String> WebContentView::dump_layout_tree()

void WebContentView::enqueue_native_event(Web::MouseEvent::Type type, QSinglePointEvent const& event)
{
auto position = to_content_position({ event.position().x() * m_device_pixel_ratio, event.position().y() * m_device_pixel_ratio });
Web::DevicePixelPoint position = { event.position().x() * m_device_pixel_ratio, event.position().y() * m_device_pixel_ratio };
auto screen_position = Gfx::IntPoint { event.globalPosition().x() * m_device_pixel_ratio, event.globalPosition().y() * m_device_pixel_ratio };

auto button = get_button_from_qt_event(event);
Expand Down Expand Up @@ -751,7 +728,7 @@ void WebContentView::enqueue_native_event(Web::MouseEvent::Type type, QSinglePoi
}
}

enqueue_input_event(Web::MouseEvent { type, position.to_type<Web::DevicePixels>(), screen_position.to_type<Web::DevicePixels>(), button, buttons, modifiers, wheel_delta_x, wheel_delta_y, nullptr });
enqueue_input_event(Web::MouseEvent { type, position, screen_position.to_type<Web::DevicePixels>(), button, buttons, modifiers, wheel_delta_x, wheel_delta_y, nullptr });
}

struct KeyData : Web::ChromeInputData {
Expand Down
6 changes: 3 additions & 3 deletions Ladybird/Qt/WebContentView.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ class WebContentView final
// ^WebView::ViewImplementation
virtual void initialize_client(CreateNewClient) override;
virtual void update_zoom() override;
virtual Web::DevicePixelRect viewport_rect() const override;
virtual Web::DevicePixelSize viewport_size() const override;
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const override;
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint content_position) const override;

void update_viewport_rect();
void update_viewport_size();
void update_cursor(Gfx::StandardCursor cursor);

void enqueue_native_event(Web::MouseEvent::Type, QSinglePointEvent const& event);
Expand All @@ -104,7 +104,7 @@ class WebContentView final

bool m_should_show_line_box_borders { false };

Gfx::IntRect m_viewport_rect;
Gfx::IntSize m_viewport_size;

WebContentOptions m_web_content_options;
StringView m_webdriver_content_ipc_path;
Expand Down
4 changes: 4 additions & 0 deletions Tests/LibWeb/Ref/css-background-clip-text.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
<title>Document</title>

<style>
html {
scrollbar-width: none;
}

p, .container {
border: 0.8em darkviolet;
border-style: dotted double;
Expand Down
3 changes: 3 additions & 0 deletions Tests/LibWeb/Ref/reference/css-background-clip-text-ref.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
body {
background-color: white;
}
html {
scrollbar-width: none;
}
</style>
<!-- To rebase:
1. Open background-clip-text.html in Ladybird
Expand Down
5 changes: 4 additions & 1 deletion Tests/LibWeb/Ref/scroll-iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
<script>
const iframe = document.createElement("iframe");
iframe.srcdoc = `
<style>body { margin: 0 }</style>
<style>
body { margin: 0 }
html { scrollbar-width: none; }
</style>
<div style="width: 200px; height: 200px; background-color: darkblue"></div>
<div style="width: 200px; height: 200px; background-color: blue"></div>
<div style="width: 200px; height: 200px; background-color: magenta"></div>
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/DOM/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const

if (auto const* paintable_box = this->paintable_box()) {
transform = Gfx::extract_2d_affine_transform(paintable_box->transform());
for (auto const* containing_block = paintable->containing_block(); containing_block; containing_block = containing_block->containing_block()) {
for (auto const* containing_block = paintable->containing_block(); !containing_block->layout_node().is_viewport(); containing_block = containing_block->containing_block()) {
transform = Gfx::extract_2d_affine_transform(containing_block->transform()).multiply(transform);
scroll_offset.translate_by(containing_block->scroll_offset());
}
Expand Down
37 changes: 28 additions & 9 deletions Userland/Libraries/LibWeb/HTML/Navigable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2012,8 +2012,19 @@ void Navigable::set_viewport_rect(CSSPixelRect const& rect)
m_needs_repaint = true;
}

if (m_viewport_scroll_offset != rect.location()) {
m_viewport_scroll_offset = rect.location();
auto new_scroll_offset = m_viewport_scroll_offset;
auto document = active_document();
if (document) {
auto x = new_scroll_offset.x();
auto y = new_scroll_offset.y();
auto scrolling_area = document->paintable_box()->scrollable_overflow_rect().value();
x = max(CSSPixels(0), min(x, scrolling_area.width() - m_size.width()));
y = max(CSSPixels(0), min(y, scrolling_area.height() - m_size.height()));
new_scroll_offset = { x, y };
}

if (m_viewport_scroll_offset != new_scroll_offset) {
m_viewport_scroll_offset = new_scroll_offset;
scroll_offset_did_change();
did_change = true;
m_needs_repaint = true;
Expand All @@ -2027,15 +2038,23 @@ void Navigable::set_viewport_rect(CSSPixelRect const& rect)
HTML::main_thread_event_loop().schedule();
}

void Navigable::perform_scroll_of_viewport(CSSPixelPoint position)
void Navigable::perform_scroll_of_viewport(CSSPixelPoint new_position)
{
auto viewport_rect = this->viewport_rect();
viewport_rect.set_location(position);
set_viewport_rect(viewport_rect);
set_needs_display();
bool did_change = false;

if (is_traversable() && active_browsing_context())
active_browsing_context()->page().client().page_did_request_scroll_to(position);
if (m_viewport_scroll_offset != new_position) {
m_viewport_scroll_offset = new_position;
scroll_offset_did_change();
did_change = true;
m_needs_repaint = true;
}

if (did_change && active_document()) {
active_document()->inform_all_viewport_clients_about_the_current_viewport_rect();
}

// Schedule the HTML event loop to ensure that a `resize` event gets fired.
HTML::main_thread_event_loop().schedule();
}

void Navigable::set_size(CSSPixelSize size)
Expand Down
Loading

0 comments on commit 92882a3

Please sign in to comment.