From ec7677d6929ba4c0a5e053efcaf97b79f95f865f Mon Sep 17 00:00:00 2001 From: aloucks Date: Sun, 16 Mar 2025 21:27:27 -0400 Subject: [PATCH] Fix a pause in the event loop when clicking the title bar on windows (#4136) * Fix a pause in the event loop when clicking the title bar on windows When clicking the title bar on Windows, to drag the window, there is a noticible pause in continuous redraw requests. This was fixed in #839 and then regressed in #1852. The cursor blinks in both cases and is unrelated. The regression made the blink happen after the pause instead of immediately. * Update the event loop pause note on the WM_NCLBUTTONDOWN handler The application example was also updated to optionally animate the fill color in order to demonstrate continuous redraw without pauses in the event loop. --- src/changelog/unreleased.md | 4 ++++ src/platform_impl/windows/event_loop.rs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 52d4636bf..38650e80d 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -43,3 +43,7 @@ changelog entry. ### Added - On Windows, add `IconExtWindows::from_resource_name`. + +### Fixed + +- On Windows, fixed ~500 ms pause when clicking the title bar during continuous redraw. diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index fa912f6ce..1fe748c67 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1216,6 +1216,31 @@ unsafe fn public_window_callback_inner( WM_NCLBUTTONDOWN => { if wparam == HTCAPTION as _ { + // Prevent the user event loop from pausing when left clicking the title bar. + // + // When the user interacts with the title bar, Windows enters the modal event + // loop. Currently, a left click causes a pause for about 500ms. Sending a dummy + // mouse-move event seems to cancel the modal loop early, preventing the pause. + // The application will never see this dummy event. + // + // The mouse coordinates are encoded into the lparam value, however the WM_MOUSEMOVE + // event is not using the same coordinate system of the WM_NCLBUTTONDOWN event. + // One uses client-area coordinates and the other is screen-coordinates. In any + // case, passing the lparam as-is with the dummy event does not seem the cancel + // the modal loop. + // + // However, passing in a value of 0 has been observed to always cancel the pause. + // + // Other notes: + // + // For some unknown reason, the cursor will blink when clicking the title bar. + // Cancelling the modal loop early causes the blink to happen *immediately*. + // Otherwise, the blank happens *after* the pause. + // + // When right-click the title bar, the system window menu is presented to the user, + // and the modal event loop begins. This dummy event does *not* prevent the freeze + // in the main event loop caused by that popup menu. + let lparam = 0; unsafe { PostMessageW(window, WM_MOUSEMOVE, 0, lparam) }; } result = ProcResult::DefWindowProc(wparam);