diff --git a/Cargo.lock b/Cargo.lock index 060343ecebd..a40d522d77a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8304,6 +8304,7 @@ dependencies = [ "libc", "log", "serde", + "servo_geometry", "surfman", "webrender_api", ] diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 30965214603..31c4380f8ba 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -17,7 +17,7 @@ use script_traits::{ GamepadEvent, MediaSessionActionType, MouseButton, TouchEventType, TouchId, TraversalDirection, WheelDelta, }; -use servo_geometry::DeviceIndependentPixel; +use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize, DeviceIndependentPixel}; use servo_url::ServoUrl; use style_traits::DevicePixel; use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, DeviceRect}; @@ -241,11 +241,11 @@ pub struct EmbedderCoordinates { /// The pixel density of the display. pub hidpi_factor: Scale, /// Size of the screen. - pub screen_size: DeviceIntSize, + pub screen_size: DeviceIndependentIntSize, /// Size of the available screen space (screen without toolbars and docks). - pub available_screen_size: DeviceIntSize, + pub available_screen_size: DeviceIndependentIntSize, /// Position and size of the native window. - pub window_rect: DeviceIntRect, + pub window_rect: DeviceIndependentIntRect, /// Size of the GL buffer in the window. pub framebuffer: DeviceIntSize, /// Coordinates of the document within the framebuffer. @@ -278,23 +278,23 @@ impl EmbedderCoordinates { #[cfg(test)] mod test { - use euclid::{Point2D, Scale, Size2D}; + use euclid::{Box2D, Point2D, Scale, Size2D}; use webrender_api::units::DeviceIntRect; use super::EmbedderCoordinates; #[test] fn test() { - let pos = Point2D::zero(); - let viewport = Size2D::new(800, 600); - let screen = Size2D::new(1080, 720); + let screen_size = Size2D::new(1080, 720); + let viewport = Box2D::from_origin_and_size(Point2D::zero(), Size2D::new(800, 600)); + let window_rect = Box2D::from_origin_and_size(Point2D::zero(), Size2D::new(800, 600)); let coordinates = EmbedderCoordinates { hidpi_factor: Scale::new(1.), - screen_size: screen, - available_screen_size: screen, - window_rect: DeviceIntRect::from_origin_and_size(pos, viewport), - framebuffer: viewport, - viewport: DeviceIntRect::from_origin_and_size(pos, viewport), + screen_size, + available_screen_size: screen_size, + window_rect, + framebuffer: viewport.size(), + viewport, }; // Check if viewport conversion is correct. diff --git a/components/config/opts.rs b/components/config/opts.rs index 62645c294b2..22e16286254 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -83,6 +83,10 @@ pub struct Opts { /// The initial requested size of the window. pub initial_window_size: Size2D, + /// An override for the screen resolution. This is useful for testing behavior on different screen sizes, + /// such as the screen of a mobile device. + pub screen_size_override: Option>, + /// Whether we're running in multiprocess mode. pub multiprocess: bool, @@ -410,6 +414,7 @@ pub fn default_opts() -> Opts { devtools_server_enabled: false, webdriver_port: None, initial_window_size: Size2D::new(1024, 740), + screen_size_override: None, multiprocess: false, background_hang_monitor: false, random_pipeline_closure_probability: None, @@ -503,7 +508,18 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR "Start remote WebDriver server on port", "7000", ); - opts.optopt("", "resolution", "Set window resolution.", "1024x740"); + opts.optopt( + "", + "window-size", + "Set the initial window size in logical (device independenrt) pixels", + "1024x740", + ); + opts.optopt( + "", + "screen-size", + "Override the screen resolution in logical (device independent) pixels", + "1024x768", + ); opts.optflag("M", "multiprocess", "Run in multiprocess mode"); opts.optflag("B", "bhm", "Background Hang Monitor enabled"); opts.optflag("S", "sandbox", "Run in a sandbox if multiprocess"); @@ -694,21 +710,33 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR }) }); - let initial_window_size = match opt_match.opt_str("resolution") { - Some(res_string) => { - let res: Vec = res_string - .split('x') - .map(|r| { - r.parse().unwrap_or_else(|err| { - args_fail(&format!("Error parsing option: --resolution ({})", err)) - }) + let parse_resolution_string = |string: String| { + let components: Vec = string + .split('x') + .map(|component| { + component.parse().unwrap_or_else(|error| { + args_fail(&format!("Error parsing resolution '{string}': {error}")); }) - .collect(); - Size2D::new(res[0], res[1]) - }, - None => Size2D::new(1024, 740), + }) + .collect(); + Size2D::new(components[0], components[1]) }; + let screen_size_override = opt_match + .opt_str("screen-size") + .map(parse_resolution_string); + + // Make sure the default window size is not larger than any provided screen size. + let default_window_size = Size2D::new(1024, 740); + let default_window_size = screen_size_override + .map_or(default_window_size, |screen_size_override| { + default_window_size.min(screen_size_override) + }); + + let initial_window_size = opt_match + .opt_str("window-size") + .map_or(default_window_size, parse_resolution_string); + if opt_match.opt_present("M") { MULTIPROCESS.store(true, Ordering::SeqCst) } @@ -753,6 +781,7 @@ pub fn from_cmdline_args(mut opts: Options, args: &[String]) -> ArgumentParsingR devtools_server_enabled, webdriver_port, initial_window_size, + screen_size_override, multiprocess: opt_match.opt_present("M"), background_hang_monitor: opt_match.opt_present("B"), sandbox: opt_match.opt_present("S"), diff --git a/components/geometry/lib.rs b/components/geometry/lib.rs index 25ce5cfceaf..7b0acc07042 100644 --- a/components/geometry/lib.rs +++ b/components/geometry/lib.rs @@ -5,8 +5,8 @@ use std::f32; use app_units::{Au, MAX_AU, MIN_AU}; -use euclid::default::{Point2D, Rect, Size2D}; -use euclid::Length; +use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D}; +use euclid::{Box2D, Length, Point2D, SideOffsets2D, Size2D, Vector2D}; use malloc_size_of_derive::MallocSizeOf; use webrender_api::units::{FramebufferPixel, LayoutPoint, LayoutRect, LayoutSize}; @@ -30,6 +30,19 @@ pub type FramebufferUintLength = Length; #[derive(Clone, Copy, Debug, MallocSizeOf)] pub enum DeviceIndependentPixel {} +pub type DeviceIndependentIntRect = Box2D; +pub type DeviceIndependentIntPoint = Point2D; +pub type DeviceIndependentIntSize = Size2D; +pub type DeviceIndependentIntLength = Length; +pub type DeviceIndependentIntSideOffsets = SideOffsets2D; +pub type DeviceIndependentIntVector2D = Vector2D; + +pub type DeviceIndependentRect = Box2D; +pub type DeviceIndependentBox2D = Box2D; +pub type DeviceIndependentPoint = Point2D; +pub type DeviceIndependentVector2D = Vector2D; +pub type DeviceIndependentSize = Size2D; + // An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was // originally proposed in 2002 as a standard unit of measure in Gecko. // See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info. @@ -38,20 +51,20 @@ pub trait MaxRect { fn max_rect() -> Self; } -impl MaxRect for Rect { +impl MaxRect for UntypedRect { #[inline] - fn max_rect() -> Rect { - Rect::new( - Point2D::new(MIN_AU / 2, MIN_AU / 2), - Size2D::new(MAX_AU, MAX_AU), + fn max_rect() -> Self { + Self::new( + UntypedPoint2D::new(MIN_AU / 2, MIN_AU / 2), + UntypedSize2D::new(MAX_AU, MAX_AU), ) } } impl MaxRect for LayoutRect { #[inline] - fn max_rect() -> LayoutRect { - LayoutRect::from_origin_and_size( + fn max_rect() -> Self { + Self::from_origin_and_size( LayoutPoint::new(f32::MIN / 2.0, f32::MIN / 2.0), LayoutSize::new(f32::MAX, f32::MAX), ) @@ -59,8 +72,8 @@ impl MaxRect for LayoutRect { } /// A helper function to convert a rect of `f32` pixels to a rect of app units. -pub fn f32_rect_to_au_rect(rect: Rect) -> Rect { - Rect::new( +pub fn f32_rect_to_au_rect(rect: UntypedRect) -> UntypedRect { + UntypedRect::new( Point2D::new( Au::from_f32_px(rect.origin.x), Au::from_f32_px(rect.origin.y), @@ -73,8 +86,8 @@ pub fn f32_rect_to_au_rect(rect: Rect) -> Rect { } /// A helper function to convert a rect of `Au` pixels to a rect of f32 units. -pub fn au_rect_to_f32_rect(rect: Rect) -> Rect { - Rect::new( +pub fn au_rect_to_f32_rect(rect: UntypedRect) -> UntypedRect { + UntypedRect::new( Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()), Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()), ) diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs index d7ce8b6b4be..f45f6355269 100644 --- a/components/script/dom/screen.rs +++ b/components/script/dom/screen.rs @@ -5,8 +5,8 @@ use dom_struct::dom_struct; use euclid::Size2D; use profile_traits::ipc; +use servo_geometry::DeviceIndependentIntSize; use style_traits::CSSPixel; -use webrender_api::units::DeviceIntSize; use webrender_traits::CrossProcessCompositorMessage; use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods; @@ -35,28 +35,28 @@ impl Screen { fn screen_size(&self) -> Size2D { let (send, recv) = - ipc::channel::(self.global().time_profiler_chan().clone()).unwrap(); + ipc::channel::(self.global().time_profiler_chan().clone()) + .unwrap(); self.window .compositor_api() .sender() .send(CrossProcessCompositorMessage::GetScreenSize(send)) .unwrap(); - let dpr = self.window.device_pixel_ratio(); - let screen = recv.recv().unwrap_or(Size2D::zero()); - (screen.to_f32() / dpr).to_u32() + let size = recv.recv().unwrap_or(Size2D::zero()).to_u32(); + Size2D::new(size.width, size.height) } fn screen_avail_size(&self) -> Size2D { let (send, recv) = - ipc::channel::(self.global().time_profiler_chan().clone()).unwrap(); + ipc::channel::(self.global().time_profiler_chan().clone()) + .unwrap(); self.window .compositor_api() .sender() .send(CrossProcessCompositorMessage::GetAvailableScreenSize(send)) .unwrap(); - let dpr = self.window.device_pixel_ratio(); - let screen = recv.recv().unwrap_or(Size2D::zero()); - (screen.to_f32() / dpr).to_u32() + let size = recv.recv().unwrap_or(Size2D::zero()).to_u32(); + Size2D::new(size.width, size.height) } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index f6ca5d96861..e133eb6cb46 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -63,7 +63,7 @@ use selectors::attr::CaseSensitivity; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::pref; -use servo_geometry::{f32_rect_to_au_rect, MaxRect}; +use servo_geometry::{f32_rect_to_au_rect, DeviceIndependentIntRect, MaxRect}; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use style::dom::OpaqueNode; use style::error_reporting::{ContextualParseError, ParseErrorReporter}; @@ -76,7 +76,7 @@ use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{CssRuleType, Origin, UrlExtraData}; use style_traits::{CSSPixel, DevicePixel, ParsingMode}; use url::Position; -use webrender_api::units::{DeviceIntRect, LayoutPixel}; +use webrender_api::units::LayoutPixel; use webrender_api::{DocumentId, ExternalScrollId}; use webrender_traits::CrossProcessCompositorApi; @@ -1782,16 +1782,16 @@ impl Window { fn client_window(&self) -> (Size2D, Point2D) { let timer_profile_chan = self.global().time_profiler_chan().clone(); - let (send, recv) = ProfiledIpc::channel::(timer_profile_chan).unwrap(); + let (send, recv) = + ProfiledIpc::channel::(timer_profile_chan).unwrap(); let _ = self .compositor_api .sender() .send(webrender_traits::CrossProcessCompositorMessage::GetClientWindowRect(send)); - let rect = recv.recv().unwrap_or_default(); - let dpr = self.device_pixel_ratio(); + let rect = recv.recv().unwrap_or_default().to_u32(); ( - (rect.size().to_f32() / dpr).to_u32(), - (rect.min.to_f32() / dpr).to_i32(), + Size2D::new(rect.size().width, rect.size().height), + Point2D::new(rect.min.x as i32, rect.min.y as i32), ) } diff --git a/components/shared/webrender/Cargo.toml b/components/shared/webrender/Cargo.toml index fb40beeeaf6..14e1c405468 100644 --- a/components/shared/webrender/Cargo.toml +++ b/components/shared/webrender/Cargo.toml @@ -21,5 +21,6 @@ log = { workspace = true } libc = { workspace = true } webrender_api = { workspace = true } serde = { workspace = true } +servo_geometry = { path = "../../geometry" } surfman = { workspace = true } diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs index 807c8909d61..48847edaedf 100644 --- a/components/shared/webrender/lib.rs +++ b/components/shared/webrender/lib.rs @@ -14,12 +14,13 @@ use std::sync::{Arc, Mutex}; use base::id::PipelineId; use display_list::{CompositorDisplayListInfo, ScrollTreeNodeId}; use embedder_traits::Cursor; -use euclid::default::Size2D; +use euclid::default::Size2D as UntypedSize2D; use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; use libc::c_void; use log::warn; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePoint, LayoutPoint, TexelRect}; +use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize}; +use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect}; use webrender_api::{ BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData, ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId, @@ -77,12 +78,12 @@ pub enum CrossProcessCompositorMessage { RemoveFonts(Vec, Vec), /// Get the client window size and position. - GetClientWindowRect(IpcSender), + GetClientWindowRect(IpcSender), /// Get the size of the screen that the client window inhabits. - GetScreenSize(IpcSender), + GetScreenSize(IpcSender), /// Get the available screen size (without toolbars and docks) for the screen /// the client window inhabits. - GetAvailableScreenSize(IpcSender), + GetAvailableScreenSize(IpcSender), } impl fmt::Debug for CrossProcessCompositorMessage { @@ -291,7 +292,7 @@ impl CrossProcessCompositorApi { /// This trait is used to notify lock/unlock messages and get the /// required info that WR needs. pub trait WebrenderExternalImageApi { - fn lock(&mut self, id: u64) -> (WebrenderImageSource, Size2D); + fn lock(&mut self, id: u64) -> (WebrenderImageSource, UntypedSize2D); fn unlock(&mut self, id: u64); } diff --git a/etc/start_servo.py b/etc/start_servo.py index a3815e0dc1a..5c241f4300a 100644 --- a/etc/start_servo.py +++ b/etc/start_servo.py @@ -18,7 +18,7 @@ import subprocess def start_servo(port, resolution): # Use the below command if you are running this script on windows - # cmds = 'mach.bat run --webdriver ' + port + ' --resolution ' + resolution - cmds = './mach run --webdriver=' + port + ' --resolution ' + resolution + # cmds = 'mach.bat run --webdriver ' + port + ' --window-size ' + resolution + cmds = './mach run --webdriver=' + port + ' --window-size ' + resolution process = subprocess.Popen(cmds, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return process diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs index bd5ea8e9e58..4c97d68a52a 100644 --- a/ports/servoshell/desktop/headed_window.rs +++ b/ports/servoshell/desktop/headed_window.rs @@ -38,12 +38,12 @@ use super::window_trait::{WindowPortsMethods, LINE_HEIGHT}; pub struct Window { winit_window: winit::window::Window, rendering_context: RenderingContext, - screen_size: Size2D, - inner_size: Cell>, + screen_size: Size2D, + inner_size: Cell>, toolbar_height: Cell>, mouse_down_button: Cell>, mouse_down_point: Cell>, - primary_monitor: winit::monitor::MonitorHandle, + monitor: winit::monitor::MonitorHandle, event_queue: RefCell>, mouse_pos: Cell>, last_pressed: Cell)>>, @@ -59,7 +59,7 @@ pub struct Window { impl Window { pub fn new( - win_size: Size2D, + window_size: Size2D, event_loop: &winit::event_loop::EventLoop, no_native_titlebar: bool, device_pixel_ratio_override: Option, @@ -76,7 +76,7 @@ impl Window { .with_title("Servo".to_string()) .with_decorations(!no_native_titlebar) .with_transparent(no_native_titlebar) - .with_inner_size(LogicalSize::new(win_size.width, win_size.height)) + .with_inner_size(LogicalSize::new(window_size.width, window_size.height)) .with_visible(visible); #[allow(deprecated)] @@ -90,13 +90,18 @@ impl Window { winit_window.set_window_icon(Some(load_icon(icon_bytes))); } - let primary_monitor = winit_window - .available_monitors() - .nth(0) + let monitor = winit_window + .current_monitor() + .or_else(|| winit_window.available_monitors().nth(0)) .expect("No monitor detected"); - let screen_size = winit_size_to_euclid_size(primary_monitor.size()); - let inner_size = winit_size_to_euclid_size(winit_window.inner_size()); + let (screen_size, screen_scale) = opts.screen_size_override.map_or_else( + || (monitor.size(), monitor.scale_factor()), + |size| (PhysicalSize::new(size.width, size.height), 1.0), + ); + let screen_scale: Scale = + Scale::new(screen_scale); + let screen_size = (winit_size_to_euclid_size(screen_size).to_f64() * screen_scale).to_u32(); // Initialize surfman let display_handle = winit_window @@ -110,12 +115,15 @@ impl Window { let window_handle = winit_window .window_handle() .expect("could not get window handle from window"); + + let inner_size = winit_window.inner_size(); let native_widget = connection .create_native_widget_from_window_handle( window_handle, - inner_size.to_i32().to_untyped(), + winit_size_to_euclid_size(inner_size).to_i32().to_untyped(), ) .expect("Failed to create native widget"); + let surface_type = SurfaceType::Widget { native_widget }; let rendering_context = RenderingContext::create(&connection, &adapter, surface_type) .expect("Failed to create WR surfman"); @@ -133,7 +141,7 @@ impl Window { animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), inner_size: Cell::new(inner_size), - primary_monitor, + monitor, screen_size, device_pixel_ratio_override, xr_window_poses: RefCell::new(vec![]), @@ -321,7 +329,7 @@ impl WindowPortsMethods for Window { if self.fullscreen.get() != state { self.winit_window.set_fullscreen(if state { Some(winit::window::Fullscreen::Borderless(Some( - self.primary_monitor.clone(), + self.monitor.clone(), ))) } else { None @@ -469,13 +477,10 @@ impl WindowPortsMethods for Window { winit::event::WindowEvent::CloseRequested => { self.event_queue.borrow_mut().push(EmbedderEvent::Quit); }, - winit::event::WindowEvent::Resized(physical_size) => { - let (width, height) = physical_size.into(); - let new_size = Size2D::new(width, height); + winit::event::WindowEvent::Resized(new_size) => { if self.inner_size.get() != new_size { - let physical_size = Size2D::new(physical_size.width, physical_size.height); self.rendering_context - .resize(physical_size.to_i32()) + .resize(Size2D::new(new_size.width, new_size.height).to_i32()) .expect("Failed to resize"); self.inner_size.set(new_size); self.event_queue @@ -528,6 +533,11 @@ impl WindowMethods for Window { let window_size = winit_size_to_euclid_size(self.winit_window.outer_size()).to_i32(); let window_origin = self.winit_window.outer_position().unwrap_or_default(); let window_origin = winit_position_to_euclid_point(window_origin).to_i32(); + let window_rect = DeviceIntRect::from_origin_and_size(window_origin, window_size); + let window_scale: Scale = + Scale::new(self.winit_window.scale_factor()); + let window_rect = (window_rect.to_f64() * window_scale).to_i32(); + let viewport_origin = DeviceIntPoint::zero(); // bottom left let viewport_size = winit_size_to_euclid_size(self.winit_window.inner_size()).to_f32(); let viewport = DeviceIntRect::from_origin_and_size(viewport_origin, viewport_size.to_i32()); @@ -536,7 +546,7 @@ impl WindowMethods for Window { EmbedderCoordinates { viewport, framebuffer: viewport.size(), - window_rect: DeviceIntRect::from_origin_and_size(window_origin, window_size), + window_rect, screen_size, // FIXME: Winit doesn't have API for available size. Fallback to screen size available_screen_size: screen_size, diff --git a/ports/servoshell/desktop/headless_window.rs b/ports/servoshell/desktop/headless_window.rs index de4caa1c713..b358b996608 100644 --- a/ports/servoshell/desktop/headless_window.rs +++ b/ports/servoshell/desktop/headless_window.rs @@ -9,14 +9,15 @@ use std::rc::Rc; use std::sync::RwLock; use euclid::num::Zero; -use euclid::{Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; +use euclid::{Box2D, Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; use log::warn; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderEvent, WindowMethods, }; +use servo::config::opts; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; -use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize}; +use servo::webrender_api::units::DeviceIntSize; use servo::webrender_traits::RenderingContext; use surfman::{Connection, Context, Device, SurfaceType}; @@ -26,8 +27,10 @@ pub struct Window { rendering_context: RenderingContext, animation_state: Cell, fullscreen: Cell, - device_pixel_ratio_override: Option, - inner_size: Cell>, + device_pixel_ratio_override: Option>, + inner_size: Cell, + screen_size: Size2D, + window_rect: Box2D, event_queue: RwLock>, } @@ -42,17 +45,33 @@ impl Window { let adapter = connection .create_software_adapter() .expect("Failed to create adapter"); - let size = size.to_untyped().to_i32(); - let surface_type = SurfaceType::Generic { size }; + let surface_type = SurfaceType::Generic { + size: size.to_untyped().to_i32(), + }; let rendering_context = RenderingContext::create(&connection, &adapter, surface_type) .expect("Failed to create WR surfman"); + let device_pixel_ratio_override: Option> = + device_pixel_ratio_override.map(Scale::new); + let hidpi_factor = device_pixel_ratio_override.unwrap_or_else(Scale::identity); + + let size = size.to_i32(); + let inner_size = Cell::new((size.to_f32() * hidpi_factor).to_i32()); + let window_rect = Box2D::from_origin_and_size(Point2D::zero(), size); + + let screen_size = opts::get().screen_size_override.map_or_else( + || window_rect.size(), + |screen_size_override| screen_size_override.to_i32(), + ); + let window = Window { rendering_context, animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), device_pixel_ratio_override, - inner_size: Cell::new(size.to_i32()), + inner_size, + screen_size, + window_rect, event_queue: RwLock::new(Vec::new()), }; @@ -73,17 +92,15 @@ impl WindowPortsMethods for Window { } fn request_inner_size(&self, size: DeviceIntSize) -> Option { - let (width, height) = size.into(); - // Surfman doesn't support zero-sized surfaces. - let new_size = DeviceIntSize::new(width.max(1), height.max(1)); - if self.inner_size.get() == new_size.to_untyped() { + let new_size = DeviceIntSize::new(size.width.max(1), size.height.max(1)); + if self.inner_size.get() == new_size { return Some(new_size); } match self.rendering_context.resize(new_size.to_untyped()) { Ok(()) => { - self.inner_size.set(new_size.to_untyped()); + self.inner_size.set(new_size); if let Ok(ref mut queue) = self.event_queue.write() { queue.push(EmbedderEvent::WindowResize); } @@ -103,7 +120,7 @@ impl WindowPortsMethods for Window { fn device_pixel_ratio_override( &self, ) -> Option> { - self.device_pixel_ratio_override.map(Scale::new) + self.device_pixel_ratio_override } fn page_height(&self) -> f32 { @@ -155,21 +172,14 @@ impl WindowPortsMethods for Window { impl WindowMethods for Window { fn get_coordinates(&self) -> EmbedderCoordinates { - let dpr = self.hidpi_factor(); - let size = self - .rendering_context - .context_surface_info() - .unwrap_or(None) - .map(|info| Size2D::from_untyped(info.size)) - .unwrap_or(Size2D::new(0, 0)); - let viewport = DeviceIntRect::from_origin_and_size(Point2D::zero(), size); + let inner_size = self.inner_size.get(); EmbedderCoordinates { - viewport, - framebuffer: size, - window_rect: DeviceIntRect::from_origin_and_size(Point2D::zero(), size), - screen_size: size, - available_screen_size: size, - hidpi_factor: dpr, + viewport: Box2D::from_origin_and_size(Point2D::zero(), inner_size), + framebuffer: inner_size, + window_rect: self.window_rect, + screen_size: self.screen_size, + available_screen_size: self.screen_size, + hidpi_factor: self.hidpi_factor(), } } diff --git a/ports/servoshell/egl/servo_glue.rs b/ports/servoshell/egl/servo_glue.rs index cc4f30667fd..dd9816cbce8 100644 --- a/ports/servoshell/egl/servo_glue.rs +++ b/ports/servoshell/egl/servo_glue.rs @@ -18,7 +18,7 @@ use servo::embedder_traits::{ ContextMenuResult, EmbedderMsg, EmbedderProxy, EventLoopWaker, MediaSessionEvent, PermissionPrompt, PermissionRequest, PromptDefinition, PromptOrigin, PromptResult, }; -use servo::euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; +use servo::euclid::{Box2D, Point2D, Rect, Scale, Size2D, Vector2D}; use servo::keyboard_types::{Key, KeyState, KeyboardEvent}; use servo::script_traits::{ MediaSessionActionType, MouseButton, TouchEventType, TouchId, TraversalDirection, @@ -691,12 +691,13 @@ impl EmbedderMethods for ServoEmbedderCallbacks { impl WindowMethods for ServoWindowCallbacks { fn get_coordinates(&self) -> EmbedderCoordinates { let coords = self.coordinates.borrow(); + let screen_size = (coords.viewport.size.to_f32() * Scale::new(self.density)).to_i32(); EmbedderCoordinates { viewport: coords.viewport.to_box2d(), framebuffer: coords.framebuffer, - window_rect: DeviceIntRect::from_origin_and_size(Point2D::zero(), coords.viewport.size), - screen_size: coords.viewport.size, - available_screen_size: coords.viewport.size, + window_rect: Box2D::from_origin_and_size(Point2D::zero(), screen_size), + screen_size, + available_screen_size: screen_size, hidpi_factor: Scale::new(self.density), } } diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index c82f0f6a6dc..c00f9dea53e 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -496873,7 +496873,7 @@ [] ], "executorservo.py": [ - "d8bb47be5f9259f793902a3157ae96a8954f8fb6", + "1d96ffa41da33c9b3c2650ee68c27174bf3081a6", [] ], "executorservodriver.py": [ diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservo.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservo.py index d8bb47be5f9..1d96ffa41da 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservo.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorservo.py @@ -230,7 +230,7 @@ class ServoRefTestExecutor(ServoExecutor): with TempFilename(self.tempdir) as output_path: extra_args = ["--exit", "--output=%s" % output_path, - "--resolution", viewport_size or "800x600"] + "--window-size", viewport_size or "800x600"] debug_opts = "disable-text-aa,load-webfonts-synchronously,replace-surrogates" if dpi: