Fix window freezing when dragged or resized on Windows (#18004)

# Objective

Fixes #17488

## Solution

The world update logic happened in the the `about_to_wait` winit window
callback, but this is is not correct as (1) the winit documentation
states that the callback should not be used for that purpose and (2) the
callback is not fired when the window is resized or being dragged.
However, that callback was used in #11245 to fix an iOS bug (which
caused the regression). The solution presented here is a workaround
until the event loop code can be re-written.

## Testing

I confirmed that the `eased_motion` example continued to be animated
when dragging or resizing the window.


https://github.com/user-attachments/assets/ffaf0abf-4cd7-479b-83e9-e1850aaf3513
This commit is contained in:
aloucks 2025-02-23 18:56:10 -05:00 committed by GitHub
parent 283654cf4d
commit 8122b35ce2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -431,6 +431,13 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
}
WindowEvent::RedrawRequested => {
self.ran_update_since_last_redraw = false;
// https://github.com/bevyengine/bevy/issues/17488
#[cfg(target_os = "windows")]
{
self.redraw_requested = true;
self.redraw_requested(_event_loop);
}
}
_ => {}
}
@ -468,6 +475,27 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
create_windows(event_loop, create_window.get_mut(self.world_mut()));
create_window.apply(self.world_mut());
// TODO: This is a workaround for https://github.com/bevyengine/bevy/issues/17488
// while preserving the iOS fix in https://github.com/bevyengine/bevy/pull/11245
// The monitor sync logic likely belongs in monitor event handlers and not here.
#[cfg(not(target_os = "windows"))]
self.redraw_requested(event_loop);
}
fn suspended(&mut self, _event_loop: &ActiveEventLoop) {
// Mark the state as `WillSuspend`. This will let the schedule run one last time
// before actually suspending to let the application react
self.lifecycle = AppLifecycle::WillSuspend;
}
fn exiting(&mut self, _event_loop: &ActiveEventLoop) {
let world = self.world_mut();
world.clear_all();
}
}
impl<T: Event> WinitAppRunnerState<T> {
fn redraw_requested(&mut self, event_loop: &ActiveEventLoop) {
let mut redraw_event_reader = EventCursor::<RequestRedraw>::default();
let mut focused_windows_state: SystemState<(Res<WinitSettings>, Query<(Entity, &Window)>)> =
@ -662,19 +690,6 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
}
}
fn suspended(&mut self, _event_loop: &ActiveEventLoop) {
// Mark the state as `WillSuspend`. This will let the schedule run one last time
// before actually suspending to let the application react
self.lifecycle = AppLifecycle::WillSuspend;
}
fn exiting(&mut self, _event_loop: &ActiveEventLoop) {
let world = self.world_mut();
world.clear_all();
}
}
impl<T: Event> WinitAppRunnerState<T> {
fn should_update(&self, update_mode: UpdateMode) -> bool {
let handle_event = match update_mode {
UpdateMode::Continuous => {