gpui(windows): Only poll PAINT messages twice in foreground task timeout (#43883)

Lukas Wirth created

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/gpui/src/platform/windows/platform.rs | 23 +++++++++++++++++----
1 file changed, 18 insertions(+), 5 deletions(-)

Detailed changes

crates/gpui/src/platform/windows/platform.rs 🔗

@@ -822,12 +822,25 @@ impl WindowsPlatformInner {
                     // we spent our budget on gpui tasks, we likely have a lot of work queued so drain system events first
                     // before returning to main thread task work
                     let mut msg = MSG::default();
-                    let peek_msg_type = PM_REMOVE | PM_QS_INPUT | PM_QS_PAINT;
-                    while unsafe { PeekMessageW(&mut msg, None, 0, 0, peek_msg_type) }.as_bool() {
-                        if translate_accelerator(&msg).is_none() {
-                            _ = unsafe { TranslateMessage(&msg) };
-                            unsafe { DispatchMessageW(&msg) };
+                    let process_message = |msg: &_| {
+                        if translate_accelerator(msg).is_none() {
+                            _ = unsafe { TranslateMessage(msg) };
+                            unsafe { DispatchMessageW(msg) };
                         }
+                    };
+                    let peek_msg = |msg: &mut _, msg_kind| unsafe {
+                        PeekMessageW(msg, None, 0, 0, PM_REMOVE | msg_kind).as_bool()
+                    };
+                    // We process a paint at the start and end only to prevent getting stuck in a paint loop
+                    // due to on going gpui animations
+                    if peek_msg(&mut msg, PM_QS_PAINT) {
+                        process_message(&msg);
+                    }
+                    while peek_msg(&mut msg, PM_QS_INPUT) {
+                        process_message(&msg);
+                    }
+                    if peek_msg(&mut msg, PM_QS_PAINT) {
+                        process_message(&msg);
                     }
                 }
                 match self.main_receiver.try_recv() {