From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56073 --- dlls/user32/tests/input.c | 31 +++++++++++++++++++++++++++++++ dlls/user32/tests/win.c | 28 +++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 26f7d08e422..b33f592b8c2 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -6128,6 +6128,8 @@ static void test_input_desktop( char **argv ) test_LoadKeyboardLayoutEx( hkl );
ok_ret( 1, SetCursorPos( pos.x, pos.y ) ); + + run_in_process( argv, "test_SetFocus" ); }
static void test_keyboard_layout(void) @@ -6279,6 +6281,33 @@ static void test_system_messages_with_rawinput_nolegacy(void) pump_messages(); }
+static void test_SetFocus_process(void) +{ + HWND hwnd, foreground; + + ok( GetFocus() == 0, "got focus %p\n", GetFocus() ); + ok( GetActiveWindow() == 0, "got active %p\n", GetActiveWindow() ); + foreground = GetForegroundWindow(); + + hwnd = CreateWindowExW( 0, L"static", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, NULL, NULL ); + ok( !!hwnd, "CreateWindowExW failed, error %lu\n", GetLastError() ); + wait_messages( 200, FALSE ); + + ShowWindow( hwnd, SW_SHOWNA ); + wait_messages( 200, FALSE ); + ok( GetFocus() == 0, "got focus %p\n", GetFocus() ); + ok( GetActiveWindow() == 0, "got active %p\n", GetActiveWindow() ); + ok( GetForegroundWindow() == foreground, "got foreground %p\n", GetForegroundWindow() ); + + SetFocus( hwnd ); + ok( GetFocus() == hwnd, "got focus %p\n", GetFocus() ); + ok( GetActiveWindow() == hwnd, "got active %p\n", GetActiveWindow() ); + todo_wine ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); + + SetForegroundWindow( hwnd ); + DestroyWindow( hwnd ); +} + START_TEST(input) { char **argv; @@ -6305,6 +6334,8 @@ START_TEST(input) return test_input_desktop( argv ); if (argc >= 3 && !strcmp( argv[2], "test_system_messages_with_rawinput_nolegacy" )) return test_system_messages_with_rawinput_nolegacy(); + if (argc >= 3 && !strcmp( argv[2], "test_SetFocus" )) + return test_SetFocus_process();
run_in_desktop( argv, "test_input_desktop", 1 ); test_keynames(); diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 28c74764534..166653f0d2c 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3657,7 +3657,7 @@ static LRESULT WINAPI set_focus_on_activate_proc(HWND hwnd, UINT msg, WPARAM wp,
static void test_SetFocus(HWND hwnd) { - HWND child, child2, ret; + HWND child, child2, ret, other; WNDPROC old_wnd_proc;
/* check if we can set focus to non-visible windows */ @@ -3666,21 +3666,26 @@ static void test_SetFocus(HWND hwnd) SetFocus(0); SetFocus(hwnd); ok( GetFocus() == hwnd, "Failed to set focus to visible window %p\n", hwnd ); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); ok( GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE, "Window %p not visible\n", hwnd ); ShowWindow(hwnd, SW_HIDE); SetFocus(0); SetFocus(hwnd); ok( GetFocus() == hwnd, "Failed to set focus to invisible window %p\n", hwnd ); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); ok( !(GetWindowLongA(hwnd,GWL_STYLE) & WS_VISIBLE), "Window %p still visible\n", hwnd ); child = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 0, 0, hwnd, 0, 0, NULL); assert(child); SetFocus(child); ok( GetFocus() == child, "Failed to set focus to invisible child %p\n", child ); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child ); ShowWindow(child, SW_SHOW); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); ok( GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE, "Child %p is not visible\n", child ); ok( GetFocus() == child, "Focus no longer on child %p\n", child ); ShowWindow(child, SW_HIDE); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); ok( !(GetWindowLongA(child,GWL_STYLE) & WS_VISIBLE), "Child %p is visible\n", child ); ok( GetFocus() == hwnd, "Focus should be on parent %p, not %p\n", hwnd, GetFocus() ); ShowWindow(child, SW_SHOW); @@ -3760,6 +3765,27 @@ static void test_SetFocus(HWND hwnd)
DestroyWindow( child2 ); DestroyWindow( child ); + + SetForegroundWindow( GetDesktopWindow() ); + + other = CreateWindowExA( 0, "static", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, NULL, NULL ); + ok( !!other, "CreateWindowExA failed, error %lu\n", GetLastError() ); + flush_events( TRUE ); + + ShowWindow( other, SW_SHOWNA ); + flush_events( TRUE ); + ok( GetFocus() == 0, "got focus %p\n", GetFocus() ); + ok( GetActiveWindow() == 0, "got active %p\n", GetActiveWindow() ); + todo_wine ok( GetForegroundWindow() == 0, "got foreground %p\n", GetForegroundWindow() ); + + SetFocus( other ); + ok( GetFocus() == other, "got focus %p\n", GetFocus() ); + ok( GetActiveWindow() == other, "got active %p\n", GetActiveWindow() ); + todo_wine ok( GetForegroundWindow() == 0, "got foreground %p\n", GetForegroundWindow() ); + + SetForegroundWindow( hwnd ); + DestroyWindow( other ); + flush_events( TRUE ); }
static void test_SetActiveWindow_0_proc( char **argv )
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56073 --- dlls/user32/tests/input.c | 2 +- dlls/win32u/input.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index b33f592b8c2..4d4c3c81000 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -6302,7 +6302,7 @@ static void test_SetFocus_process(void) SetFocus( hwnd ); ok( GetFocus() == hwnd, "got focus %p\n", GetFocus() ); ok( GetActiveWindow() == hwnd, "got active %p\n", GetActiveWindow() ); - todo_wine ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() ); + ok( GetForegroundWindow() == hwnd, "got foreground %p\n", GetForegroundWindow() );
SetForegroundWindow( hwnd ); DestroyWindow( hwnd ); diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index a4834b740d8..99a0dcb2ace 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2107,7 +2107,7 @@ HWND WINAPI NtUserSetActiveWindow( HWND hwnd ) */ HWND WINAPI NtUserSetFocus( HWND hwnd ) { - HWND hwndTop = hwnd; + HWND hwndTop = hwnd, active; HWND previous = get_focus();
TRACE( "%p prev %p\n", hwnd, previous ); @@ -2142,7 +2142,8 @@ HWND WINAPI NtUserSetFocus( HWND hwnd ) if (call_hooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, 0 )) return 0;
/* activate hwndTop if needed. */ - if (hwndTop != get_active_window()) + if (!(active = get_active_window()) && !set_foreground_window( hwndTop, FALSE )) return 0; + if (hwndTop != active) { if (!set_active_window( hwndTop, NULL, FALSE, FALSE, 0 )) return 0; if (!is_window( hwnd )) return 0; /* Abort if window destroyed */