From d5608162def4688052c75e43f5d1b04268af4d06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 21 Oct 2025 23:56:06 +0200 Subject: [PATCH] Try to fix window resize race conditons during `RedrawRequested` --- winit/src/lib.rs | 37 +++++++++++++++++++++++++++++-------- winit/src/window.rs | 11 +++++------ winit/src/window/state.rs | 26 +++----------------------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 32c05649..75269d6a 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -785,22 +785,20 @@ async fn run_instance

( }; let physical_size = window.state.physical_size(); + let mut logical_size = window.state.logical_size(); if physical_size.width == 0 || physical_size.height == 0 { continue; } - if window.viewport_version - != window.state.viewport_version() - { - let logical_size = window.state.logical_size(); - - let layout_span = debug::layout(id); + // Window was resized between redraws + if window.surface_size != physical_size { let ui = user_interfaces .remove(&id) .expect("Remove user interface"); + let layout_span = debug::layout(id); let _ = user_interfaces.insert( id, ui.relayout(logical_size, &mut window.renderer), @@ -813,8 +811,7 @@ async fn run_instance

( physical_size.height, ); - window.viewport_version = - window.state.viewport_version(); + window.surface_size = physical_size; } let redraw_event = core::Event::Window( @@ -922,6 +919,30 @@ async fn run_instance

( current_compositor = next_compositor; window = window_manager.get_mut(id).unwrap(); + + // Window scale factor changed during a redraw request + if logical_size != window.state.logical_size() { + logical_size = window.state.logical_size(); + + log::debug!( + "Window scale factor changed during a redraw request" + ); + + let ui = user_interfaces + .remove(&id) + .expect("Remove user interface"); + + let layout_span = debug::layout(id); + let _ = user_interfaces.insert( + id, + ui.relayout( + logical_size, + &mut window.renderer, + ), + ); + layout_span.finish(); + } + interface = user_interfaces.get_mut(&id).unwrap(); } diff --git a/winit/src/window.rs b/winit/src/window.rs index a1e8c8b3..5d66913f 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -57,12 +57,11 @@ where system_theme: theme::Mode, ) -> &mut Window { let state = State::new(program, id, &window, system_theme); - let viewport_version = state.viewport_version(); - let physical_size = state.physical_size(); + let surface_size = state.physical_size(); let surface = compositor.create_surface( window.clone(), - physical_size.width, - physical_size.height, + surface_size.width, + surface_size.height, ); let renderer = compositor.create_renderer(); @@ -73,9 +72,9 @@ where Window { raw: window, state, - viewport_version, exit_on_close_request, surface, + surface_size, renderer, mouse_interaction: mouse::Interaction::None, redraw_at: None, @@ -164,10 +163,10 @@ where { pub raw: Arc, pub state: State

, - pub viewport_version: u64, pub exit_on_close_request: bool, pub mouse_interaction: mouse::Interaction, pub surface: C::Surface, + pub surface_size: Size, pub renderer: P::Renderer, pub redraw_at: Option, preedit: Option>, diff --git a/winit/src/window/state.rs b/winit/src/window/state.rs index 4c3cb403..042e37be 100644 --- a/winit/src/window/state.rs +++ b/winit/src/window/state.rs @@ -17,7 +17,6 @@ where title: String, scale_factor: f32, viewport: Viewport, - viewport_version: u64, cursor_position: Option>, modifiers: winit::keyboard::ModifiersState, theme: Option, @@ -35,7 +34,6 @@ where .field("title", &self.title) .field("scale_factor", &self.scale_factor) .field("viewport", &self.viewport) - .field("viewport_version", &self.viewport_version) .field("cursor_position", &self.cursor_position) .field("style", &self.style) .finish() @@ -74,7 +72,6 @@ where title, scale_factor, viewport, - viewport_version: 0, cursor_position: None, modifiers: winit::keyboard::ModifiersState::default(), theme, @@ -89,13 +86,6 @@ where &self.viewport } - /// Returns the version of the [`Viewport`] of the [`State`]. - /// - /// The version is incremented every time the [`Viewport`] changes. - pub fn viewport_version(&self) -> u64 { - self.viewport_version - } - /// Returns the physical [`Size`] of the [`Viewport`] of the [`State`]. pub fn physical_size(&self) -> Size { self.viewport.physical_size() @@ -164,8 +154,6 @@ where size, window.scale_factor() as f32 * self.scale_factor, ); - - self.viewport_version = self.viewport_version.wrapping_add(1); } WindowEvent::ScaleFactorChanged { scale_factor: new_scale_factor, @@ -177,8 +165,6 @@ where size, *new_scale_factor as f32 * self.scale_factor, ); - - self.viewport_version = self.viewport_version.wrapping_add(1); } WindowEvent::CursorMoved { position, .. } | WindowEvent::Touch(Touch { @@ -225,20 +211,14 @@ where self.title = new_title; } - // Update scale factor and size + // Update scale factor let new_scale_factor = program.scale_factor(window_id); - let new_size = window.inner_size(); - let current_size = self.viewport.physical_size(); - if self.scale_factor != new_scale_factor - || (current_size.width, current_size.height) - != (new_size.width, new_size.height) - { + if self.scale_factor != new_scale_factor { self.viewport = Viewport::with_physical_size( - Size::new(new_size.width, new_size.height), + self.viewport.physical_size(), window.scale_factor() as f32 * new_scale_factor, ); - self.viewport_version = self.viewport_version.wrapping_add(1); self.scale_factor = new_scale_factor; }