-- v2: win32u: Correctly fill new foreground window TID in WM_ACTIVATEAPP. win32u: Call set_active_window() helper directly from handle_internal_message().
From: Paul Gofman pgofman@codeweavers.com
--- dlls/win32u/input.c | 2 +- dlls/win32u/message.c | 7 ++++++- dlls/win32u/win32u_private.h | 1 + 3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 14862e9a8a4..8c6b448ee30 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1901,7 +1901,7 @@ static HWND set_focus_window( HWND hwnd ) /******************************************************************* * set_active_window */ -static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) +BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) { HWND previous = get_active_window(); BOOL ret; diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index a0cbfbce95c..3f2203aa5dd 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2099,8 +2099,13 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR if (is_desktop_window( hwnd )) return 0; return set_window_style( hwnd, wparam, lparam ); case WM_WINE_SETACTIVEWINDOW: + { + HWND prev; + if (!wparam && NtUserGetForegroundWindow() == hwnd) return 0; - return (LRESULT)NtUserSetActiveWindow( (HWND)wparam ); + if (!set_active_window( (HWND)wparam, &prev, FALSE, TRUE )) return 0; + return (LRESULT)prev; + } case WM_WINE_KEYBOARD_LL_HOOK: case WM_WINE_MOUSE_LL_HOOK: { diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e7a5791dc92..472ae3a4b70 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -103,6 +103,7 @@ extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ); extern BOOL set_caret_blink_time( unsigned int time ); extern BOOL set_caret_pos( int x, int y ); extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ); +extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ); extern BOOL set_ime_composition_window_pos( HWND hwnd, const POINT *point ); extern void toggle_caret( HWND hwnd ); extern void update_mouse_tracking_info( HWND hwnd );
From: Paul Gofman pgofman@codeweavers.com
--- dlls/win32u/input.c | 17 ++++++++++------- dlls/win32u/message.c | 2 +- dlls/win32u/win32u_private.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 8c6b448ee30..0d7b088f996 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1901,7 +1901,7 @@ static HWND set_focus_window( HWND hwnd ) /******************************************************************* * set_active_window */ -BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) +BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, DWORD new_active_thread_id ) { HWND previous = get_active_window(); BOOL ret; @@ -1959,10 +1959,11 @@ BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) { if (old_thread) { + if (!new_active_thread_id) new_active_thread_id = new_thread; for (phwnd = list; *phwnd; phwnd++) { if (get_window_thread( *phwnd, NULL ) == old_thread) - send_message( *phwnd, WM_ACTIVATEAPP, 0, new_thread ); + send_message( *phwnd, WM_ACTIVATEAPP, 0, new_active_thread_id ); } } if (new_thread) @@ -2032,7 +2033,7 @@ HWND WINAPI NtUserSetActiveWindow( HWND hwnd ) return get_active_window(); /* Windows doesn't seem to return an error here */ }
- if (!set_active_window( hwnd, &prev, FALSE, TRUE )) return 0; + if (!set_active_window( hwnd, &prev, FALSE, TRUE, 0 )) return 0; return prev; }
@@ -2078,7 +2079,7 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) /* activate hwndTop if needed. */ if (hwndTop != get_active_window()) { - if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0; + if (!set_active_window( hwndTop, NULL, FALSE, FALSE, 0 )) return 0; if (!is_window( hwnd )) return 0; /* Abort if window destroyed */
/* Do not change focus if the window is no longer active */ @@ -2101,9 +2102,11 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) BOOL set_foreground_window( HWND hwnd, BOOL mouse ) { BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE; + DWORD new_thread_id; HWND previous = 0;
if (mouse) hwnd = get_full_window_handle( hwnd ); + new_thread_id = get_window_thread( hwnd, NULL );
SERVER_START_REQ( set_foreground_window ) { @@ -2120,16 +2123,16 @@ BOOL set_foreground_window( HWND hwnd, BOOL mouse ) if (ret && previous != hwnd) { if (send_msg_old) /* old window belongs to other thread */ - NtUserMessageCall( previous, WM_WINE_SETACTIVEWINDOW, 0, 0, + NtUserMessageCall( previous, WM_WINE_SETACTIVEWINDOW, 0, new_thread_id, 0, NtUserSendNotifyMessage, FALSE ); else if (send_msg_new) /* old window belongs to us but new one to other thread */ - ret = set_active_window( 0, NULL, mouse, TRUE ); + ret = set_active_window( 0, NULL, mouse, TRUE, new_thread_id );
if (send_msg_new) /* new window belongs to other thread */ NtUserMessageCall( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0, 0, NtUserSendNotifyMessage, FALSE ); else /* new window belongs to us */ - ret = set_active_window( hwnd, NULL, mouse, TRUE ); + ret = set_active_window( hwnd, NULL, mouse, TRUE, 0 ); } return ret; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 3f2203aa5dd..24a55365b7a 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2103,7 +2103,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR HWND prev;
if (!wparam && NtUserGetForegroundWindow() == hwnd) return 0; - if (!set_active_window( (HWND)wparam, &prev, FALSE, TRUE )) return 0; + if (!set_active_window( (HWND)wparam, &prev, FALSE, TRUE, lparam )) return 0; return (LRESULT)prev; } case WM_WINE_KEYBOARD_LL_HOOK: diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 472ae3a4b70..bf88b130f67 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -103,7 +103,7 @@ extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ); extern BOOL set_caret_blink_time( unsigned int time ); extern BOOL set_caret_pos( int x, int y ); extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ); -extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ); +extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, DWORD new_active_thread_id ); extern BOOL set_ime_composition_window_pos( HWND hwnd, const POINT *point ); extern void toggle_caret( HWND hwnd ); extern void update_mouse_tracking_info( HWND hwnd );
v2: - pass new thread id around from set_foreground_window() instead of storing that on the server; - drop the interactive test.
This merge request was approved by Rémi Bernon.