Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/tests/win.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 0f683f858a1..a31255f505d 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3164,7 +3164,17 @@ static void test_SetActiveWindow(HWND hwnd) ShowWindow(hwnd, SW_HIDE); SetFocus(0); SetActiveWindow(0); - check_wnd_state(0, 0, 0, 0); + + /* On w1064v1809, ShowWindow(hwnd, SW_HIDE) / SetActiveWindow(0) + * does not change active window to 0, and then focus is not + * restored either when window is activated. */ + if (broken(GetActiveWindow() != 0)) + { + check_wnd_state(hwnd, 0, 0, 0); + SetFocus(hwnd); + } + else + check_wnd_state(0, 0, 0, 0);
ShowWindow(hwnd, SW_SHOW); check_wnd_state(hwnd, hwnd, hwnd, 0); @@ -3188,7 +3198,17 @@ static void test_SetActiveWindow(HWND hwnd) check_wnd_state(hwnd, hwnd, hwnd, 0);
ShowWindow(hwnd, SW_HIDE); - check_wnd_state(0, 0, 0, 0); + + /* On w1064v1809, ShowWindow(hwnd, SW_HIDE) / SetActiveWindow(0) + * does not change active window to 0, and then focus is not + * restored either when window is activated. */ + if (broken(GetActiveWindow() != 0)) + { + check_wnd_state(hwnd, 0, 0, 0); + SetFocus(hwnd); + } + else + check_wnd_state(0, 0, 0, 0);
/* Invisible window. */ SetActiveWindow(hwnd);
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/tests/win.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index a31255f505d..4184d6104bc 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3908,6 +3908,8 @@ static void test_mouse_input(HWND hwnd) msg.hwnd, popup, msg.message);
ret = wait_for_message( &msg ); + if (broken(msg.message >= WM_USER) /* on w1064v1809 */) + ret = wait_for_message( &msg ); ok(ret, "no message available\n"); ok(msg.hwnd == popup && msg.message == WM_LBUTTONUP, "hwnd %p/%p message %04x\n", msg.hwnd, popup, msg.message);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63686
Your paranoid android.
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3872: Test failed: hwnd 000202FE message 7fff win.c:3953: Test failed: hwnd 000202FE/00080376 message 7fff win.c:3956: Test failed: hwnd 000202FE/00080376 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9461: Test failed: didn't get start_event win.c:9465: Test failed: WindowFromPoint returned 000203F0, expected 00000000 win.c:9473: Test failed: WindowFromPoint returned 000203F0, expected 00000000 win.c:9374: Test failed: WindowFromPoint returned 0001038C, expected 000203F0 win.c:9381: Test failed: WindowFromPoint returned 0001038C, expected 0003017E win.c:9387: Test failed: CreateWindowEx failed win.c:9402: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9403: Test failed: button under static window didn't get WM_LBUTTONUP win.c:3872: Test failed: hwnd 0001038E message 0282 win.c:3953: Test failed: hwnd 0001038E/000C03EE message 0282 win.c:3956: Test failed: hwnd 0001038E/000C03EE message 0282
When calling SetForegroundWindow for a window in another thread, an internal message is posted to the thread's message queue.
If this thread then calls SetForegroundWindow before processing its messages it will execute the corresponding set_active_window first, but then overwrite the active window later, when processing its internal messages.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/tests/win.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 4184d6104bc..c89f7515eb7 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3266,7 +3266,9 @@ static void test_SetActiveWindow(HWND hwnd) struct create_window_thread_params { HWND window; + HWND other_window; HANDLE window_created; + HANDLE set_foreground; HANDLE test_finished; };
@@ -3275,12 +3277,23 @@ static DWORD WINAPI create_window_thread(void *param) struct create_window_thread_params *p = param; DWORD res; BOOL ret; + MSG msg;
+ p->other_window = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); p->window = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0);
ret = SetEvent(p->window_created); ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
+ res = WaitForSingleObject(p->set_foreground, INFINITE); + ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError()); + + SetForegroundWindow(p->other_window); + check_active_state(p->other_window, p->other_window, p->other_window); + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + todo_wine + check_active_state(p->other_window, p->other_window, p->other_window); + res = WaitForSingleObject(p->test_finished, INFINITE); ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
@@ -3375,6 +3388,8 @@ static void test_SetForegroundWindow(HWND hwnd)
thread_params.window_created = CreateEventW(NULL, FALSE, FALSE, NULL); ok(!!thread_params.window_created, "CreateEvent failed, last error %#x.\n", GetLastError()); + thread_params.set_foreground = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!thread_params.set_foreground, "CreateEvent failed, last error %#x.\n", GetLastError()); thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL); ok(!!thread_params.test_finished, "CreateEvent failed, last error %#x.\n", GetLastError()); thread = CreateThread(NULL, 0, create_window_thread, &thread_params, 0, &tid); @@ -3408,12 +3423,25 @@ static void test_SetForegroundWindow(HWND hwnd) ok(!SetForegroundWindow(hwnd2), "SetForegroundWindow failed\n"); check_wnd_state(hwnd, hwnd, hwnd, 0);
+ SetForegroundWindow(hwnd); + check_active_state(hwnd, hwnd, hwnd); + SetForegroundWindow(thread_params.window); + check_active_state(0, thread_params.window, 0); + SetForegroundWindow(hwnd); + check_active_state(hwnd, hwnd, hwnd); + res = SetEvent(thread_params.set_foreground); + ok(res, "SetEvent failed, last error %#x.\n", GetLastError()); + SetEvent(thread_params.test_finished); WaitForSingleObject(thread, INFINITE); CloseHandle(thread_params.test_finished); + CloseHandle(thread_params.set_foreground); CloseHandle(thread_params.window_created); CloseHandle(thread); DestroyWindow(hwnd2); + + /* process any pending internal message */ + PeekMessageA(&msg, 0, 0, 0, 0); }
static WNDPROC old_button_proc;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63687
Your paranoid android.
=== w1064v1809 (32 bit report) ===
Report errors: user32:win is missing some failure messages
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3775: Test failed: message 0738 available win.c:3900: Test failed: hwnd 00040314 message 7fff win.c:3981: Test failed: hwnd 00040314/000E02DC message 7fff win.c:3984: Test failed: hwnd 00040314/000E02DC message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:3900: Test failed: hwnd 0001038A message 0282 win.c:3981: Test failed: hwnd 0001038A/000A03D4 message 0282 win.c:3984: Test failed: hwnd 0001038A/000A03D4 message 0282
This makes set_active_window calls process the pending internal WM_WINE_SETACTIVEWINDOW messages first.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/focus.c | 22 ++++++++++++++-------- dlls/user32/message.c | 2 +- dlls/user32/tests/win.c | 1 - dlls/user32/user_private.h | 1 + 4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c index f1c883167ed..8b68c2abdee 100644 --- a/dlls/user32/focus.c +++ b/dlls/user32/focus.c @@ -74,13 +74,19 @@ 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, BOOL sent ) { - HWND previous = GetActiveWindow(); + MSG msg; + HWND previous; BOOL ret; DWORD old_thread, new_thread; CBTACTIVATESTRUCT cbt;
+ /* process pending WM_WINE_SETACTIVEWINDOW messages first */ + if (!sent) PeekMessageW( &msg, 0, 0, 0, QS_SENDMESSAGE ); + + previous = GetActiveWindow(); + if (previous == hwnd) { if (prev) *prev = hwnd; @@ -200,14 +206,14 @@ static BOOL set_foreground_window( HWND hwnd, BOOL mouse ) if (ret && previous != hwnd) { if (send_msg_old) /* old window belongs to other thread */ - SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 ); + SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, mouse ); 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, FALSE );
if (send_msg_new) /* new window belongs to other thread */ - SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 ); + SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, mouse ); else /* new window belongs to us */ - ret = set_active_window( hwnd, NULL, mouse, TRUE ); + ret = set_active_window( hwnd, NULL, mouse, TRUE, FALSE ); } return ret; } @@ -249,7 +255,7 @@ HWND WINAPI SetActiveWindow( HWND hwnd ) return GetActiveWindow(); /* 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, FALSE )) return 0; return prev; }
@@ -296,7 +302,7 @@ HWND WINAPI SetFocus( HWND hwnd ) /* activate hwndTop if needed. */ if (hwndTop != GetActiveWindow()) { - if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0; + if (!set_active_window( hwndTop, NULL, FALSE, FALSE, FALSE )) return 0; if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */
/* Do not change focus if the window is no longer active */ diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 1336865112a..84de851085b 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1874,7 +1874,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return WIN_SetStyle(hwnd, wparam, lparam); case WM_WINE_SETACTIVEWINDOW: if (!wparam && GetForegroundWindow() == hwnd) return 0; - return (LRESULT)SetActiveWindow( (HWND)wparam ); + return (LRESULT)set_active_window( (HWND)wparam, NULL, lparam, TRUE, TRUE ); case WM_WINE_KEYBOARD_LL_HOOK: case WM_WINE_MOUSE_LL_HOOK: { diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index c89f7515eb7..fcfc86ad80e 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3291,7 +3291,6 @@ static DWORD WINAPI create_window_thread(void *param) SetForegroundWindow(p->other_window); check_active_state(p->other_window, p->other_window, p->other_window); while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); - todo_wine check_active_state(p->other_window, p->other_window, p->other_window);
res = WaitForSingleObject(p->test_finished, INFINITE); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 7e294558ef1..115503eb38d 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -231,6 +231,7 @@ struct tagWND;
extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL FOCUS_MouseActivate( HWND hwnd ) DECLSPEC_HIDDEN; +extern BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, BOOL sent ) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; extern void free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN; extern void invalidate_dce( struct tagWND *win, const RECT *rect ) DECLSPEC_HIDDEN;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63688
Your paranoid android.
=== w1064v1507 (32 bit report) ===
Report errors: user32:win is missing some failure messages
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3774: Test failed: message 0738 available win.c:3899: Test failed: hwnd 000202F0 message 7fff win.c:3980: Test failed: hwnd 000202F0/0011031E message 7fff win.c:3983: Test failed: hwnd 000202F0/0011031E message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9488: Test failed: didn't get start_event win.c:9429: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9430: Test failed: button under static window didn't get WM_LBUTTONUP win.c:3899: Test failed: hwnd 0002038A message 0282 win.c:3980: Test failed: hwnd 0002038A/000C03DC message 0282 win.c:3983: Test failed: hwnd 0002038A/000C03DC message 0282
=== debian10 (32 bit report) ===
user32: msg.c:5277: Test failed: SetWindowPos:show_popup_first_show_window: 14: the msg sequence is not complete: expected 0000 - actual 0046
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=63685
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: win.c:3912: Test failed: hwnd 00040056/000E0066 message 0737 win.c:3917: Test failed: hwnd 000E0066/000E0066 message 0202 win.c:3922: Test failed: hwnd 000E0066/000E0066 message 0203 win.c:3926: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3912: Test failed: hwnd 0009018A/000401A4 message 0737 win.c:3917: Test failed: hwnd 000401A4/000401A4 message 0202 win.c:3922: Test failed: hwnd 000401A4/000401A4 message 0203 win.c:3926: Test failed: message 0202 available
=== w1064v1809_ar (32 bit report) ===
user32: win.c:3747: Test failed: message 0738 available
=== w1064v1809_he (32 bit report) ===
user32: win.c:9459: Test failed: didn't get start_event win.c:9463: Test failed: WindowFromPoint returned 00060072, expected 00000000 win.c:9471: Test failed: WindowFromPoint returned 00060072, expected 00000000 win.c:9372: Test failed: WindowFromPoint returned 00050084, expected 00060072 win.c:9376: Test failed: CreateWindowEx failed win.c:9379: Test failed: WindowFromPoint returned 00050084, expected 00000000 win.c:9385: Test failed: CreateWindowEx failed win.c:9400: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9401: Test failed: button under static window didn't get WM_LBUTTONUP win.c:3747: Test failed: message 0738 available
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3747: Test failed: message 0738 available win.c:3872: Test failed: hwnd 002B01C6 message 7fff win.c:3951: Test failed: hwnd 002B01C6/000C009C message 7fff win.c:3954: Test failed: hwnd 002B01C6/000C009C message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:3872: Test failed: hwnd 0002038A message 0282 win.c:3951: Test failed: hwnd 0002038A/000E0040 message 0282 win.c:3954: Test failed: hwnd 0002038A/000E0040 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3912: Test failed: hwnd 0000000000020102/00000000000B02E6 message 0737 win.c:3917: Test failed: hwnd 00000000000B02E6/00000000000B02E6 message 0202 win.c:3922: Test failed: hwnd 00000000000B02E6/00000000000B02E6 message 0203 win.c:3926: Test failed: message 0202 available
=== debian10 (32 bit report) ===
user32: win.c:10228: Test failed: Expected foreground window 008200B6, got 00E000AE win.c:10230: Test failed: GetActiveWindow() = 00000000 win.c:10230: Test failed: GetFocus() = 00000000 win.c:10231: Test failed: Received WM_ACTIVATEAPP(1), did not expect it. win.c:10232: Test failed: Received WM_ACTIVATEAPP(0), did not expect it.