Fix resize event is not fired for window in headless mode (#26194)

Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Daniel Alley 2024-02-16 05:54:36 -05:00 committed by GitHub
parent aeb2503fdb
commit faaf9e9323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 4 deletions

View file

@ -6,15 +6,17 @@
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
use std::sync::RwLock;
use euclid::{Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; use euclid::{Length, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D};
use log::warn;
use servo::compositing::windowing::{ use servo::compositing::windowing::{
AnimationState, EmbedderCoordinates, EmbedderEvent, WindowMethods, AnimationState, EmbedderCoordinates, EmbedderEvent, WindowMethods,
}; };
use servo::rendering_context::RenderingContext; use servo::rendering_context::RenderingContext;
use servo::servo_geometry::DeviceIndependentPixel; use servo::servo_geometry::DeviceIndependentPixel;
use servo::style_traits::DevicePixel; 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 surfman::{Connection, Context, Device, SurfaceType};
use crate::events_loop::WakerEvent; use crate::events_loop::WakerEvent;
@ -25,6 +27,8 @@ pub struct Window {
animation_state: Cell<AnimationState>, animation_state: Cell<AnimationState>,
fullscreen: Cell<bool>, fullscreen: Cell<bool>,
device_pixel_ratio_override: Option<f32>, device_pixel_ratio_override: Option<f32>,
inner_size: Cell<Size2D<i32, UnknownUnit>>,
event_queue: RwLock<Vec<EmbedderEvent>>,
} }
impl Window { impl Window {
@ -47,6 +51,8 @@ impl Window {
animation_state: Cell::new(AnimationState::Idle), animation_state: Cell::new(AnimationState::Idle),
fullscreen: Cell::new(false), fullscreen: Cell::new(false),
device_pixel_ratio_override, device_pixel_ratio_override,
inner_size: Cell::new(size.to_i32()),
event_queue: RwLock::new(Vec::new()),
}; };
Rc::new(window) Rc::new(window)
@ -55,17 +61,44 @@ impl Window {
impl WindowPortsMethods for Window { impl WindowPortsMethods for Window {
fn get_events(&self) -> Vec<EmbedderEvent> { fn get_events(&self) -> Vec<EmbedderEvent> {
vec![] match self.event_queue.write() {
Ok(ref mut event_queue) => std::mem::take(event_queue),
Err(_) => vec![],
}
} }
fn has_events(&self) -> bool { 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 { fn id(&self) -> winit::window::WindowId {
unsafe { winit::window::WindowId::dummy() } 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<f32, DeviceIndependentPixel, DevicePixel> { fn device_hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> {
Scale::new(1.0) Scale::new(1.0)
} }

View file

@ -38,7 +38,7 @@ pub trait WindowPortsMethods: WindowMethods {
fn queue_embedder_events_for_winit_event(&self, event: winit::event::WindowEvent<'_>); fn queue_embedder_events_for_winit_event(&self, event: winit::event::WindowEvent<'_>);
fn is_animating(&self) -> bool; fn is_animating(&self) -> bool;
fn set_title(&self, _title: &str) {} 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_position(&self, _point: DeviceIntPoint) {}
fn set_fullscreen(&self, _state: bool) {} fn set_fullscreen(&self, _state: bool) {}
fn set_cursor(&self, _cursor: Cursor) {} fn set_cursor(&self, _cursor: Cursor) {}

View file

@ -14142,6 +14142,13 @@
{} {}
] ]
], ],
"window_resizeTo.html": [
"87d60498e80bcd01b5790feb3f9e104410cb6e1b",
[
null,
{}
]
],
"window_resize_not_triggered_on_load.html": [ "window_resize_not_triggered_on_load.html": [
"f551f67ee91f25c7e05c868dbbcad5cb11c93645", "f551f67ee91f25c7e05c868dbbcad5cb11c93645",
[ [

View file

@ -0,0 +1,16 @@
<!doctype html>
<meta charset="utf-8">
<title>Verify that the resize event is fired when the window is resized (particularly in headless mode)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(function (t) {
window.onresize = t.step_func(function () {
assert_equals(window.innerWidth, 200);
assert_equals(window.innerHeight, 200);
t.done();
});
window.resizeTo(200, 200);
}, "onresize");
</script>