From 6adc1d13bd3acf3cecb323e317d81556e56a30f1 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Sun, 19 Jun 2022 00:12:18 +0800 Subject: [PATCH 1/3] Remove most RedrawWindow to event tartget window --- src/platform_impl/windows/event_loop.rs | 6 +++--- src/platform_impl/windows/event_loop/runner.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index ffc5bfd3d..741eccc56 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -2018,9 +2018,9 @@ unsafe extern "system" fn thread_event_target_callback( ) -> LRESULT { let subclass_input = Box::from_raw(subclass_input_ptr as *mut ThreadMsgTargetSubclassInput); - if msg != WM_PAINT { - RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); - } + // if msg != WM_PAINT { + // RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); + // } let mut subclass_removed = false; diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index a5eb983ce..7f269b35c 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -394,12 +394,12 @@ impl EventLoopRunner { }; self.call_event_handler(Event::NewEvents(start_cause)); self.dispatch_buffered_events(); - 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) { From 298453729fde38b52864176e6815d502f1196d16 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Mon, 20 Jun 2022 20:07:26 +0800 Subject: [PATCH 2/3] Add workaround to handle clear event --- src/platform_impl/windows/event_loop.rs | 48 ++++++++++--------- .../windows/event_loop/runner.rs | 23 ++++++--- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 741eccc56..4f11e01dd 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -2018,9 +2018,11 @@ unsafe extern "system" fn thread_event_target_callback( ) -> LRESULT { let subclass_input = Box::from_raw(subclass_input_ptr as *mut ThreadMsgTargetSubclassInput); - // if msg != WM_PAINT { - // RedrawWindow(window, ptr::null(), HRGN::default(), RDW_INTERNALPAINT); - // } + // 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); + } let mut subclass_removed = false; @@ -2037,25 +2039,8 @@ 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()); - // 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); - } - } + + handle_clear_event(&subclass_input.event_loop_runner, window); // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. DefSubclassProc(window, msg, wparam, lparam) @@ -2323,3 +2308,22 @@ 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 7f269b35c..cce59f3b1 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -196,6 +196,13 @@ 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. @@ -394,12 +401,16 @@ impl EventLoopRunner { }; self.call_event_handler(Event::NewEvents(start_cause)); self.dispatch_buffered_events(); - // RedrawWindow( - // self.thread_msg_target, - // ptr::null(), - // HRGN::default(), - // RDW_INTERNALPAINT, - // ); + // 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, + ); + } } unsafe fn call_redraw_events_cleared(&self) { From 9b1fad4fae4b2e41242fa0aac9419113743ffed4 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Tue, 28 Jun 2022 18:49:09 +0800 Subject: [PATCH 3/3] Add change file --- .changes/wmpaint.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/wmpaint.md diff --git a/.changes/wmpaint.md b/.changes/wmpaint.md new file mode 100644 index 000000000..54b07d901 --- /dev/null +++ b/.changes/wmpaint.md @@ -0,0 +1,5 @@ +--- +tao: "patch" +--- + +Reduce `WM_PAINT` singal on event target window to prevent from webview2 delay.