diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 0d4ae0afc05..24d112b92ce 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -912,26 +912,6 @@ impl IOCompositor { .collect(); let _ = result_sender.send((font_keys, font_instance_keys)); }, - CompositorMsg::GetScreenSize(webview_id, response_sender) => { - let screen_size = self - .webview_renderers - .get(webview_id) - .map(WebViewRenderer::screen_size) - .unwrap_or_default(); - if let Err(error) = response_sender.send(screen_size) { - warn!("Sending response to get screen size failed ({error:?})."); - } - }, - CompositorMsg::GetAvailableScreenSize(webview_id, response_sender) => { - let available_screen_size = self - .webview_renderers - .get(webview_id) - .map(WebViewRenderer::available_screen_size) - .unwrap_or_default(); - if let Err(error) = response_sender.send(available_screen_size) { - warn!("Sending response to get screen size failed ({error:?})."); - } - }, CompositorMsg::Viewport(webview_id, viewport_description) => { if let Some(webview) = self.webview_renderers.get_mut(webview_id) { webview.set_viewport_description(viewport_description); @@ -981,16 +961,6 @@ impl IOCompositor { .collect(); let _ = result_sender.send((font_keys, font_instance_keys)); }, - CompositorMsg::GetScreenSize(_, response_sender) => { - if let Err(error) = response_sender.send(Default::default()) { - warn!("Sending response to get client window failed ({error:?})."); - } - }, - CompositorMsg::GetAvailableScreenSize(_, response_sender) => { - if let Err(error) = response_sender.send(Default::default()) { - warn!("Sending response to get client window failed ({error:?})."); - } - }, CompositorMsg::NewWebRenderFrameReady(..) => { // Subtract from the number of pending frames, but do not do any compositing. self.pending_frames -= 1; diff --git a/components/compositing/tracing.rs b/components/compositing/tracing.rs index 904148e0b24..7de9ebc0f9e 100644 --- a/components/compositing/tracing.rs +++ b/components/compositing/tracing.rs @@ -51,8 +51,6 @@ mod from_constellation { Self::AddSystemFont(..) => target!("AddSystemFont"), Self::AddFontInstance(..) => target!("AddFontInstance"), Self::RemoveFonts(..) => target!("RemoveFonts"), - Self::GetScreenSize(..) => target!("GetScreenSize"), - Self::GetAvailableScreenSize(..) => target!("GetAvailableScreenSize"), Self::CollectMemoryReport(..) => target!("CollectMemoryReport"), Self::Viewport(..) => target!("Viewport"), Self::GenerateImageKeysForPipeline(..) => target!("GenerateImageKeysForPipeline"), diff --git a/components/compositing/webview_renderer.rs b/components/compositing/webview_renderer.rs index 7648c727732..917d909a7fd 100644 --- a/components/compositing/webview_renderer.rs +++ b/components/compositing/webview_renderer.rs @@ -19,7 +19,7 @@ use embedder_traits::{ MouseButtonEvent, MouseMoveEvent, ScrollEvent as EmbedderScrollEvent, ShutdownState, TouchEvent, TouchEventResult, TouchEventType, TouchId, ViewportDetails, }; -use euclid::{Point2D, Scale, Size2D, Vector2D}; +use euclid::{Point2D, Scale, Vector2D}; use fnv::FnvHashSet; use log::{debug, warn}; use servo_geometry::DeviceIndependentPixel; @@ -1039,16 +1039,6 @@ impl WebViewRenderer { old_rect != self.rect } - pub(crate) fn screen_size(&self) -> Size2D { - let screen_geometry = self.webview.screen_geometry().unwrap_or_default(); - (screen_geometry.size.to_f32() / self.hidpi_scale_factor).to_i32() - } - - pub(crate) fn available_screen_size(&self) -> Size2D { - let screen_geometry = self.webview.screen_geometry().unwrap_or_default(); - (screen_geometry.available_size.to_f32() / self.hidpi_scale_factor).to_i32() - } - pub fn set_viewport_description(&mut self, viewport_description: ViewportDescription) { self.pending_scroll_zoom_events .push(ScrollZoomEvent::ViewportZoom( diff --git a/components/constellation/tracing.rs b/components/constellation/tracing.rs index 37186126e2a..24ea7d7bbf2 100644 --- a/components/constellation/tracing.rs +++ b/components/constellation/tracing.rs @@ -215,6 +215,7 @@ mod from_script { Self::NewFavicon(..) => target_variant!("NewFavicon"), Self::HistoryChanged(..) => target_variant!("HistoryChanged"), Self::GetWindowRect(..) => target_variant!("GetWindowRect"), + Self::GetScreenMetrics(..) => target_variant!("GetScreenMetrics"), Self::NotifyFullscreenStateChanged(..) => { target_variant!("NotifyFullscreenStateChanged") }, diff --git a/components/geometry/lib.rs b/components/geometry/lib.rs index 7b0acc07042..ce4ec707e08 100644 --- a/components/geometry/lib.rs +++ b/components/geometry/lib.rs @@ -6,9 +6,12 @@ use std::f32; use app_units::{Au, MAX_AU, MIN_AU}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D}; -use euclid::{Box2D, Length, Point2D, SideOffsets2D, Size2D, Vector2D}; +use euclid::{Box2D, Length, Point2D, Scale, SideOffsets2D, Size2D, Vector2D}; use malloc_size_of_derive::MallocSizeOf; -use webrender_api::units::{FramebufferPixel, LayoutPoint, LayoutRect, LayoutSize}; +use webrender_api::units::{ + DeviceIntRect, DeviceIntSize, DevicePixel, FramebufferPixel, LayoutPoint, LayoutRect, + LayoutSize, +}; // Units for use with euclid::length and euclid::scale_factor. @@ -51,6 +54,22 @@ pub trait MaxRect { fn max_rect() -> Self; } +/// A helper function to convert a Device rect to CSS pixels. +pub fn convert_rect_to_css_pixel( + rect: DeviceIntRect, + scale: Scale, +) -> DeviceIndependentIntRect { + (rect.to_f32() / scale).round().to_i32() +} + +/// A helper function to convert a Device size to CSS pixels. +pub fn convert_size_to_css_pixel( + size: DeviceIntSize, + scale: Scale, +) -> DeviceIndependentIntSize { + (size.to_f32() / scale).round().to_i32() +} + impl MaxRect for UntypedRect { #[inline] fn max_rect() -> Self { diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs index 061b2da3eca..fad30125750 100644 --- a/components/script/dom/screen.rs +++ b/components/script/dom/screen.rs @@ -2,16 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use compositing_traits::CompositorMsg; use dom_struct::dom_struct; -use euclid::Size2D; -use profile_traits::ipc; -use servo_geometry::DeviceIndependentIntSize; -use style_traits::CSSPixel; +use embedder_traits::{EmbedderMsg, ScreenMetrics}; +use ipc_channel::ipc; use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods; use crate::dom::bindings::num::Finite; -use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object}; +use crate::dom::bindings::reflector::{Reflector, reflect_dom_object}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::window::Window; use crate::script_runtime::CanGc; @@ -34,58 +31,38 @@ impl Screen { reflect_dom_object(Box::new(Screen::new_inherited(window)), window, can_gc) } - fn screen_size(&self) -> Size2D { - let (sender, receiver) = - ipc::channel::(self.global().time_profiler_chan().clone()) - .unwrap(); - self.window - .compositor_api() - .sender() - .send(CompositorMsg::GetScreenSize( - self.window.webview_id(), - sender, - )) - .unwrap(); - let size = receiver.recv().unwrap_or(Size2D::zero()).to_u32(); - Size2D::new(size.width, size.height) - } + /// Retrives [`ScreenMetrics`] from the embedder. + fn screen_metrics(&self) -> ScreenMetrics { + let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); - fn screen_avail_size(&self) -> Size2D { - let (sender, receiver) = - ipc::channel::(self.global().time_profiler_chan().clone()) - .unwrap(); - self.window - .compositor_api() - .sender() - .send(CompositorMsg::GetAvailableScreenSize( - self.window.webview_id(), - sender, - )) - .unwrap(); - let size = receiver.recv().unwrap_or(Size2D::zero()).to_u32(); - Size2D::new(size.width, size.height) + self.window.send_to_embedder(EmbedderMsg::GetScreenMetrics( + self.window.webview_id(), + sender, + )); + + receiver.recv().unwrap_or_default() } } impl ScreenMethods for Screen { // https://drafts.csswg.org/cssom-view/#dom-screen-availwidth fn AvailWidth(&self) -> Finite { - Finite::wrap(self.screen_avail_size().width as f64) + Finite::wrap(self.screen_metrics().available_size.width as f64) } // https://drafts.csswg.org/cssom-view/#dom-screen-availheight fn AvailHeight(&self) -> Finite { - Finite::wrap(self.screen_avail_size().height as f64) + Finite::wrap(self.screen_metrics().available_size.height as f64) } // https://drafts.csswg.org/cssom-view/#dom-screen-width fn Width(&self) -> Finite { - Finite::wrap(self.screen_size().width as f64) + Finite::wrap(self.screen_metrics().screen_size.width as f64) } // https://drafts.csswg.org/cssom-view/#dom-screen-height fn Height(&self) -> Finite { - Finite::wrap(self.screen_size().height as f64) + Finite::wrap(self.screen_metrics().screen_size.height as f64) } // https://drafts.csswg.org/cssom-view/#dom-screen-colordepth diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 128d7b1a024..81b43a3792b 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -100,7 +100,9 @@ use servo_config::opts::Opts; use servo_config::prefs::Preferences; use servo_config::{opts, pref, prefs}; use servo_delegate::DefaultServoDelegate; -use servo_geometry::DeviceIndependentIntRect; +use servo_geometry::{ + DeviceIndependentIntRect, convert_rect_to_css_pixel, convert_size_to_css_pixel, +}; use servo_media::ServoMedia; use servo_media::player::context::GlContext; use servo_url::ServoUrl; @@ -1009,15 +1011,38 @@ impl Servo { return DeviceIndependentIntRect::default(); }; - (screen_geometry.window_rect.to_f32() / hidpi_scale_factor) - .round() - .to_i32() + convert_rect_to_css_pixel(screen_geometry.window_rect, hidpi_scale_factor) }; if let Err(error) = response_sender.send(window_rect()) { warn!("Failed to respond to GetWindowRect: {error}"); } }, + EmbedderMsg::GetScreenMetrics(webview_id, response_sender) => { + let screen_metrics = || { + let Some(webview) = self.get_webview_handle(webview_id) else { + return ScreenMetrics::default(); + }; + let hidpi_scale_factor = webview.hidpi_scale_factor(); + let Some(screen_geometry) = webview.delegate().screen_geometry(webview) else { + return ScreenMetrics::default(); + }; + + ScreenMetrics { + screen_size: convert_size_to_css_pixel( + screen_geometry.size, + hidpi_scale_factor, + ), + available_size: convert_size_to_css_pixel( + screen_geometry.available_size, + hidpi_scale_factor, + ), + } + }; + if let Err(error) = response_sender.send(screen_metrics()) { + warn!("Failed to respond to GetScreenMetrics: {error}"); + } + }, } } diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs index d1863b1bf4c..654137a6771 100644 --- a/components/shared/compositing/lib.rs +++ b/components/shared/compositing/lib.rs @@ -33,7 +33,6 @@ use euclid::default::Size2D as UntypedSize2D; use ipc_channel::ipc::{self, IpcSharedMemory}; use profile_traits::mem::{OpaqueSender, ReportsChan}; use serde::{Deserialize, Serialize}; -use servo_geometry::DeviceIndependentIntSize; use webrender_api::units::{DevicePoint, LayoutVector2D, TexelRect}; use webrender_api::{ BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData, @@ -152,13 +151,6 @@ pub enum CompositorMsg { AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags), /// Remove the given font resources from our WebRender instance. RemoveFonts(Vec, Vec), - /// Get the size of the screen that the client window inhabits. - GetScreenSize(WebViewId, IpcSender), - /// Get the available screen size, without system interface elements such as menus, docks, and - /// taskbars. - /// the client window inhabits. - GetAvailableScreenSize(WebViewId, IpcSender), - /// Measure the current memory usage associated with the compositor. /// The report must be sent on the provided channel once it's complete. CollectMemoryReport(ReportsChan), diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs index 036aaa87b10..96d2e6dc49e 100644 --- a/components/shared/embedder/lib.rs +++ b/components/shared/embedder/lib.rs @@ -31,7 +31,7 @@ use malloc_size_of_derive::MallocSizeOf; use num_derive::FromPrimitive; use pixels::RasterImage; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use servo_geometry::DeviceIndependentIntRect; +use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize}; use servo_url::ServoUrl; use strum_macros::IntoStaticStr; use style::queries::values::PrefersColorScheme; @@ -310,6 +310,14 @@ pub struct ViewportDetails { pub hidpi_scale_factor: Scale, } +/// Unlike [`ScreenGeometry`], the data is in device-independent pixels +/// to be used by DOM APIs +#[derive(Default, Deserialize, Serialize)] +pub struct ScreenMetrics { + pub screen_size: DeviceIndependentIntSize, + pub available_size: DeviceIndependentIntSize, +} + #[derive(Deserialize, IntoStaticStr, Serialize)] pub enum EmbedderMsg { /// A status message to be displayed by the browser chrome. @@ -366,6 +374,8 @@ pub enum EmbedderMsg { HistoryChanged(WebViewId, Vec, usize), /// Get the device independent window rectangle. GetWindowRect(WebViewId, IpcSender), + /// Get the device independent screen size and available size. + GetScreenMetrics(WebViewId, IpcSender), /// Entered or exited fullscreen. NotifyFullscreenStateChanged(WebViewId, bool), /// The [`LoadStatus`] of the Given `WebView` has changed. diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini index 8698a74cdbf..22e577306cf 100644 --- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini +++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/interactability.py.ini @@ -2,9 +2,6 @@ [test_document_element_is_interactable] expected: FAIL - [test_iframe_is_interactable] - expected: FAIL - [test_not_a_focusable_element] expected: FAIL diff --git a/tests/wpt/mozilla/meta/css/linear_gradients_non_square_a.html.ini b/tests/wpt/mozilla/meta/css/linear_gradients_non_square_a.html.ini deleted file mode 100644 index f55fed9a439..00000000000 --- a/tests/wpt/mozilla/meta/css/linear_gradients_non_square_a.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[linear_gradients_non_square_a.html] - expected: FAIL