servoshell: Sync window toolbar height with minibrowser (#38328)

Toolbar size can be changed if resized, such as entering fullscreen.
Hit-test had wrong offsets after fullscreen/resize as
`WindowEvent::CursorMoved` set wrong coordinates for
`webview_relative_mouse_point` due to outdated toolbar height.

Testing: #38297 now works properly.
Fixes: #38297

---------

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
This commit is contained in:
Euclid Ye 2025-08-04 03:16:15 +08:00 committed by GitHub
parent 874645ae86
commit f0eb6c2b97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 14 additions and 8 deletions

View file

@ -201,10 +201,8 @@ impl App {
webdriver_receiver,
));
running_state.create_and_focus_toplevel_webview(self.initial_url.clone().into_url());
if let Some(ref mut minibrowser) = self.minibrowser {
minibrowser.update(window.winit_window().unwrap(), &running_state, "init");
window.set_toolbar_height(minibrowser.toolbar_height);
minibrowser.update(window.as_ref(), &running_state, "init");
}
self.state = AppState::Running(running_state);
@ -683,7 +681,7 @@ impl ApplicationHandler<AppEvent> for App {
// WARNING: do not defer painting or presenting to some later tick of the event
// loop or servoshell may become unresponsive! (servo#30312)
if let Some(ref mut minibrowser) = self.minibrowser {
minibrowser.update(window.winit_window().unwrap(), state, "RedrawRequested");
minibrowser.update(window.as_ref(), state, "RedrawRequested");
minibrowser.paint(window.winit_window().unwrap());
}
}
@ -721,7 +719,7 @@ impl ApplicationHandler<AppEvent> for App {
// Update minibrowser if there's resize event to sync up with window.
if let WindowEvent::Resized(_) = event {
minibrowser.update(
window.winit_window().unwrap(),
window.as_ref(),
state,
"Sync WebView size with Window Resize event",
);

View file

@ -31,6 +31,7 @@ use super::egui_glue::EguiGlow;
use super::events_loop::EventLoopProxy;
use super::geometry::winit_position_to_euclid_point;
use super::headed_window::Window as ServoWindow;
use crate::desktop::window_trait::WindowPortsMethods;
pub struct Minibrowser {
rendering_context: Rc<OffscreenRenderingContext>,
@ -265,8 +266,14 @@ impl Minibrowser {
/// Update the minibrowser, but dont paint.
/// If `servo_framebuffer_id` is given, set up a paint callback to blit its contents to our
/// CentralPanel when [`Minibrowser::paint`] is called.
pub fn update(&mut self, window: &Window, state: &RunningAppState, reason: &'static str) {
pub fn update(
&mut self,
window: &dyn WindowPortsMethods,
state: &RunningAppState,
reason: &'static str,
) {
let now = Instant::now();
let winit_window = window.winit_window().unwrap();
trace!(
"{:?} since last update ({})",
now - self.last_update,
@ -283,10 +290,10 @@ impl Minibrowser {
..
} = self;
let _duration = context.run(window, |ctx| {
let _duration = context.run(winit_window, |ctx| {
// TODO: While in fullscreen add some way to mitigate the increased phishing risk
// when not displaying the URL bar: https://github.com/servo/servo/issues/32443
if window.fullscreen().is_none() {
if winit_window.fullscreen().is_none() {
let frame = egui::Frame::default()
.fill(ctx.style().visuals.window_fill)
.inner_margin(4.0);
@ -390,6 +397,7 @@ impl Minibrowser {
// For reasons that are unclear, the TopBottomPanels ui cursor exceeds this by one egui
// point, but the Context is correct and the TopBottomPanel is wrong.
*toolbar_height = Length::new(ctx.available_rect().min.y);
window.set_toolbar_height(*toolbar_height);
let scale =
Scale::<_, DeviceIndependentPixel, DevicePixel>::new(ctx.pixels_per_point());