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::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<AnimationState>,
fullscreen: Cell<bool>,
device_pixel_ratio_override: Option<f32>,
inner_size: Cell<Size2D<i32, UnknownUnit>>,
event_queue: RwLock<Vec<EmbedderEvent>>,
}
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<EmbedderEvent> {
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<f32, DeviceIndependentPixel, DevicePixel> {
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 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) {}

View file

@ -14142,6 +14142,13 @@
{}
]
],
"window_resizeTo.html": [
"87d60498e80bcd01b5790feb3f9e104410cb6e1b",
[
null,
{}
]
],
"window_resize_not_triggered_on_load.html": [
"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>