From dec45ce0ff0d5e9aabcb28381ac6458cbc15b2f0 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 8 Nov 2023 16:21:33 +0100 Subject: [PATCH] On Windows, fix `set_control_flow` from `AboutToWait In case the AboutToWait event sets the control flow to another value it's not being used on this iteration. Fixes #3215. --- CHANGELOG.md | 1 + src/platform_impl/windows/event_loop.rs | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5be490485e..a0c8775bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Unreleased` header. - On X11, check common alternative cursor names when loading cursor. - On Windows, fix so `drag_window` and `drag_resize_window` can be called from another thread. +- On Windows, fix `set_control_flow` in `AboutToWait` not being taken in account. - On macOS, send a `Resized` event after each `ScaleFactorChanged` event. # 0.29.3 diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 2bedd9a4be..d4263920af 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -356,19 +356,6 @@ impl EventLoop { /// Wait for one message and dispatch it, optionally with a timeout fn wait_and_dispatch_message(&mut self, timeout: Option) { - let start = Instant::now(); - - let runner = &self.window_target.p.runner_shared; - - let control_flow_timeout = match runner.control_flow() { - ControlFlow::Wait => None, - ControlFlow::Poll => Some(Duration::ZERO), - ControlFlow::WaitUntil(wait_deadline) => { - Some(wait_deadline.saturating_duration_since(start)) - } - }; - let timeout = min_timeout(control_flow_timeout, timeout); - fn get_msg_with_timeout(msg: &mut MSG, timeout: Option) -> PumpStatus { unsafe { // A timeout of None means wait indefinitely (so we don't need to call SetTimer) @@ -404,6 +391,8 @@ impl EventLoop { } } + let runner = &self.window_target.p.runner_shared; + // We aim to be consistent with the MacOS backend which has a RunLoop // observer that will dispatch AboutToWait when about to wait for // events, and NewEvents after the RunLoop wakes up. @@ -415,6 +404,16 @@ impl EventLoop { // runner.prepare_wait(); + let control_flow_timeout = match runner.control_flow() { + ControlFlow::Wait => None, + ControlFlow::Poll => Some(Duration::ZERO), + ControlFlow::WaitUntil(wait_deadline) => { + let start = Instant::now(); + Some(wait_deadline.saturating_duration_since(start)) + } + }; + let timeout = min_timeout(control_flow_timeout, timeout); + // # Safety // The Windows API has no documented requirement for bitwise // initializing a `MSG` struct (it can be uninitialized memory for the C