From 226604cb186589023de2b088915fc660adf80f35 Mon Sep 17 00:00:00 2001 From: "Ngo Iok Ui (Wu Yu Wei)" Date: Fri, 1 Jul 2022 05:11:46 +0800 Subject: [PATCH] Revert "Remove most RedrawWindow to event target window (#427)" This reverts commit 5ca39af1117677b469f92a8094769610c01419ad. --- src/platform_impl/windows/event_loop.rs | 44 +++++++++---------- .../windows/event_loop/runner.rs | 23 +++------- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 747018818..fb87d64f7 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -2051,10 +2051,8 @@ unsafe extern "system" fn thread_event_target_callback( ) -> LRESULT { let subclass_input = Box::from_raw(subclass_input_ptr as *mut ThreadMsgTargetSubclassInput); - // Calling RedrawWindow will cause other window busy waiting. So we handle clear event directly - // as long as there's a thread event target message. if msg != WM_PAINT { - handle_clear_event(&subclass_input.event_loop_runner, window); + RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); } let mut subclass_removed = false; @@ -2072,8 +2070,25 @@ unsafe extern "system" fn thread_event_target_callback( // when the event queue has been emptied. See `process_event` for more details. win32wm::WM_PAINT => { ValidateRect(window, ptr::null()); - - handle_clear_event(&subclass_input.event_loop_runner, window); + // If the WM_PAINT handler in `public_window_callback` has already flushed the redraw + // events, `handling_events` will return false and we won't emit a second + // `RedrawEventsCleared` event. + if subclass_input.event_loop_runner.handling_events() { + if subclass_input.event_loop_runner.should_buffer() { + // This branch can be triggered when a nested win32 event loop is triggered + // inside of the `event_handler` callback. + RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); + } else { + // This WM_PAINT handler will never be re-entrant because `flush_paint_messages` + // doesn't call WM_PAINT for the thread event target (i.e. this window). + assert!(flush_paint_messages( + None, + &subclass_input.event_loop_runner + )); + subclass_input.event_loop_runner.redraw_events_cleared(); + process_control_flow(&subclass_input.event_loop_runner); + } + } // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. DefSubclassProc(window, msg, wparam, lparam) @@ -2341,22 +2356,3 @@ unsafe fn handle_raw_input( }); } } - -unsafe fn handle_clear_event(event_loop_runner: &EventLoopRunner, window: HWND) { - // If the WM_PAINT handler in `public_window_callback` has already flushed the redraw - // events, `handling_events` will return false and we won't emit a second - // `RedrawEventsCleared` event. - if event_loop_runner.handling_events() { - if event_loop_runner.should_buffer() { - // This branch can be triggered when a nested win32 event loop is triggered - // inside of the `event_handler` callback. - RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); - } else { - // This WM_PAINT handler will never be re-entrant because `flush_paint_messages` - // doesn't call WM_PAINT for the thread event target (i.e. this window). - assert!(flush_paint_messages(None, &event_loop_runner)); - event_loop_runner.redraw_events_cleared(); - process_control_flow(&event_loop_runner); - } - } -} diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index cce59f3b1..a5eb983ce 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -196,13 +196,6 @@ impl EventLoopRunner { owned_windows.extend(&new_owned_windows); self.owned_windows.set(owned_windows); } - - pub fn no_owned_windows(&self) -> bool { - let owned_windows = self.owned_windows.take(); - let result = owned_windows.is_empty(); - self.owned_windows.set(owned_windows); - result - } } /// Event dispatch functions. @@ -401,16 +394,12 @@ impl EventLoopRunner { }; self.call_event_handler(Event::NewEvents(start_cause)); self.dispatch_buffered_events(); - // Calling RedrawWindow will cause other window busy waiting. So we only call it when - // there's no window. - if self.no_owned_windows() { - RedrawWindow( - self.thread_msg_target, - ptr::null(), - HRGN::default(), - RDW_INTERNALPAINT, - ); - } + RedrawWindow( + self.thread_msg_target, + ptr::null(), + HRGN::default(), + RDW_INTERNALPAINT, + ); } unsafe fn call_redraw_events_cleared(&self) {