From a0df9569a4d71385c0f3c88ba910791fc2af3db6 Mon Sep 17 00:00:00 2001 From: VZout Date: Thu, 19 Nov 2020 14:18:37 +0100 Subject: [PATCH 1/6] Added default WM_PAINT behaviour --- src/platform_impl/windows/event_loop.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 27af039fb6..1c6b510792 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -821,6 +821,7 @@ unsafe extern "system" fn public_window_callback( winuser::WM_PAINT => { if subclass_input.event_loop_runner.should_buffer() { + println!("buffer"); // this branch can happen in response to `UpdateWindow`, if win32 decides to // redraw the window outside the normal flow of the event loop. winuser::RedrawWindow( @@ -830,6 +831,7 @@ unsafe extern "system" fn public_window_callback( winuser::RDW_INTERNALPAINT, ); } else { + println!("no buffer"); let managing_redraw = flush_paint_messages(Some(window), &subclass_input.event_loop_runner); subclass_input.send_event(Event::RedrawRequested(RootWindowId(WindowId(window)))); @@ -1947,10 +1949,10 @@ unsafe extern "system" fn thread_event_target_callback( // Because WM_PAINT comes after all other messages, we use it during modal loops to detect // when the event queue has been emptied. See `process_event` for more details. winuser::WM_PAINT => { - winuser::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. + winuser::ValidateRect(window, ptr::null()); 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 @@ -1964,15 +1966,20 @@ unsafe extern "system" fn thread_event_target_callback( } 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( + /*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. + let mut ps: winuser::PAINTSTRUCT = std::mem::zeroed(); + winuser::BeginPaint(window, &mut ps as *mut _); + winuser::EndPaint(window, &mut ps as *mut _); + 0 } From 7524bf3045a1c14763a3b2dc1bdb5bfe69da985d Mon Sep 17 00:00:00 2001 From: VZout Date: Thu, 19 Nov 2020 14:22:46 +0100 Subject: [PATCH 2/6] cleanup --- src/platform_impl/windows/event_loop.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 1c6b510792..3e219614db 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -821,7 +821,6 @@ unsafe extern "system" fn public_window_callback( winuser::WM_PAINT => { if subclass_input.event_loop_runner.should_buffer() { - println!("buffer"); // this branch can happen in response to `UpdateWindow`, if win32 decides to // redraw the window outside the normal flow of the event loop. winuser::RedrawWindow( @@ -831,7 +830,6 @@ unsafe extern "system" fn public_window_callback( winuser::RDW_INTERNALPAINT, ); } else { - println!("no buffer"); let managing_redraw = flush_paint_messages(Some(window), &subclass_input.event_loop_runner); subclass_input.send_event(Event::RedrawRequested(RootWindowId(WindowId(window)))); @@ -1949,10 +1947,10 @@ unsafe extern "system" fn thread_event_target_callback( // Because WM_PAINT comes after all other messages, we use it during modal loops to detect // when the event queue has been emptied. See `process_event` for more details. winuser::WM_PAINT => { + winuser::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. - winuser::ValidateRect(window, ptr::null()); 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 From 6d0ad9e71d93b7e0df267950d644db382a301d88 Mon Sep 17 00:00:00 2001 From: VZout Date: Thu, 19 Nov 2020 14:24:11 +0100 Subject: [PATCH 3/6] Added back in a commented out assert --- src/platform_impl/windows/event_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 3e219614db..18e069f40e 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1964,10 +1964,10 @@ unsafe extern "system" fn thread_event_target_callback( } 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( + 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); } From 5de3740258b9308222495f89f38970f81422c8e3 Mon Sep 17 00:00:00 2001 From: VZout Date: Thu, 19 Nov 2020 14:48:38 +0100 Subject: [PATCH 4/6] future proofing. apparently mem::zeroed will be deprecated --- src/platform_impl/windows/event_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 18e069f40e..7e3415b179 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1974,7 +1974,7 @@ unsafe extern "system" fn thread_event_target_callback( } // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. - let mut ps: winuser::PAINTSTRUCT = std::mem::zeroed(); + let mut ps = std::mem::MaybeUninit::::zeroed().assume_init(); winuser::BeginPaint(window, &mut ps as *mut _); winuser::EndPaint(window, &mut ps as *mut _); From cf8f46ad6410ce83392d4702effb1e49e6ab8090 Mon Sep 17 00:00:00 2001 From: Viktor Zoutman Date: Fri, 20 Nov 2020 11:07:49 +0100 Subject: [PATCH 5/6] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0195304ec3..54e7855cf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- On Windows, fix bug causing message boxes to appear delayed. - On Android, calling `WindowEvent::Focused` now works properly instead of always returning false. - On Windows, fix alt-tab behaviour by removing borderless fullscreen "always on top" flag. - On Windows, fix bug preventing windows with transparency enabled from having fully-opaque regions. From 4215824cd9a522206e73eee99c93ac4a90e75e7a Mon Sep 17 00:00:00 2001 From: VZout Date: Mon, 23 Nov 2020 15:17:47 +0100 Subject: [PATCH 6/6] DefSubclassProc in favor of manual calls --- src/platform_impl/windows/event_loop.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 7e3415b179..37817cb51b 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -1974,11 +1974,7 @@ unsafe extern "system" fn thread_event_target_callback( } // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. - let mut ps = std::mem::MaybeUninit::::zeroed().assume_init(); - winuser::BeginPaint(window, &mut ps as *mut _); - winuser::EndPaint(window, &mut ps as *mut _); - - 0 + commctrl::DefSubclassProc(window, msg, wparam, lparam) } winuser::WM_INPUT_DEVICE_CHANGE => {