From aaf04883dd025dd9288679e6b763b0f27c179f2a Mon Sep 17 00:00:00 2001 From: Euclid Ye Date: Fri, 4 Jul 2025 16:10:58 +0800 Subject: [PATCH] servoshell: Make `fn request_resize` resize window w.r.t. outer_size accurately (#37848) `toolbar_height` is already part of `inner_size`, caused wrongly calculated `outer_size`. Even worse, it tried to `request_inner_size` with the already wrong `outer_size`. This PR make sure resize is accurate by first calculate the title/border height, and then compute the `inner_size` for `request_inner_size`. This is necessary because no direct `request_outer_size` is available. Testing: As manually tested, set window size WebDriver command no longer overshoot. This is also shared by [window.resizeTo](https://drafts.csswg.org/cssom-view/#dom-window-resizeto) JS method. WPT test would be necessary. (But that one is intermittent TIMEOUT. So created new one in https://github.com/servo/servo/pull/37856) WebDriver test will be postponed after https://github.com/web-platform-tests/wpt/pull/53421 is merged and synced to Servo. Fixes: Task 3 of https://github.com/servo/servo/issues/37804 --------- Signed-off-by: Euclid Ye --- ports/servoshell/desktop/app_state.rs | 6 +++--- ports/servoshell/desktop/headed_window.rs | 11 +++++------ ports/servoshell/desktop/window_trait.rs | 5 +++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ports/servoshell/desktop/app_state.rs b/ports/servoshell/desktop/app_state.rs index 5bd5ef42fb8..380b2435aca 100644 --- a/ports/servoshell/desktop/app_state.rs +++ b/ports/servoshell/desktop/app_state.rs @@ -444,11 +444,11 @@ impl WebViewDelegate for RunningAppState { self.inner().window.set_position(new_position); } - fn request_resize_to(&self, webview: servo::WebView, new_size: DeviceIntSize) { + fn request_resize_to(&self, webview: servo::WebView, new_outer_size: DeviceIntSize) { let mut rect = webview.rect(); - rect.set_size(new_size.to_f32()); + rect.set_size(new_outer_size.to_f32()); webview.move_resize(rect); - self.inner().window.request_resize(&webview, new_size); + self.inner().window.request_resize(&webview, new_outer_size); } fn show_simple_dialog(&self, webview: servo::WebView, dialog: SimpleDialog) { diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs index 341b8c12e67..e0d3124e804 100644 --- a/ports/servoshell/desktop/headed_window.rs +++ b/ports/servoshell/desktop/headed_window.rs @@ -466,14 +466,13 @@ impl WindowPortsMethods for Window { self.winit_window.set_title(title); } - fn request_resize(&self, _: &WebView, size: DeviceIntSize) -> Option { - let toolbar_height = self.toolbar_height() * self.hidpi_scale_factor(); - let toolbar_height = toolbar_height.get().ceil() as i32; - let total_size = PhysicalSize::new(size.width, size.height + toolbar_height); + fn request_resize(&self, _: &WebView, new_outer_size: DeviceIntSize) -> Option { + let title_height = + self.winit_window.outer_size().height - self.winit_window.inner_size().height; self.winit_window .request_inner_size::>(PhysicalSize::new( - total_size.width, - total_size.height, + new_outer_size.width, + new_outer_size.height - title_height as i32, )) .and_then(|size| { Some(DeviceIntSize::new( diff --git a/ports/servoshell/desktop/window_trait.rs b/ports/servoshell/desktop/window_trait.rs index 233c90cb5a5..1ef83443adf 100644 --- a/ports/servoshell/desktop/window_trait.rs +++ b/ports/servoshell/desktop/window_trait.rs @@ -26,8 +26,9 @@ pub trait WindowPortsMethods { fn get_fullscreen(&self) -> bool; fn handle_winit_event(&self, state: Rc, event: winit::event::WindowEvent); fn set_title(&self, _title: &str) {} - /// Request a new inner size for the window, not including external decorations. - fn request_resize(&self, webview: &WebView, inner_size: DeviceIntSize) + /// Request a new outer size for the window, including external decorations. + /// This should be the same as `window.outerWidth` and `window.outerHeight`` + fn request_resize(&self, webview: &WebView, outer_size: DeviceIntSize) -> Option; fn set_position(&self, _point: DeviceIntPoint) {} fn set_fullscreen(&self, _state: bool) {}