From: Rémi Bernon rbernon@codeweavers.com
We should probably change the foreground window even if a different window is already foreground, tracking the last user input time for instance, but this would be a much larger impacting change.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56073 --- dlls/user32/tests/input.c | 1 - dlls/win32u/defwnd.c | 2 +- dlls/win32u/input.c | 16 ++++++++++++---- dlls/win32u/message.c | 2 +- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 6 +++--- 6 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index f8890d0d6d0..50b77bb9f2b 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -5407,7 +5407,6 @@ static void test_SetFocus_activate(void) tmp_hwnd = SetFocus( hwnd ); ok( tmp_hwnd == hwnd, "SetFocus returned %p\n", tmp_hwnd ); tmp_hwnd = GetForegroundWindow(); - todo_wine ok( tmp_hwnd == hwnd, "GetForegroundWindow returned %p\n", tmp_hwnd ); tmp_hwnd = GetFocus(); ok( tmp_hwnd == hwnd, "GetFocus returned %p\n", tmp_hwnd ); diff --git a/dlls/win32u/defwnd.c b/dlls/win32u/defwnd.c index cba5f02c02e..253cc81fdf0 100644 --- a/dlls/win32u/defwnd.c +++ b/dlls/win32u/defwnd.c @@ -2194,7 +2194,7 @@ static LRESULT handle_nc_lbutton_down( HWND hwnd, WPARAM wparam, LPARAM lparam ) top = parent; }
- if (set_foreground_window( top, TRUE ) || (get_active_window() == top)) + if (set_foreground_window( top, TRUE, TRUE ) || (get_active_window() == top)) send_message( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lparam ); break; } diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 3ee46f0bfcf..d757d07bfbf 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2034,7 +2034,15 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) /* activate hwndTop if needed. */ if (hwndTop != get_active_window()) { - if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0; + BOOL ret; + + /* make the process foreground if no other process is */ + if (NtUserGetForegroundWindow() == NtUserGetDesktopWindow()) + ret = set_foreground_window( hwndTop, FALSE, FALSE ); + else + ret = set_active_window( hwnd, NULL, FALSE, FALSE ); + if (!ret) return 0; + if (!is_window( hwnd )) return 0; /* Abort if window destroyed */
/* Do not change focus if the window is no longer active */ @@ -2054,7 +2062,7 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) /******************************************************************* * set_foreground_window */ -BOOL set_foreground_window( HWND hwnd, BOOL mouse ) +BOOL set_foreground_window( HWND hwnd, BOOL mouse, BOOL set_focus ) { BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE; HWND previous = 0; @@ -2079,13 +2087,13 @@ BOOL set_foreground_window( HWND hwnd, BOOL mouse ) NtUserMessageCall( previous, WM_WINE_SETACTIVEWINDOW, 0, 0, 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, set_focus );
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, set_focus ); } return ret; } diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 91f836a60bd..74bdab476e7 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2623,7 +2623,7 @@ static BOOL process_mouse_message( MSG *msg, UINT hw_id, ULONG_PTR extra_info, H /* fall through */ case MA_ACTIVATE: case 0: - if (!set_foreground_window( hwndTop, TRUE )) eat_msg = TRUE; + if (!set_foreground_window( hwndTop, TRUE, TRUE )) eat_msg = TRUE; break; default: WARN( "unknown WM_MOUSEACTIVATE code %d\n", ret ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index b08c0ceb716..ff22f1e5fa3 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -102,7 +102,7 @@ extern BOOL release_capture(void); 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_foreground_window( HWND hwnd, BOOL mouse, BOOL set_focus ); extern void toggle_caret( HWND hwnd ); extern void update_mouse_tracking_info( HWND hwnd ); extern BOOL get_clip_cursor( RECT *rect ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 69dd8caba5d..7af092e5acd 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3468,7 +3468,7 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) if ((get_window_long( winpos->hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD) send_message( winpos->hwnd, WM_CHILDACTIVATE, 0, 0 ); else - set_foreground_window( winpos->hwnd, FALSE ); + set_foreground_window( winpos->hwnd, FALSE, TRUE ); }
if(!(orig_flags & SWP_DEFERERASE)) @@ -3808,7 +3808,7 @@ static void activate_other_window( HWND hwnd ) TRACE( "win = %p fg = %p\n", hwnd_to, fg ); if (!fg || hwnd == fg) { - if (set_foreground_window( hwnd_to, FALSE )) return; + if (set_foreground_window( hwnd_to, FALSE, TRUE )) return; } if (NtUserSetActiveWindow( hwnd_to )) NtUserSetActiveWindow( 0 ); } @@ -5464,7 +5464,7 @@ ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code ) return is_window_visible( hwnd );
case NtUserCallHwnd_SetForegroundWindow: - return set_foreground_window( hwnd, FALSE ); + return set_foreground_window( hwnd, FALSE, TRUE );
case NtUserCallHwnd_SetProgmanWindow: return HandleToUlong( set_progman_window( hwnd ));