From 6964cecc149e14eb9f000ca66412b1b9af09ca81 Mon Sep 17 00:00:00 2001 From: Junkui Zhang <364772080@qq.com> Date: Wed, 23 Jul 2025 23:28:05 +0800 Subject: [PATCH] ensure app is idle --- crates/gpui/src/platform.rs | 2 +- crates/gpui/src/platform/windows/events.rs | 17 ++++++++++++++--- crates/gpui/src/platform/windows/window.rs | 6 +++--- crates/gpui/src/window.rs | 6 +++++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index f0b9be68bb09bf7b9f00b667b4e4c28d1cf08b98..633a62fb44a22a72d773a2aabde1926a32cfa6ae 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -479,7 +479,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle { fn zoom(&self); fn toggle_fullscreen(&self); fn is_fullscreen(&self) -> bool; - fn on_request_frame(&self, callback: Box); + fn on_request_frame(&self, callback: Box bool>); fn on_input(&self, callback: Box DispatchEventResult>); fn on_active_status_change(&self, callback: Box); fn on_hover_status_change(&self, callback: Box); diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index 6fd899cbef864a5ff019e4496d3768345208dad5..ebacf8e96515a0c6e35cf161bc45a521ca7b1571 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -237,12 +237,23 @@ fn handle_timer_msg( fn handle_paint_msg(handle: HWND, state_ptr: Rc) -> Option { let mut lock = state_ptr.state.borrow_mut(); - if let Some(mut request_frame) = lock.callbacks.request_frame.take() { + let is_idle = if let Some(mut request_frame) = lock.callbacks.request_frame.take() { drop(lock); - request_frame(Default::default()); + // request_frame(RequestFrameOptions { + // require_presentation: true, + // }); + let is_idle = request_frame(Default::default()); state_ptr.state.borrow_mut().callbacks.request_frame = Some(request_frame); - } + is_idle + } else { + false + }; unsafe { ValidateRect(Some(handle), None).ok().log_err() }; + if is_idle { + unsafe { + MsgWaitForMultipleObjects(None, false, 100, QS_ALLINPUT); + } + } Some(0) } diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index 159cb6d95f876da130fec03e6f69e34437c6bab9..8e073a0a6986de00ec2f5ee12abd258e44808c11 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -38,7 +38,7 @@ pub struct WindowsWindowState { pub border_offset: WindowBorderOffset, pub appearance: WindowAppearance, pub scale_factor: f32, - pub restore_from_minimized: Option>, + pub restore_from_minimized: Option bool>>, pub callbacks: Callbacks, pub input_handler: Option, @@ -312,7 +312,7 @@ impl WindowsWindowStatePtr { #[derive(Default)] pub(crate) struct Callbacks { - pub(crate) request_frame: Option>, + pub(crate) request_frame: Option bool>>, pub(crate) input: Option DispatchEventResult>>, pub(crate) active_status_change: Option>, pub(crate) hovered_status_change: Option>, @@ -734,7 +734,7 @@ impl PlatformWindow for WindowsWindow { self.0.state.borrow().is_fullscreen() } - fn on_request_frame(&self, callback: Box) { + fn on_request_frame(&self, callback: Box bool>) { self.0.state.borrow_mut().callbacks.request_frame = Some(callback); } diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 963d2bb45c437e98d7a56587dedd7ff56827a56f..af873b12d895441c5fc034fea64f1bbf7b0eb16b 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -1012,6 +1012,7 @@ impl Window { .log_err(); } + let invalidator_is_dirty = invalidator.is_dirty(); // Keep presenting the current scene for 1 extra second since the // last input to prevent the display from underclocking the refresh rate. let needs_present = request_frame_options.require_presentation @@ -1019,7 +1020,7 @@ impl Window { || (active.get() && last_input_timestamp.get().elapsed() < Duration::from_secs(1)); - if invalidator.is_dirty() { + if invalidator_is_dirty { measure("frame duration", || { handle .update(&mut cx, |_, window, cx| { @@ -1041,6 +1042,9 @@ impl Window { window.complete_frame(); }) .log_err(); + + // Return true if app is idle + !(invalidator_is_dirty || needs_present) } })); platform_window.on_resize(Box::new({