[windows] Use the PeekMessage trick to make timers less laggy.
@@ -27,9 +27,9 @@ use winapi::shared::winerror::HRESULT_FROM_WIN32;
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::shellscalingapi::PROCESS_PER_MONITOR_DPI_AWARE;
use winapi::um::winuser::{
- DispatchMessageW, GetAncestor, GetMessageW, LoadIconW, PostMessageW, PostQuitMessage,
- RegisterClassW, SendMessageW, TranslateAcceleratorW, TranslateMessage, GA_ROOT,
- IDI_APPLICATION, MSG, WNDCLASSW,
+ DispatchMessageW, GetAncestor, GetMessageW, LoadIconW, PeekMessageW, PostMessageW,
+ PostQuitMessage, RegisterClassW, SendMessageW, TranslateAcceleratorW, TranslateMessage,
+ GA_ROOT, IDI_APPLICATION, MSG, PM_NOREMOVE, WM_TIMER, WNDCLASSW,
};
use crate::application::AppHandler;
@@ -107,7 +107,10 @@ impl Application {
pub fn run(self, _handler: Option<Box<dyn AppHandler>>) {
unsafe {
- // Handle windows messages
+ // Handle windows messages.
+ //
+ // NOTE: Code here will not run when we aren't in charge of the message loop. That
+ // will include when moving or resizing the window, and when showing modal dialogs.
loop {
if let Ok(state) = self.state.try_borrow() {
for hwnd in &state.windows {
@@ -115,6 +118,18 @@ impl Application {
}
}
let mut msg = mem::MaybeUninit::uninit();
+
+ // Timer messages have a low priority and tend to get delayed. Peeking for them
+ // helps for some reason; see
+ // https://devblogs.microsoft.com/oldnewthing/20191108-00/?p=103080
+ PeekMessageW(
+ msg.as_mut_ptr(),
+ ptr::null_mut(),
+ WM_TIMER,
+ WM_TIMER,
+ PM_NOREMOVE,
+ );
+
let res = GetMessageW(msg.as_mut_ptr(), ptr::null_mut(), 0, 0);
if res <= 0 {
if res == -1 {
