diff --git a/crates/gpui/src/platform/windows/dispatcher.rs b/crates/gpui/src/platform/windows/dispatcher.rs index f543202e77..dd53c86f5e 100644 --- a/crates/gpui/src/platform/windows/dispatcher.rs +++ b/crates/gpui/src/platform/windows/dispatcher.rs @@ -25,7 +25,7 @@ pub(crate) struct WindowsDispatcher { pub(crate) wake_posted: AtomicBool, main_sender: Sender, main_thread_id: ThreadId, - platform_window_handle: SafeHwnd, + pub(crate) platform_window_handle: SafeHwnd, validation_number: usize, } diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index 942cb62d22..548b08eca8 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -813,9 +813,28 @@ impl WindowsPlatformInner { #[inline] fn run_foreground_task(&self) -> Option { + const MAIN_TASK_TIMEOUT: u128 = 10; + + let start = std::time::Instant::now(); loop { - for runnable in self.main_receiver.drain() { - WindowsDispatcher::execute_runnable(runnable); + loop { + if start.elapsed().as_millis() >= MAIN_TASK_TIMEOUT { + // requeue main thread dispatch and bail, allowing more system messages to be processed + unsafe { + PostMessageW( + Some(self.dispatcher.platform_window_handle.as_raw()), + WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD, + WPARAM(self.validation_number), + LPARAM(0), + ) + .log_err(); + } + return Some(0); + } + match self.main_receiver.try_recv() { + Err(_) => break, + Ok(runnable) => WindowsDispatcher::execute_runnable(runnable), + } } // Someone could enqueue a Runnable here. The flag is still true, so they will not PostMessage.