diff --git a/ports/servoshell/headless_window.rs b/ports/servoshell/headless_window.rs index ba87ffd388c..308a85120ce 100644 --- a/ports/servoshell/headless_window.rs +++ b/ports/servoshell/headless_window.rs @@ -6,15 +6,17 @@ use std::cell::Cell; use std::rc::Rc; +use std::sync::RwLock; use euclid::{Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; +use log::warn; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderEvent, WindowMethods, }; use servo::rendering_context::RenderingContext; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; -use servo::webrender_api::units::DeviceIntRect; +use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize}; use surfman::{Connection, Context, Device, SurfaceType}; use crate::events_loop::WakerEvent; @@ -25,6 +27,8 @@ pub struct Window { animation_state: Cell, fullscreen: Cell, device_pixel_ratio_override: Option, + inner_size: Cell>, + event_queue: RwLock>, } impl Window { @@ -47,6 +51,8 @@ impl Window { animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), device_pixel_ratio_override, + inner_size: Cell::new(size.to_i32()), + event_queue: RwLock::new(Vec::new()), }; Rc::new(window) @@ -55,17 +61,44 @@ impl Window { impl WindowPortsMethods for Window { fn get_events(&self) -> Vec { - vec![] + match self.event_queue.write() { + Ok(ref mut event_queue) => std::mem::take(event_queue), + Err(_) => vec![], + } } fn has_events(&self) -> bool { - false + self.event_queue + .read() + .ok() + .map(|queue| !queue.is_empty()) + .unwrap_or(false) } fn id(&self) -> winit::window::WindowId { unsafe { winit::window::WindowId::dummy() } } + fn set_inner_size(&self, size: DeviceIntSize) { + let (width, height) = size.into(); + + // Surfman doesn't support zero-sized surfaces. + let new_size = Size2D::new(width.max(1), height.max(1)); + if self.inner_size.get() == new_size { + return; + } + + match self.rendering_context.resize(new_size.to_untyped()) { + Ok(()) => { + self.inner_size.set(new_size); + if let Ok(ref mut queue) = self.event_queue.write() { + queue.push(EmbedderEvent::Resize); + } + }, + Err(error) => warn!("Could not resize window: {error:?}"), + } + } + fn device_hidpi_factor(&self) -> Scale { Scale::new(1.0) } diff --git a/ports/servoshell/window_trait.rs b/ports/servoshell/window_trait.rs index 2babc09883d..bc31ef396e3 100644 --- a/ports/servoshell/window_trait.rs +++ b/ports/servoshell/window_trait.rs @@ -38,7 +38,7 @@ pub trait WindowPortsMethods: WindowMethods { fn queue_embedder_events_for_winit_event(&self, event: winit::event::WindowEvent<'_>); fn is_animating(&self) -> bool; fn set_title(&self, _title: &str) {} - fn set_inner_size(&self, _size: DeviceIntSize) {} + fn set_inner_size(&self, _size: DeviceIntSize); fn set_position(&self, _point: DeviceIntPoint) {} fn set_fullscreen(&self, _state: bool) {} fn set_cursor(&self, _cursor: Cursor) {} diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 6dd9129a031..73b7326bb53 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -14142,6 +14142,13 @@ {} ] ], + "window_resizeTo.html": [ + "87d60498e80bcd01b5790feb3f9e104410cb6e1b", + [ + null, + {} + ] + ], "window_resize_not_triggered_on_load.html": [ "f551f67ee91f25c7e05c868dbbcad5cb11c93645", [ diff --git a/tests/wpt/mozilla/tests/mozilla/window_resizeTo.html b/tests/wpt/mozilla/tests/mozilla/window_resizeTo.html new file mode 100644 index 00000000000..87d60498e80 --- /dev/null +++ b/tests/wpt/mozilla/tests/mozilla/window_resizeTo.html @@ -0,0 +1,16 @@ + + +Verify that the resize event is fired when the window is resized (particularly in headless mode) + + +