diff --git a/Libraries/LibWeb/HTML/Navigable.h b/Libraries/LibWeb/HTML/Navigable.h index 83e2340975..db780500e3 100644 --- a/Libraries/LibWeb/HTML/Navigable.h +++ b/Libraries/LibWeb/HTML/Navigable.h @@ -172,6 +172,8 @@ public: void set_viewport_size(CSSPixelSize); void perform_scroll_of_viewport_scrolling_box(CSSPixelPoint position); + Painting::BackingStoreManager& backing_store_manager() { return *m_backing_store_manager; } + // https://html.spec.whatwg.org/multipage/webappapis.html#rendering-opportunity [[nodiscard]] bool has_a_rendering_opportunity() const; diff --git a/Libraries/LibWeb/Internals/Internals.cpp b/Libraries/LibWeb/Internals/Internals.cpp index 4f09080421..0d11b01635 100644 --- a/Libraries/LibWeb/Internals/Internals.cpp +++ b/Libraries/LibWeb/Internals/Internals.cpp @@ -437,6 +437,11 @@ void Internals::set_browser_zoom(double factor) page().client().page_did_set_browser_zoom(factor); } +void Internals::set_device_pixel_ratio(double ratio) +{ + page().client().page_did_set_device_pixel_ratio_for_testing(ratio); +} + bool Internals::headless() { return page().client().is_headless(); diff --git a/Libraries/LibWeb/Internals/Internals.h b/Libraries/LibWeb/Internals/Internals.h index 69824a6604..d83b04d346 100644 --- a/Libraries/LibWeb/Internals/Internals.h +++ b/Libraries/LibWeb/Internals/Internals.h @@ -69,6 +69,7 @@ public: static void set_echo_server_port(u16 port); void set_browser_zoom(double factor); + void set_device_pixel_ratio(double ratio); bool headless(); diff --git a/Libraries/LibWeb/Internals/Internals.idl b/Libraries/LibWeb/Internals/Internals.idl index e164be6ace..344ef87248 100644 --- a/Libraries/LibWeb/Internals/Internals.idl +++ b/Libraries/LibWeb/Internals/Internals.idl @@ -58,6 +58,7 @@ interface Internals { unsigned short getEchoServerPort(); undefined setBrowserZoom(double factor); + undefined setDevicePixelRatio(double ratio); readonly attribute boolean headless; diff --git a/Libraries/LibWeb/Page/Page.h b/Libraries/LibWeb/Page/Page.h index c1df05e7c2..00114d71b1 100644 --- a/Libraries/LibWeb/Page/Page.h +++ b/Libraries/LibWeb/Page/Page.h @@ -417,6 +417,7 @@ public: virtual void page_did_receive_test_variant_metadata(JsonValue) { } virtual void page_did_set_browser_zoom([[maybe_unused]] double factor) { } + virtual void page_did_set_device_pixel_ratio_for_testing([[maybe_unused]] double ratio) { } virtual void page_did_change_theme_color(Gfx::Color) { } diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index 26d23f9a08..3f8ccf433d 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -207,6 +208,23 @@ void PageClient::set_viewport_size(Web::DevicePixelSize const& size) page().top_level_traversable()->set_viewport_size(page().device_to_css_size(size)); } +void PageClient::set_device_pixel_ratio(double device_pixel_ratio) +{ + if (m_device_pixel_ratio == device_pixel_ratio) + return; + + m_device_pixel_ratio = device_pixel_ratio; + + auto traversable = page().top_level_traversable(); + traversable->backing_store_manager() + .resize_backing_stores_if_needed(Web::Painting::BackingStoreManager::WindowResizingInProgress::No); + + if (auto document = traversable->active_document()) { + document->set_needs_media_query_evaluation(); + document->set_needs_display(Web::InvalidateDisplayList::Yes); + } +} + void PageClient::set_maximum_frames_per_second(u64 maximum_frames_per_second) { m_maximum_frames_per_second = maximum_frames_per_second; @@ -372,6 +390,11 @@ void PageClient::page_did_set_browser_zoom(double factor) })); } +void PageClient::page_did_set_device_pixel_ratio_for_testing(double ratio) +{ + set_device_pixel_ratio(ratio); +} + void PageClient::page_did_request_context_menu(Web::CSSPixelPoint content_position) { client().async_did_request_context_menu(m_id, page().css_to_device_point(content_position).to_type()); diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h index 5fb158a7f8..8d4d5b4baa 100644 --- a/Services/WebContent/PageClient.h +++ b/Services/WebContent/PageClient.h @@ -58,7 +58,7 @@ public: m_all_screen_rects = rects; m_main_screen_index = main_screen_index; } - void set_device_pixel_ratio(double device_pixel_ratio) { m_device_pixel_ratio = device_pixel_ratio; } + void set_device_pixel_ratio(double device_pixel_ratio); void set_zoom_level(double zoom_level) { m_zoom_level = zoom_level; } void set_maximum_frames_per_second(u64 maximum_frames_per_second); void set_preferred_color_scheme(Web::CSS::PreferredColorScheme); @@ -182,6 +182,7 @@ private: virtual void page_did_receive_reference_test_metadata(JsonValue) override; virtual void page_did_receive_test_variant_metadata(JsonValue) override; virtual void page_did_set_browser_zoom(double factor) override; + virtual void page_did_set_device_pixel_ratio_for_testing(double ratio) override; virtual void page_did_change_theme_color(Gfx::Color color) override; virtual void page_did_insert_clipboard_entry(Web::Clipboard::SystemClipboardRepresentation const&, StringView presentation_style) override; virtual void page_did_request_clipboard_entries(u64 request_id) override; diff --git a/Tests/LibWeb/Text/expected/device-pixel-ratio-media-query.txt b/Tests/LibWeb/Text/expected/device-pixel-ratio-media-query.txt new file mode 100644 index 0000000000..6bd45c7259 --- /dev/null +++ b/Tests/LibWeb/Text/expected/device-pixel-ratio-media-query.txt @@ -0,0 +1,5 @@ +Initial matches (at 1x): false +Change event 1: matches = true +PASS: Media query matched after DPI changed to 2x +Change event 2: matches = false +PASS: Media query unmatched after DPI changed back to 1x diff --git a/Tests/LibWeb/Text/input/device-pixel-ratio-media-query.html b/Tests/LibWeb/Text/input/device-pixel-ratio-media-query.html new file mode 100644 index 0000000000..70549c2953 --- /dev/null +++ b/Tests/LibWeb/Text/input/device-pixel-ratio-media-query.html @@ -0,0 +1,36 @@ + + +