ensure app is idle
This commit is contained in:
parent
63daf44693
commit
6964cecc14
4 changed files with 23 additions and 8 deletions
|
@ -479,7 +479,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {
|
||||||
fn zoom(&self);
|
fn zoom(&self);
|
||||||
fn toggle_fullscreen(&self);
|
fn toggle_fullscreen(&self);
|
||||||
fn is_fullscreen(&self) -> bool;
|
fn is_fullscreen(&self) -> bool;
|
||||||
fn on_request_frame(&self, callback: Box<dyn FnMut(RequestFrameOptions)>);
|
fn on_request_frame(&self, callback: Box<dyn FnMut(RequestFrameOptions) -> bool>);
|
||||||
fn on_input(&self, callback: Box<dyn FnMut(PlatformInput) -> DispatchEventResult>);
|
fn on_input(&self, callback: Box<dyn FnMut(PlatformInput) -> DispatchEventResult>);
|
||||||
fn on_active_status_change(&self, callback: Box<dyn FnMut(bool)>);
|
fn on_active_status_change(&self, callback: Box<dyn FnMut(bool)>);
|
||||||
fn on_hover_status_change(&self, callback: Box<dyn FnMut(bool)>);
|
fn on_hover_status_change(&self, callback: Box<dyn FnMut(bool)>);
|
||||||
|
|
|
@ -237,12 +237,23 @@ fn handle_timer_msg(
|
||||||
|
|
||||||
fn handle_paint_msg(handle: HWND, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
fn handle_paint_msg(handle: HWND, state_ptr: Rc<WindowsWindowStatePtr>) -> Option<isize> {
|
||||||
let mut lock = state_ptr.state.borrow_mut();
|
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);
|
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);
|
state_ptr.state.borrow_mut().callbacks.request_frame = Some(request_frame);
|
||||||
}
|
is_idle
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
unsafe { ValidateRect(Some(handle), None).ok().log_err() };
|
unsafe { ValidateRect(Some(handle), None).ok().log_err() };
|
||||||
|
if is_idle {
|
||||||
|
unsafe {
|
||||||
|
MsgWaitForMultipleObjects(None, false, 100, QS_ALLINPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(0)
|
Some(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub struct WindowsWindowState {
|
||||||
pub border_offset: WindowBorderOffset,
|
pub border_offset: WindowBorderOffset,
|
||||||
pub appearance: WindowAppearance,
|
pub appearance: WindowAppearance,
|
||||||
pub scale_factor: f32,
|
pub scale_factor: f32,
|
||||||
pub restore_from_minimized: Option<Box<dyn FnMut(RequestFrameOptions)>>,
|
pub restore_from_minimized: Option<Box<dyn FnMut(RequestFrameOptions) -> bool>>,
|
||||||
|
|
||||||
pub callbacks: Callbacks,
|
pub callbacks: Callbacks,
|
||||||
pub input_handler: Option<PlatformInputHandler>,
|
pub input_handler: Option<PlatformInputHandler>,
|
||||||
|
@ -312,7 +312,7 @@ impl WindowsWindowStatePtr {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct Callbacks {
|
pub(crate) struct Callbacks {
|
||||||
pub(crate) request_frame: Option<Box<dyn FnMut(RequestFrameOptions)>>,
|
pub(crate) request_frame: Option<Box<dyn FnMut(RequestFrameOptions) -> bool>>,
|
||||||
pub(crate) input: Option<Box<dyn FnMut(crate::PlatformInput) -> DispatchEventResult>>,
|
pub(crate) input: Option<Box<dyn FnMut(crate::PlatformInput) -> DispatchEventResult>>,
|
||||||
pub(crate) active_status_change: Option<Box<dyn FnMut(bool)>>,
|
pub(crate) active_status_change: Option<Box<dyn FnMut(bool)>>,
|
||||||
pub(crate) hovered_status_change: Option<Box<dyn FnMut(bool)>>,
|
pub(crate) hovered_status_change: Option<Box<dyn FnMut(bool)>>,
|
||||||
|
@ -734,7 +734,7 @@ impl PlatformWindow for WindowsWindow {
|
||||||
self.0.state.borrow().is_fullscreen()
|
self.0.state.borrow().is_fullscreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_request_frame(&self, callback: Box<dyn FnMut(RequestFrameOptions)>) {
|
fn on_request_frame(&self, callback: Box<dyn FnMut(RequestFrameOptions) -> bool>) {
|
||||||
self.0.state.borrow_mut().callbacks.request_frame = Some(callback);
|
self.0.state.borrow_mut().callbacks.request_frame = Some(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1012,6 +1012,7 @@ impl Window {
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let invalidator_is_dirty = invalidator.is_dirty();
|
||||||
// Keep presenting the current scene for 1 extra second since the
|
// Keep presenting the current scene for 1 extra second since the
|
||||||
// last input to prevent the display from underclocking the refresh rate.
|
// last input to prevent the display from underclocking the refresh rate.
|
||||||
let needs_present = request_frame_options.require_presentation
|
let needs_present = request_frame_options.require_presentation
|
||||||
|
@ -1019,7 +1020,7 @@ impl Window {
|
||||||
|| (active.get()
|
|| (active.get()
|
||||||
&& last_input_timestamp.get().elapsed() < Duration::from_secs(1));
|
&& last_input_timestamp.get().elapsed() < Duration::from_secs(1));
|
||||||
|
|
||||||
if invalidator.is_dirty() {
|
if invalidator_is_dirty {
|
||||||
measure("frame duration", || {
|
measure("frame duration", || {
|
||||||
handle
|
handle
|
||||||
.update(&mut cx, |_, window, cx| {
|
.update(&mut cx, |_, window, cx| {
|
||||||
|
@ -1041,6 +1042,9 @@ impl Window {
|
||||||
window.complete_frame();
|
window.complete_frame();
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
|
|
||||||
|
// Return true if app is idle
|
||||||
|
!(invalidator_is_dirty || needs_present)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
platform_window.on_resize(Box::new({
|
platform_window.on_resize(Box::new({
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue