mirror of
https://github.com/servo/servo.git
synced 2025-07-19 21:33:49 +01:00
script: Get the screen metrics from the WebViewDelegate
instead of via the compositor (#38020)
Similar to #37960, previously, `AvailHeight`, `AvailWidth`, `Height`, `Width` ask compositor for screen metrics. This PR moves the request to embedder. This simplifies code, and reduces workload of compositor, which is busier most of time. Testing: No behaviour change. Updated some tests. `Width/Height` matches other browsers. --------- Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
parent
d0a93a8b02
commit
d38ffb82b2
11 changed files with 79 additions and 102 deletions
|
@ -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;
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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<i32, DeviceIndependentPixel> {
|
||||
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<i32, DeviceIndependentPixel> {
|
||||
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(
|
||||
|
|
|
@ -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")
|
||||
},
|
||||
|
|
|
@ -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<f32, DeviceIndependentPixel, DevicePixel>,
|
||||
) -> 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<f32, DeviceIndependentPixel, DevicePixel>,
|
||||
) -> DeviceIndependentIntSize {
|
||||
(size.to_f32() / scale).round().to_i32()
|
||||
}
|
||||
|
||||
impl MaxRect for UntypedRect<Au> {
|
||||
#[inline]
|
||||
fn max_rect() -> Self {
|
||||
|
|
|
@ -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<u32, CSSPixel> {
|
||||
let (sender, receiver) =
|
||||
ipc::channel::<DeviceIndependentIntSize>(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<u32, CSSPixel> {
|
||||
let (sender, receiver) =
|
||||
ipc::channel::<DeviceIndependentIntSize>(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<crate::DomTypeHolder> for Screen {
|
||||
// https://drafts.csswg.org/cssom-view/#dom-screen-availwidth
|
||||
fn AvailWidth(&self) -> Finite<f64> {
|
||||
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<f64> {
|
||||
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<f64> {
|
||||
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<f64> {
|
||||
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
|
||||
|
|
|
@ -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}");
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<FontKey>, Vec<FontInstanceKey>),
|
||||
/// Get the size of the screen that the client window inhabits.
|
||||
GetScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
||||
/// Get the available screen size, without system interface elements such as menus, docks, and
|
||||
/// taskbars.
|
||||
/// the client window inhabits.
|
||||
GetAvailableScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
||||
|
||||
/// Measure the current memory usage associated with the compositor.
|
||||
/// The report must be sent on the provided channel once it's complete.
|
||||
CollectMemoryReport(ReportsChan),
|
||||
|
|
|
@ -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<f32, CSSPixel, DevicePixel>,
|
||||
}
|
||||
|
||||
/// 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<ServoUrl>, usize),
|
||||
/// Get the device independent window rectangle.
|
||||
GetWindowRect(WebViewId, IpcSender<DeviceIndependentIntRect>),
|
||||
/// Get the device independent screen size and available size.
|
||||
GetScreenMetrics(WebViewId, IpcSender<ScreenMetrics>),
|
||||
/// Entered or exited fullscreen.
|
||||
NotifyFullscreenStateChanged(WebViewId, bool),
|
||||
/// The [`LoadStatus`] of the Given `WebView` has changed.
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
[test_document_element_is_interactable]
|
||||
expected: FAIL
|
||||
|
||||
[test_iframe_is_interactable]
|
||||
expected: FAIL
|
||||
|
||||
[test_not_a_focusable_element]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[linear_gradients_non_square_a.html]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue