servo/components/script/dom/screen.rs
Martin Robinson e9daec7d42
compositor: Unify the cross process and in-process API (#36543)
Because there used to be two traits exposing messages to the compositor,
there were two kinds of messages that could be sent:

1. In-process messages from the `Constellation`
2. Cross-process messages from other parts of Servo

Now these two types of messages can be unified into one type.

This is a reland of #36443, which caused regressions due to the fact
that messages to the compositor were no longer triggering the event loop
waker. This version of the PR splits out just the bits that unify the
two APIs, leaving the cleanup of routes in the constellation for another
PR.

Testing: This is covered by existing WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-04-15 18:31:46 +00:00

100 lines
3.2 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 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::root::{Dom, DomRoot};
use crate::dom::window::Window;
use crate::script_runtime::CanGc;
#[dom_struct]
pub(crate) struct Screen {
reflector_: Reflector,
window: Dom<Window>,
}
impl Screen {
fn new_inherited(window: &Window) -> Screen {
Screen {
reflector_: Reflector::new(),
window: Dom::from_ref(window),
}
}
pub(crate) fn new(window: &Window, can_gc: CanGc) -> DomRoot<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)
}
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)
}
}
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)
}
// https://drafts.csswg.org/cssom-view/#dom-screen-availheight
fn AvailHeight(&self) -> Finite<f64> {
Finite::wrap(self.screen_avail_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)
}
// https://drafts.csswg.org/cssom-view/#dom-screen-height
fn Height(&self) -> Finite<f64> {
Finite::wrap(self.screen_size().height as f64)
}
// https://drafts.csswg.org/cssom-view/#dom-screen-colordepth
fn ColorDepth(&self) -> u32 {
24
}
// https://drafts.csswg.org/cssom-view/#dom-screen-pixeldepth
fn PixelDepth(&self) -> u32 {
24
}
}