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.
This is not always the correct behavior and these tests help determine what should actually be done in various situations.
This aims to check the following sequences:
* window A0, A1, or A2 is foreground, then: * thread B sets foreground to window A0 * thread A sets foreground to window A1
As well as these sequences where foreground is also temporarily switched to thread B' window B0:
* window A0, A1, or A2 is foreground, then: * thread B sets foreground to window B0 * thread B sets foreground to window A0 * thread B sets foreground to window B0 * thread A sets foreground to window A1
In addition, we also do tests with additional SetActiveWindow / SetFocus calls to validate their influence.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
For system-wide input (by opposition to per-window as currently done) to be correctly implemented, for instance for a correct implementation of the rawinput API, but also to be able to implement focus change requests like using _NET_ACTIVE_WINDOW request on X11, Wine focus tracking has to precisely match system focus.
There's currently several issues with that and this patch series fixes some focus inversions that may happen because of internal messages being queued, then processed late, overwriting previous changes, when multiple threads or processes are switching foreground.
Another future improvement that I think would be helpful, will be to add timestamps to SetForegroundWindow requests, so that we can use the system event time to tell events that are the result of window creation from events that come from an actual system focus change.
Then, if an application is't processing its messages, we will not check for system events and that could be a problem: when focus is changed to a non-Wine window, no other window will receive an event. A fix for that would be to additionally listen to focus changes events globally, for instance in explorer.exe or a dedicated service, and tell wineserver about them.
dlls/user32/tests/win.c | 204 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 190 insertions(+), 14 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 25d643f54a6e..46bc0952b73c 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3243,25 +3243,165 @@ static void test_SetActiveWindow(HWND hwnd) struct create_window_thread_params { HWND window; - HANDLE window_created; - HANDLE test_finished; + HANDLE test_ready; + HANDLE set_foreground; + HANDLE test_done; +}; + +static int set_foreground_msgcount; + +static LRESULT WINAPI set_foreground_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch (msg) + { + case WM_NCACTIVATE: + case WM_ACTIVATE: + case WM_SETFOCUS: + case WM_KILLFOCUS: + set_foreground_msgcount++; + break; + } + + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +struct set_foreground_test_desc +{ + int initial_window; + BOOL steal_foreground; + BOOL call_set_active_window; + BOOL call_set_focus; + + BOOL todo_msgcount_before_set_foreground; + int msgcount_before_set_foreground; + BOOL todo_msgcount_after_set_foreground; + int msgcount_after_set_foreground; + BOOL todo_msgcount_after_peek_message; + int msgcount_after_peek_message; + BOOL todo_expected_window; + int expected_window; +}; + +static struct set_foreground_test_desc set_foreground_tests[] = { + {1, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, + {1, TRUE, FALSE, FALSE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + {1, FALSE, TRUE, FALSE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, + {1, TRUE, TRUE, FALSE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + {1, FALSE, FALSE, TRUE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, + {1, TRUE, FALSE, TRUE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + + {2, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, + {2, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, + {2, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, TRUE, 0, TRUE, 1}, + {2, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, TRUE, 6, TRUE, 0}, + {2, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, TRUE, 0, TRUE, 1}, + {2, TRUE, FALSE, TRUE, TRUE, 8, TRUE, 1, TRUE, 6, TRUE, 0}, + + {0, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, + {0, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, + {0, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, FALSE, 0, FALSE, 1}, + {0, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, FALSE, 6, FALSE, 0}, + {0, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, FALSE, 0, FALSE, 1}, + {0, TRUE, FALSE, TRUE, TRUE, 8, TRUE, 1, FALSE, 6, FALSE, 0}, };
static DWORD WINAPI create_window_thread(void *param) { struct create_window_thread_params *p = param; DWORD res; + WNDPROC wndprocs[3]; + HWND windows[3]; BOOL ret; + MSG msg; + int i;
- p->window = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); + windows[1] = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); + windows[2] = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); + windows[0] = p->window = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); + trace("window[0]:%p windows[1]:%p windows[2]:%p\n", windows[0], windows[1], windows[2]);
- ret = SetEvent(p->window_created); + ret = SetEvent(p->test_ready); ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
- res = WaitForSingleObject(p->test_finished, INFINITE); + res = WaitForSingleObject(p->test_done, INFINITE); ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError()); + ret = ResetEvent(p->test_done); + ok(ret, "ResetEvent failed, last error %#x.\n", GetLastError()); + + + for (i = 0; i < ARRAY_SIZE(windows); ++i) + wndprocs[i] = (WNDPROC)SetWindowLongPtrA(windows[i], GWLP_WNDPROC, (LONG_PTR)set_foreground_wndproc); + + flush_events(TRUE); + + for (i = 0; i < ARRAY_SIZE(set_foreground_tests); ++i) + { + struct set_foreground_test_desc *test = set_foreground_tests + i; + HWND initial_window = windows[test->initial_window]; + HWND expected_window = windows[test->expected_window]; + + SetForegroundWindow(initial_window); + flush_events(TRUE); + check_wnd_state(initial_window, initial_window, initial_window, 0); + + ret = SetEvent(p->test_ready); + 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()); + ret = ResetEvent(p->set_foreground); + ok(ret, "ResetEvent failed, last error %#x.\n", GetLastError()); + + set_foreground_msgcount = 0; + + if (test->call_set_active_window) + SetActiveWindow(windows[1]); + if (test->call_set_focus) + SetFocus(windows[1]); + + todo_wine_if(test->todo_msgcount_before_set_foreground) + ok(set_foreground_msgcount == test->msgcount_before_set_foreground, + "%d: Unexpected number of messages received before SetForegroundWindow: %d\n", i, set_foreground_msgcount); + set_foreground_msgcount = 0; + + SetForegroundWindow(windows[1]); + + todo_wine_if(test->todo_msgcount_after_set_foreground) + ok(set_foreground_msgcount == test->msgcount_after_set_foreground, + "%d: Unexpected number of messages received after SetForegroundWindow: %d\n", i, set_foreground_msgcount); + set_foreground_msgcount = 0; + + ok(GetForegroundWindow() == windows[1], "GetForegroundWindow() returned %p\n", GetForegroundWindow()); + ok(GetActiveWindow() == windows[1], "GetActiveWindow() returned %p\n", GetActiveWindow()); + ok(GetFocus() == windows[1], "GetFocus() returned %p\n", GetFocus()); + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + + todo_wine_if(test->todo_msgcount_after_peek_message) + ok(set_foreground_msgcount == test->msgcount_after_peek_message, + "%d: Unexpected number of messages received after PeekMessageA: %d\n", i, set_foreground_msgcount); + set_foreground_msgcount = 0; + + todo_wine_if(test->todo_expected_window) + ok(GetForegroundWindow() == expected_window, "%d: GetForegroundWindow() returned %p\n", i, GetForegroundWindow()); + todo_wine_if(test->todo_expected_window) + ok(GetActiveWindow() == expected_window, "%d: GetActiveWindow() returned %p\n", i, GetActiveWindow()); + todo_wine_if(test->todo_expected_window) + ok(GetFocus() == expected_window, "%d: GetFocus() returned %p\n", i, GetFocus()); + + res = WaitForSingleObject(p->test_done, INFINITE); + ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError()); + ret = ResetEvent(p->test_done); + ok(ret, "ResetEvent failed, last error %#x.\n", GetLastError()); + } + + for (i = 0; i < ARRAY_SIZE(windows); ++i) + SetWindowLongPtrA(windows[i], GWLP_WNDPROC, (LONG_PTR)wndprocs[i]); + + + for (i = 0; i < ARRAY_SIZE(windows); ++i) + DestroyWindow(windows[i]);
- DestroyWindow(p->window); return 0; }
@@ -3274,6 +3414,7 @@ static void test_SetForegroundWindow(HWND hwnd) HWND hwnd2; MSG msg; LONG style; + int i;
flush_events( TRUE ); ShowWindow(hwnd, SW_HIDE); @@ -3350,14 +3491,18 @@ static void test_SetForegroundWindow(HWND hwnd) hwnd2 = CreateWindowA("static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, 0, 0, 0, 0); check_wnd_state(hwnd2, hwnd2, hwnd2, 0);
- thread_params.window_created = CreateEventW(NULL, FALSE, FALSE, NULL); - ok(!!thread_params.window_created, "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_params.test_ready = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!thread_params.test_ready, "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_done = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!thread_params.test_done, "CreateEvent failed, last error %#x.\n", GetLastError()); thread = CreateThread(NULL, 0, create_window_thread, &thread_params, 0, &tid); ok(!!thread, "Failed to create thread, last error %#x.\n", GetLastError()); - res = WaitForSingleObject(thread_params.window_created, INFINITE); + res = WaitForSingleObject(thread_params.test_ready, INFINITE); ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError()); + ret = ResetEvent(thread_params.test_ready); + ok(ret, "ResetEvent failed, last error %#x.\n", GetLastError()); check_wnd_state(hwnd2, thread_params.window, hwnd2, 0);
SetForegroundWindow(hwnd2); @@ -3385,12 +3530,43 @@ static void test_SetForegroundWindow(HWND hwnd) ok(!SetForegroundWindow(hwnd2), "SetForegroundWindow failed\n"); check_wnd_state(hwnd, hwnd, hwnd, 0);
- SetEvent(thread_params.test_finished); + res = SetEvent(thread_params.test_done); + ok(res, "SetEvent failed, last error %#x.\n", GetLastError()); + + + for (i = 0; i < ARRAY_SIZE(set_foreground_tests); ++i) + { + struct set_foreground_test_desc *test = set_foreground_tests + i; + + while (MsgWaitForMultipleObjects(1, &thread_params.test_ready, FALSE, INFINITE, QS_SENDMESSAGE) != WAIT_OBJECT_0) + { + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE)) + DispatchMessageA(&msg); + } + + ret = ResetEvent(thread_params.test_ready); + ok(ret, "ResetEvent failed, last error %#x.\n", GetLastError()); + + if (test->steal_foreground) SetForegroundWindow(hwnd); + SetForegroundWindow(thread_params.window); + if (test->steal_foreground) SetForegroundWindow(hwnd); + + res = SetEvent(thread_params.set_foreground); + ok(res, "SetEvent failed, last error %#x.\n", GetLastError()); + + ret = SetEvent(thread_params.test_done); + ok(res, "SetEvent failed, last error %#x.\n", GetLastError()); + } + + WaitForSingleObject(thread, INFINITE); - CloseHandle(thread_params.test_finished); - CloseHandle(thread_params.window_created); + CloseHandle(thread_params.set_foreground); + CloseHandle(thread_params.test_done); + CloseHandle(thread_params.test_ready); CloseHandle(thread); DestroyWindow(hwnd2); + + flush_events(TRUE); }
static WNDPROC old_button_proc;
Instead of only checking that the window is foreground.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/message.c | 2 +- dlls/user32/tests/win.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 2717d91dbb51..af909f61f6d8 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1873,7 +1873,7 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR if (is_desktop_window( hwnd )) return 0; return WIN_SetStyle(hwnd, wparam, lparam); case WM_WINE_SETACTIVEWINDOW: - if (!wparam && GetForegroundWindow() == hwnd) return 0; + if (!wparam && GetWindowThreadProcessId( GetForegroundWindow(), NULL ) == GetCurrentThreadId()) return 0; return (LRESULT)SetActiveWindow( (HWND)wparam ); 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 46bc0952b73c..90c49a8f5c2b 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3284,18 +3284,18 @@ struct set_foreground_test_desc
static struct set_foreground_test_desc set_foreground_tests[] = { {1, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, - {1, TRUE, FALSE, FALSE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + {1, TRUE, FALSE, FALSE, FALSE, 0, TRUE, 1, FALSE, 6, FALSE, 0}, {1, FALSE, TRUE, FALSE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, - {1, TRUE, TRUE, FALSE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + {1, TRUE, TRUE, FALSE, FALSE, 0, TRUE, 1, FALSE, 6, FALSE, 0}, {1, FALSE, FALSE, TRUE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, - {1, TRUE, FALSE, TRUE, FALSE, 0, TRUE, 1, TRUE, 6, TRUE, 0}, + {1, TRUE, FALSE, TRUE, FALSE, 0, TRUE, 1, FALSE, 6, FALSE, 0},
{2, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, {2, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, {2, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, TRUE, 0, TRUE, 1}, - {2, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, TRUE, 6, TRUE, 0}, + {2, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, FALSE, 6, FALSE, 0}, {2, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, TRUE, 0, TRUE, 1}, - {2, TRUE, FALSE, TRUE, TRUE, 8, TRUE, 1, TRUE, 6, TRUE, 0}, + {2, TRUE, FALSE, TRUE, TRUE, 8, TRUE, 1, FALSE, 6, FALSE, 0},
{0, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, {0, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1},
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=70652
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 0003004C win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 0003004C win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 00020174/000F02C4 message 0737 win.c:4070: Test failed: hwnd 000F02C4/000F02C4 message 0202 win.c:4075: Test failed: hwnd 000F02C4/000F02C4 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 0004029A win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 0004029A win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000402A0/000B0150 message 0737 win.c:4070: Test failed: hwnd 000B0150/000B0150 message 0202 win.c:4075: Test failed: hwnd 000B0150/000B0150 message 0203 win.c:4079: Test failed: message 0202 available win.c:4091: Test failed: hwnd 0004029A/0004029A message 0200 win.c:4095: Test failed: hwnd 0004029A/0004029A message 0201 win.c:4104: Test failed: hwnd 000B0150/000B0150 message 0202 win.c:4107: Test failed: hwnd 000B0150/000B0150 message 0201
=== w1064v1809_he (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3900: Test failed: message 0738 available win.c:4025: Test failed: hwnd 000202F2 message 7fff win.c:4104: Test failed: hwnd 000202F2/00110148 message 7fff win.c:4107: Test failed: hwnd 000202F2/00110148 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9553: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9554: Test failed: button under static window didn't get WM_LBUTTONUP win.c:4025: Test failed: hwnd 00010382 message 0282 win.c:4104: Test failed: hwnd 00010382/000C03D4 message 0282 win.c:4107: Test failed: hwnd 00010382/000C03D4 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:4065: Test failed: hwnd 0000000000020174/00000000000F02C8 message 0737 win.c:4070: Test failed: hwnd 00000000000F02C8/00000000000F02C8 message 0202 win.c:4075: Test failed: hwnd 00000000000F02C8/00000000000F02C8 message 0203 win.c:4079: Test failed: message 0202 available
=== debiant (32 bit Chinese:China report) ===
user32: clipboard.c:833: Test failed: 0: gle 5 clipboard.c:838: Test failed: 0.0: got 0000 instead of 0001 clipboard.c:868: Test failed: 0: gle 1418 clipboard.c:717: Test failed: 1: gle 5 clipboard.c:719: Test failed: 1: gle 1418 clipboard.c:746: Test failed: 1: count 4 clipboard.c:749: Test failed: 1: gle 1418 clipboard.c:760: Test failed: 1: gle 5 clipboard.c:765: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:805: Test failed: 1: gle 1418 clipboard.c:815: Test failed: 1: count 4 clipboard.c:818: Test failed: 1: gle 1418 clipboard.c:833: Test failed: 1: gle 5 clipboard.c:838: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:868: Test failed: 1: gle 1418 clipboard.c:717: Test failed: 2: gle 5 clipboard.c:719: Test failed: 2: gle 1418 clipboard.c:746: Test failed: 2: count 4 clipboard.c:749: Test failed: 2: gle 1418 clipboard.c:760: Test failed: 2: gle 5 clipboard.c:765: Test failed: 2.0: got 0000 instead of 000d clipboard.c:805: Test failed: 2: gle 1418 clipboard.c:815: Test failed: 2: count 4 clipboard.c:818: Test failed: 2: gle 1418 clipboard.c:833: Test failed: 2: gle 5 clipboard.c:838: Test failed: 2.0: got 0000 instead of 000d clipboard.c:868: Test failed: 2: gle 1418 clipboard.c:717: Test failed: 3: gle 5 clipboard.c:719: Test failed: 3: gle 1418 clipboard.c:746: Test failed: 3: count 5 clipboard.c:749: Test failed: 3: gle 1418 clipboard.c:755: Test failed: 3: 0003 not available clipboard.c:757: Test failed: 3: count 5 instead of 2 clipboard.c:760: Test failed: 3: gle 5 clipboard.c:765: Test failed: 3.0: got 0000 instead of 000e clipboard.c:805: Test failed: 3: gle 1418 clipboard.c:815: Test failed: 3: count 5 clipboard.c:818: Test failed: 3: gle 1418 clipboard.c:826: Test failed: 3: 0003 not available clipboard.c:828: Test failed: 3: count 5 instead of 2 clipboard.c:833: Test failed: 3: gle 5 clipboard.c:838: Test failed: 3.0: got 0000 instead of 000e clipboard.c:868: Test failed: 3: gle 1418 clipboard.c:717: Test failed: 4: gle 5 clipboard.c:719: Test failed: 4: gle 1418 clipboard.c:746: Test failed: 4: count 6 clipboard.c:749: Test failed: 4: gle 1418 clipboard.c:757: Test failed: 4: count 6 instead of 2 clipboard.c:760: Test failed: 4: gle 5 clipboard.c:765: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:805: Test failed: 4: gle 1418 clipboard.c:815: Test failed: 4: count 6 clipboard.c:818: Test failed: 4: gle 1418 clipboard.c:828: Test failed: 4: count 6 instead of 2 clipboard.c:833: Test failed: 4: gle 5 clipboard.c:838: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:868: Test failed: 4: gle 1418 clipboard.c:717: Test failed: 5: gle 5 clipboard.c:719: Test failed: 5: gle 1418 clipboard.c:746: Test failed: 5: count 7 clipboard.c:749: Test failed: 5: gle 1418 clipboard.c:755: Test failed: 5: 0008 not available clipboard.c:755: Test failed: 5: 0011 not available clipboard.c:757: Test failed: 5: count 7 instead of 3 clipboard.c:760: Test failed: 5: gle 5 clipboard.c:765: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:805: Test failed: 5: gle 1418 clipboard.c:815: Test failed: 5: count 7 clipboard.c:818: Test failed: 5: gle 1418 clipboard.c:826: Test failed: 5: 0008 not available clipboard.c:826: Test failed: 5: 0011 not available clipboard.c:828: Test failed: 5: count 7 instead of 3 clipboard.c:833: Test failed: 5: gle 5 clipboard.c:838: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:868: Test failed: 5: gle 1418 clipboard.c:717: Test failed: 6: gle 5 clipboard.c:719: Test failed: 6: gle 1418 clipboard.c:746: Test failed: 6: count 8 clipboard.c:749: Test failed: 6: gle 1418 clipboard.c:755: Test failed: 6: 0011 not available clipboard.c:757: Test failed: 6: count 8 instead of 3 clipboard.c:760: Test failed: 6: gle 5 clipboard.c:765: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:805: Test failed: 6: gle 1418 clipboard.c:815: Test failed: 6: count 8 clipboard.c:818: Test failed: 6: gle 1418 clipboard.c:826: Test failed: 6: 0011 not available clipboard.c:828: Test failed: 6: count 8 instead of 3 clipboard.c:833: Test failed: 6: gle 5 clipboard.c:838: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:868: Test failed: 6: gle 1418 clipboard.c:717: Test failed: 7: gle 5 clipboard.c:719: Test failed: 7: gle 1418 clipboard.c:746: Test failed: 7: count 9 clipboard.c:749: Test failed: 7: gle 1418 clipboard.c:757: Test failed: 7: count 9 instead of 3 clipboard.c:760: Test failed: 7: gle 5 clipboard.c:765: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:805: Test failed: 7: gle 1418 clipboard.c:815: Test failed: 7: count 9 clipboard.c:818: Test failed: 7: gle 1418 clipboard.c:828: Test failed: 7: count 9 instead of 3 clipboard.c:833: Test failed: 7: gle 5 clipboard.c:838: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:868: Test failed: 7: gle 1418 clipboard.c:874: Test failed: gle 5 clipboard.c:876: Test failed: gle 1418 clipboard.c:878: Test failed: gle 1418 win.c:10262: Test failed: GetForegroundWindow() = 000D0120
=== debiant (32 bit WoW report) ===
user32: Unhandled exception: page fault on read access to 0x30303063 in 32-bit code (0x7e4ef4b1). menu: Timeout monitor: Timeout msg: Timeout resource: Timeout scroll: Timeout
Report validation errors: user32:input crashed (c0000005)
=== debiant (build log) ===
The task timed out
On 4/27/20 10:11 AM, Marvin wrote:
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=70652
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 0003004C win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 0003004C win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 00020174/000F02C4 message 0737 win.c:4070: Test failed: hwnd 000F02C4/000F02C4 message 0202 win.c:4075: Test failed: hwnd 000F02C4/000F02C4 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 0004029A win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 0004029A win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000402A0/000B0150 message 0737 win.c:4070: Test failed: hwnd 000B0150/000B0150 message 0202 win.c:4075: Test failed: hwnd 000B0150/000B0150 message 0203 win.c:4079: Test failed: message 0202 available win.c:4091: Test failed: hwnd 0004029A/0004029A message 0200 win.c:4095: Test failed: hwnd 0004029A/0004029A message 0201 win.c:4104: Test failed: hwnd 000B0150/000B0150 message 0202 win.c:4107: Test failed: hwnd 000B0150/000B0150 message 0201
=== w1064v1809_he (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3900: Test failed: message 0738 available win.c:4025: Test failed: hwnd 000202F2 message 7fff win.c:4104: Test failed: hwnd 000202F2/00110148 message 7fff win.c:4107: Test failed: hwnd 000202F2/00110148 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9553: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9554: Test failed: button under static window didn't get WM_LBUTTONUP win.c:4025: Test failed: hwnd 00010382 message 0282 win.c:4104: Test failed: hwnd 00010382/000C03D4 message 0282 win.c:4107: Test failed: hwnd 00010382/000C03D4 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:4065: Test failed: hwnd 0000000000020174/00000000000F02C8 message 0737 win.c:4070: Test failed: hwnd 00000000000F02C8/00000000000F02C8 message 0202 win.c:4075: Test failed: hwnd 00000000000F02C8/00000000000F02C8 message 0203 win.c:4079: Test failed: message 0202 available
=== debiant (32 bit Chinese:China report) ===
user32: clipboard.c:833: Test failed: 0: gle 5 clipboard.c:838: Test failed: 0.0: got 0000 instead of 0001 clipboard.c:868: Test failed: 0: gle 1418 clipboard.c:717: Test failed: 1: gle 5 clipboard.c:719: Test failed: 1: gle 1418 clipboard.c:746: Test failed: 1: count 4 clipboard.c:749: Test failed: 1: gle 1418 clipboard.c:760: Test failed: 1: gle 5 clipboard.c:765: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:805: Test failed: 1: gle 1418 clipboard.c:815: Test failed: 1: count 4 clipboard.c:818: Test failed: 1: gle 1418 clipboard.c:833: Test failed: 1: gle 5 clipboard.c:838: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:868: Test failed: 1: gle 1418 clipboard.c:717: Test failed: 2: gle 5 clipboard.c:719: Test failed: 2: gle 1418 clipboard.c:746: Test failed: 2: count 4 clipboard.c:749: Test failed: 2: gle 1418 clipboard.c:760: Test failed: 2: gle 5 clipboard.c:765: Test failed: 2.0: got 0000 instead of 000d clipboard.c:805: Test failed: 2: gle 1418 clipboard.c:815: Test failed: 2: count 4 clipboard.c:818: Test failed: 2: gle 1418 clipboard.c:833: Test failed: 2: gle 5 clipboard.c:838: Test failed: 2.0: got 0000 instead of 000d clipboard.c:868: Test failed: 2: gle 1418 clipboard.c:717: Test failed: 3: gle 5 clipboard.c:719: Test failed: 3: gle 1418 clipboard.c:746: Test failed: 3: count 5 clipboard.c:749: Test failed: 3: gle 1418 clipboard.c:755: Test failed: 3: 0003 not available clipboard.c:757: Test failed: 3: count 5 instead of 2 clipboard.c:760: Test failed: 3: gle 5 clipboard.c:765: Test failed: 3.0: got 0000 instead of 000e clipboard.c:805: Test failed: 3: gle 1418 clipboard.c:815: Test failed: 3: count 5 clipboard.c:818: Test failed: 3: gle 1418 clipboard.c:826: Test failed: 3: 0003 not available clipboard.c:828: Test failed: 3: count 5 instead of 2 clipboard.c:833: Test failed: 3: gle 5 clipboard.c:838: Test failed: 3.0: got 0000 instead of 000e clipboard.c:868: Test failed: 3: gle 1418 clipboard.c:717: Test failed: 4: gle 5 clipboard.c:719: Test failed: 4: gle 1418 clipboard.c:746: Test failed: 4: count 6 clipboard.c:749: Test failed: 4: gle 1418 clipboard.c:757: Test failed: 4: count 6 instead of 2 clipboard.c:760: Test failed: 4: gle 5 clipboard.c:765: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:805: Test failed: 4: gle 1418 clipboard.c:815: Test failed: 4: count 6 clipboard.c:818: Test failed: 4: gle 1418 clipboard.c:828: Test failed: 4: count 6 instead of 2 clipboard.c:833: Test failed: 4: gle 5 clipboard.c:838: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:868: Test failed: 4: gle 1418 clipboard.c:717: Test failed: 5: gle 5 clipboard.c:719: Test failed: 5: gle 1418 clipboard.c:746: Test failed: 5: count 7 clipboard.c:749: Test failed: 5: gle 1418 clipboard.c:755: Test failed: 5: 0008 not available clipboard.c:755: Test failed: 5: 0011 not available clipboard.c:757: Test failed: 5: count 7 instead of 3 clipboard.c:760: Test failed: 5: gle 5 clipboard.c:765: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:805: Test failed: 5: gle 1418 clipboard.c:815: Test failed: 5: count 7 clipboard.c:818: Test failed: 5: gle 1418 clipboard.c:826: Test failed: 5: 0008 not available clipboard.c:826: Test failed: 5: 0011 not available clipboard.c:828: Test failed: 5: count 7 instead of 3 clipboard.c:833: Test failed: 5: gle 5 clipboard.c:838: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:868: Test failed: 5: gle 1418 clipboard.c:717: Test failed: 6: gle 5 clipboard.c:719: Test failed: 6: gle 1418 clipboard.c:746: Test failed: 6: count 8 clipboard.c:749: Test failed: 6: gle 1418 clipboard.c:755: Test failed: 6: 0011 not available clipboard.c:757: Test failed: 6: count 8 instead of 3 clipboard.c:760: Test failed: 6: gle 5 clipboard.c:765: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:805: Test failed: 6: gle 1418 clipboard.c:815: Test failed: 6: count 8 clipboard.c:818: Test failed: 6: gle 1418 clipboard.c:826: Test failed: 6: 0011 not available clipboard.c:828: Test failed: 6: count 8 instead of 3 clipboard.c:833: Test failed: 6: gle 5 clipboard.c:838: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:868: Test failed: 6: gle 1418 clipboard.c:717: Test failed: 7: gle 5 clipboard.c:719: Test failed: 7: gle 1418 clipboard.c:746: Test failed: 7: count 9 clipboard.c:749: Test failed: 7: gle 1418 clipboard.c:757: Test failed: 7: count 9 instead of 3 clipboard.c:760: Test failed: 7: gle 5 clipboard.c:765: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:805: Test failed: 7: gle 1418 clipboard.c:815: Test failed: 7: count 9 clipboard.c:818: Test failed: 7: gle 1418 clipboard.c:828: Test failed: 7: count 9 instead of 3 clipboard.c:833: Test failed: 7: gle 5 clipboard.c:838: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:868: Test failed: 7: gle 1418 clipboard.c:874: Test failed: gle 5 clipboard.c:876: Test failed: gle 1418 clipboard.c:878: Test failed: gle 1418 win.c:10262: Test failed: GetForegroundWindow() = 000D0120
=== debiant (32 bit WoW report) ===
user32: Unhandled exception: page fault on read access to 0x30303063 in 32-bit code (0x7e4ef4b1). menu: Timeout monitor: Timeout msg: Timeout resource: Timeout scroll: Timeout
Report validation errors: user32:input crashed (c0000005)
=== debiant (build log) ===
The task timed out
AFAICS the input test segfault is already there since wine-5.6 at least, I'm running a bisect to find where it comes from.
We could also pass the mouse param through, but it wasn't before so we should keep the behavior unchanged.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/focus.c | 10 +++++----- dlls/user32/message.c | 2 +- dlls/user32/user_private.h | 1 + 3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c index f1c883167ed5..09194bb08a78 100644 --- a/dlls/user32/focus.c +++ b/dlls/user32/focus.c @@ -74,7 +74,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, BOOL internal ) { HWND previous = GetActiveWindow(); BOOL ret; @@ -202,12 +202,12 @@ static BOOL set_foreground_window( HWND hwnd, BOOL mouse ) if (send_msg_old) /* old window belongs to other thread */ SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 ); 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 ); 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 +249,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 +296,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 af909f61f6d8..0f55f6ad1b3b 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 && GetWindowThreadProcessId( GetForegroundWindow(), NULL ) == GetCurrentThreadId()) return 0; - return (LRESULT)SetActiveWindow( (HWND)wparam ); + return (LRESULT)set_active_window( (HWND)wparam, NULL, FALSE, TRUE, TRUE ); case WM_WINE_KEYBOARD_LL_HOOK: case WM_WINE_MOUSE_LL_HOOK: { diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 7e294558ef12..2f46908fa0a1 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 internal ) 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=70653
Your paranoid android.
=== debiant (32 bit Chinese:China report) ===
user32: Unhandled exception: page fault on read access to 0x70263034 in 32-bit code (0x7e468481).
Report validation errors: user32:input crashed (c0000005)
We will need this to discard a specific internal message type without processing any of the other messages.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- server/queue.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/server/queue.c b/server/queue.c index 84ee0f9a4eac..fcb15d91daa1 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2386,8 +2386,8 @@ DECL_HANDLER(post_quit_message) /* get a message from the current queue */ DECL_HANDLER(get_message) { + struct message *msg; struct timer *timer; - struct list *ptr; struct msg_queue *queue = get_current_queue(); user_handle_t get_win = get_user_full_handle( req->get_win ); unsigned int filter = req->flags >> 16; @@ -2405,9 +2405,12 @@ DECL_HANDLER(get_message) if (!filter) filter = QS_ALLINPUT;
/* first check for sent messages */ - if ((ptr = list_head( &queue->msg_list[SEND_MESSAGE] ))) + LIST_FOR_EACH_ENTRY( msg, &queue->msg_list[SEND_MESSAGE], struct message, entry ) { - struct message *msg = LIST_ENTRY( ptr, struct message, entry ); + /* skip filtered internal messages */ + if ((req->get_first & 0x80000000) && (req->get_last & 0x80000000) && + (req->get_first > msg->msg || req->get_last < msg->msg)) + continue; receive_message( queue, msg, reply ); return; }
This will allow us to discard internal messages without processing them.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/message.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 0f55f6ad1b3b..118522ea4722 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -2747,7 +2747,8 @@ static inline void call_sendmsg_callback( SENDASYNCPROC callback, HWND hwnd, UIN * available; -1 on error. * All pending sent messages are processed before returning. */ -static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, UINT changed_mask ) +static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, + UINT changed_mask, BOOL discard_internal ) { LRESULT result; struct user_thread_info *thread_info = get_user_thread_info(); @@ -2816,6 +2817,9 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, continue; }
+ if (discard_internal && (info.msg.message & 0x80000000)) + continue; + TRACE( "got type %d msg %x (%s) hwnd %p wp %lx lp %lx\n", info.type, info.msg.message, (info.type == MSG_WINEVENT) ? "MSG_WINEVENT" : SPY_GetMsgName(info.msg.message, info.msg.hwnd), @@ -2955,7 +2959,8 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, } else peek_message( msg, info.msg.hwnd, info.msg.message, - info.msg.message, flags | PM_REMOVE, changed_mask ); + info.msg.message, flags | PM_REMOVE, changed_mask, + discard_internal ); continue; } if (info.msg.message >= WM_DDE_FIRST && info.msg.message <= WM_DDE_LAST) @@ -2999,7 +3004,7 @@ static int peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, UINT flags, static inline void process_sent_messages(void) { MSG msg; - peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, 0 ); + peek_message( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE, 0, FALSE ); }
@@ -3800,7 +3805,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, USER_CheckNotLock(); check_for_driver_events( 0 );
- ret = peek_message( &msg, hwnd, first, last, flags, 0 ); + ret = peek_message( &msg, hwnd, first, last, flags, 0, FALSE ); if (ret < 0) return FALSE;
if (!ret) @@ -3808,7 +3813,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, flush_window_surfaces( TRUE ); ret = wow_handlers.wait_message( 0, NULL, 0, QS_ALLINPUT, 0 ); /* if we received driver events, check again for a pending message */ - if (ret == WAIT_TIMEOUT || peek_message( &msg, hwnd, first, last, flags, 0 ) <= 0) return FALSE; + if (ret == WAIT_TIMEOUT || peek_message( &msg, hwnd, first, last, flags, 0, FALSE ) <= 0) + return FALSE; }
check_for_driver_events( msg.message ); @@ -3862,7 +3868,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT } else mask = QS_ALLINPUT;
- while (!(ret = peek_message( msg, hwnd, first, last, PM_REMOVE | (mask << 16), mask ))) + while (!(ret = peek_message( msg, hwnd, first, last, PM_REMOVE | (mask << 16), mask, FALSE ))) { wait_objects( 1, &server_queue, INFINITE, mask & (QS_SENDMESSAGE | QS_SMRESULT), mask, 0 ); }
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=70655
Your paranoid android.
=== debiant (32 bit WoW report) ===
user32: Unhandled exception: page fault on read access to 0x30303063 in 32-bit code (0x7e4ef481). win.c:10262: Test failed: GetForegroundWindow() = 000D0120
Report validation errors: user32:input crashed (c0000005)
This discards the pending WM_WINE_SETACTIVEWINDOW messages when current thread becomes -or is already- foreground, and before setting the active window.
Although it's still not enough, it should help solving several focus inversions when WM messages arrive late, or when multiple windows are created without the application checking its messages.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/focus.c | 3 +++ dlls/user32/message.c | 12 ++++++++++++ dlls/user32/tests/win.c | 10 +++++----- dlls/user32/user_private.h | 1 + 4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c index 09194bb08a78..cab557eb3a35 100644 --- a/dlls/user32/focus.c +++ b/dlls/user32/focus.c @@ -87,6 +87,9 @@ BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus, BOOL inte return TRUE; }
+ if (hwnd && !internal && GetWindowThreadProcessId( GetForegroundWindow(), NULL ) == GetCurrentThreadId()) + discard_internal_messages( WM_WINE_SETACTIVEWINDOW ); + /* call CBT hook chain */ cbt.fMouse = mouse; cbt.hWndActive = previous; diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 118522ea4722..c731f8f8ba23 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3008,6 +3008,18 @@ static inline void process_sent_messages(void) }
+/*********************************************************************** + * discard_internal_messages + * + * Remove all matching internal messages. + */ +void discard_internal_messages(UINT msg) +{ + MSG message; + peek_message( &message, 0, msg, msg, PM_REMOVE | PM_QS_SENDMESSAGE, 0, TRUE ); +} + + /*********************************************************************** * get_server_queue_handle * diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 90c49a8f5c2b..3aef70d95a92 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -3290,15 +3290,15 @@ static struct set_foreground_test_desc set_foreground_tests[] = { {1, FALSE, FALSE, TRUE, FALSE, 0, FALSE, 0, FALSE, 6, FALSE, 0}, {1, TRUE, FALSE, TRUE, FALSE, 0, TRUE, 1, FALSE, 6, FALSE, 0},
- {2, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, - {2, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, - {2, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, TRUE, 0, TRUE, 1}, + {2, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, + {2, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, + {2, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, FALSE, 0, FALSE, 1}, {2, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, FALSE, 6, FALSE, 0}, - {2, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, TRUE, 0, TRUE, 1}, + {2, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, FALSE, 0, FALSE, 1}, {2, TRUE, FALSE, TRUE, TRUE, 8, TRUE, 1, FALSE, 6, FALSE, 0},
{0, FALSE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, - {0, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, TRUE, 0, TRUE, 1}, + {0, TRUE, FALSE, FALSE, FALSE, 0, FALSE, 6, FALSE, 0, FALSE, 1}, {0, FALSE, TRUE, FALSE, FALSE, 6, FALSE, 0, FALSE, 0, FALSE, 1}, {0, TRUE, TRUE, FALSE, FALSE, 6, TRUE, 1, FALSE, 6, FALSE, 0}, {0, FALSE, FALSE, TRUE, TRUE, 8, FALSE, 0, FALSE, 0, FALSE, 1}, diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 2f46908fa0a1..6b614dc4c99c 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -233,6 +233,7 @@ 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 internal ) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; +extern void discard_internal_messages( UINT msg ); extern void free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN; extern void invalidate_dce( struct tagWND *win, const RECT *rect ) DECLSPEC_HIDDEN; extern HDC get_display_dc(void) 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=70656
Your paranoid android.
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 00030060 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 00030060 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000200E4/000C02D0 message 0737 win.c:4070: Test failed: hwnd 000C02D0/000C02D0 message 0202 win.c:4075: Test failed: hwnd 000C02D0/000C02D0 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000302A0 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 000302A0 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000302AC/000D01A0 message 0737 win.c:4070: Test failed: hwnd 000D01A0/000D01A0 message 0202 win.c:4075: Test failed: hwnd 000D01A0/000D01A0 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_he (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process
=== w1064v1809_ja (32 bit report) ===
user32: win.c:9612: Test failed: didn't get start_event win.c:9553: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9554: Test failed: button under static window didn't get WM_LBUTTONUP win.c:4025: Test failed: hwnd 000202F2 message 7fff win.c:4104: Test failed: hwnd 000202F2/00160090 message 7fff win.c:4107: Test failed: hwnd 000202F2/00160090 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:4025: Test failed: hwnd 00010384 message 0282 win.c:4104: Test failed: hwnd 00010384/000C03D6 message 0282 win.c:4107: Test failed: hwnd 00010384/000C03D6 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:4065: Test failed: hwnd 0000000000020174/00000000000D02CA message 0737 win.c:4070: Test failed: hwnd 00000000000D02CA/00000000000D02CA message 0202 win.c:4075: Test failed: hwnd 00000000000D02CA/00000000000D02CA message 0203 win.c:4079: Test failed: message 0202 available
=== debiant (64 bit WoW report) ===
user32: clipboard.c:833: Test failed: 0: gle 5 clipboard.c:838: Test failed: 0.0: got 0000 instead of 0001 clipboard.c:868: Test failed: 0: gle 1418 clipboard.c:717: Test failed: 1: gle 5 clipboard.c:719: Test failed: 1: gle 1418 clipboard.c:746: Test failed: 1: count 4 clipboard.c:749: Test failed: 1: gle 1418 clipboard.c:760: Test failed: 1: gle 5 clipboard.c:765: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:805: Test failed: 1: gle 1418 clipboard.c:815: Test failed: 1: count 4 clipboard.c:818: Test failed: 1: gle 1418 clipboard.c:833: Test failed: 1: gle 5 clipboard.c:838: Test failed: 1.0: got 0000 instead of 0007 clipboard.c:868: Test failed: 1: gle 1418 clipboard.c:717: Test failed: 2: gle 5 clipboard.c:719: Test failed: 2: gle 1418 clipboard.c:746: Test failed: 2: count 4 clipboard.c:749: Test failed: 2: gle 1418 clipboard.c:760: Test failed: 2: gle 5 clipboard.c:765: Test failed: 2.0: got 0000 instead of 000d clipboard.c:805: Test failed: 2: gle 1418 clipboard.c:815: Test failed: 2: count 4 clipboard.c:818: Test failed: 2: gle 1418 clipboard.c:833: Test failed: 2: gle 5 clipboard.c:838: Test failed: 2.0: got 0000 instead of 000d clipboard.c:868: Test failed: 2: gle 1418 clipboard.c:717: Test failed: 3: gle 5 clipboard.c:719: Test failed: 3: gle 1418 clipboard.c:746: Test failed: 3: count 5 clipboard.c:749: Test failed: 3: gle 1418 clipboard.c:755: Test failed: 3: 0003 not available clipboard.c:757: Test failed: 3: count 5 instead of 2 clipboard.c:760: Test failed: 3: gle 5 clipboard.c:765: Test failed: 3.0: got 0000 instead of 000e clipboard.c:805: Test failed: 3: gle 1418 clipboard.c:815: Test failed: 3: count 5 clipboard.c:818: Test failed: 3: gle 1418 clipboard.c:826: Test failed: 3: 0003 not available clipboard.c:828: Test failed: 3: count 5 instead of 2 clipboard.c:833: Test failed: 3: gle 5 clipboard.c:838: Test failed: 3.0: got 0000 instead of 000e clipboard.c:868: Test failed: 3: gle 1418 clipboard.c:717: Test failed: 4: gle 5 clipboard.c:719: Test failed: 4: gle 1418 clipboard.c:746: Test failed: 4: count 6 clipboard.c:749: Test failed: 4: gle 1418 clipboard.c:757: Test failed: 4: count 6 instead of 2 clipboard.c:760: Test failed: 4: gle 5 clipboard.c:765: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:805: Test failed: 4: gle 1418 clipboard.c:815: Test failed: 4: count 6 clipboard.c:818: Test failed: 4: gle 1418 clipboard.c:828: Test failed: 4: count 6 instead of 2 clipboard.c:833: Test failed: 4: gle 5 clipboard.c:838: Test failed: 4.0: got 0000 instead of 0003 clipboard.c:868: Test failed: 4: gle 1418 clipboard.c:717: Test failed: 5: gle 5 clipboard.c:719: Test failed: 5: gle 1418 clipboard.c:746: Test failed: 5: count 7 clipboard.c:749: Test failed: 5: gle 1418 clipboard.c:755: Test failed: 5: 0008 not available clipboard.c:755: Test failed: 5: 0011 not available clipboard.c:757: Test failed: 5: count 7 instead of 3 clipboard.c:760: Test failed: 5: gle 5 clipboard.c:765: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:805: Test failed: 5: gle 1418 clipboard.c:815: Test failed: 5: count 7 clipboard.c:818: Test failed: 5: gle 1418 clipboard.c:826: Test failed: 5: 0008 not available clipboard.c:826: Test failed: 5: 0011 not available clipboard.c:828: Test failed: 5: count 7 instead of 3 clipboard.c:833: Test failed: 5: gle 5 clipboard.c:838: Test failed: 5.0: got 0000 instead of 0002 clipboard.c:868: Test failed: 5: gle 1418 clipboard.c:717: Test failed: 6: gle 5 clipboard.c:719: Test failed: 6: gle 1418 clipboard.c:746: Test failed: 6: count 8 clipboard.c:749: Test failed: 6: gle 1418 clipboard.c:755: Test failed: 6: 0011 not available clipboard.c:757: Test failed: 6: count 8 instead of 3 clipboard.c:760: Test failed: 6: gle 5 clipboard.c:765: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:805: Test failed: 6: gle 1418 clipboard.c:815: Test failed: 6: count 8 clipboard.c:818: Test failed: 6: gle 1418 clipboard.c:826: Test failed: 6: 0011 not available clipboard.c:828: Test failed: 6: count 8 instead of 3 clipboard.c:833: Test failed: 6: gle 5 clipboard.c:838: Test failed: 6.0: got 0000 instead of 0008 clipboard.c:868: Test failed: 6: gle 1418 clipboard.c:717: Test failed: 7: gle 5 clipboard.c:719: Test failed: 7: gle 1418 clipboard.c:746: Test failed: 7: count 9 clipboard.c:749: Test failed: 7: gle 1418 clipboard.c:757: Test failed: 7: count 9 instead of 3 clipboard.c:760: Test failed: 7: gle 5 clipboard.c:765: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:805: Test failed: 7: gle 1418 clipboard.c:815: Test failed: 7: count 9 clipboard.c:818: Test failed: 7: gle 1418 clipboard.c:828: Test failed: 7: count 9 instead of 3 clipboard.c:833: Test failed: 7: gle 5 clipboard.c:838: Test failed: 7.0: got 0000 instead of 0011 clipboard.c:868: Test failed: 7: gle 1418 clipboard.c:874: Test failed: gle 5 clipboard.c:876: Test failed: gle 1418 clipboard.c:878: Test failed: gle 1418 Unhandled exception: page fault on read access to 0x30303063 in 32-bit code (0x7e520531).
Report validation errors: user32:input crashed (c0000005)
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=70650
Your paranoid android.
=== w1064v1507 (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 00030294 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 00030294 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000200E4/001302C6 message 0737 win.c:4070: Test failed: hwnd 001302C6/001302C6 message 0202 win.c:4075: Test failed: hwnd 001302C6/001302C6 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 00050052 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 00050052 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000502B2/000B032A message 0737 win.c:4070: Test failed: hwnd 000B032A/000B032A message 0202 win.c:4075: Test failed: hwnd 000B032A/000B032A message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3900: Test failed: message 0738 available win.c:4025: Test failed: hwnd 000202FE message 7fff win.c:4104: Test failed: hwnd 000202FE/00120320 message 7fff win.c:4107: Test failed: hwnd 000202FE/00120320 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process win.c:4025: Test failed: hwnd 00040198 message 0282 win.c:4104: Test failed: hwnd 00040198/000D0144 message 0282 win.c:4107: Test failed: hwnd 00040198/000D0144 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:4065: Test failed: hwnd 00000000000200E4/00000000000C02C4 message 0737 win.c:4070: Test failed: hwnd 00000000000C02C4/00000000000C02C4 message 0202 win.c:4075: Test failed: hwnd 00000000000C02C4/00000000000C02C4 message 0203 win.c:4079: Test failed: message 0202 available
=== debiant (32 bit Chinese:China report) ===
user32: win.c:10262: Test failed: GetForegroundWindow() = 00020052
On 4/27/20 9:26 AM, Marvin wrote:
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=70650
Your paranoid android.
=== w1064v1507 (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process
=== w1064v1809 (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 00030294 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 00030294 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000200E4/001302C6 message 0737 win.c:4070: Test failed: hwnd 001302C6/001302C6 message 0202 win.c:4075: Test failed: hwnd 001302C6/001302C6 message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 00050052 win.c:3167: Test failed: GetFocus() = 00000000 win.c:3179: Test failed: GetFocus() = 00000000 win.c:3182: Test failed: GetFocus() = 00000000 win.c:3185: Test failed: GetFocus() = 00000000 win.c:3188: Test failed: GetActiveWindow() = 00050052 win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:4065: Test failed: hwnd 000502B2/000B032A message 0737 win.c:4070: Test failed: hwnd 000B032A/000B032A message 0202 win.c:4075: Test failed: hwnd 000B032A/000B032A message 0203 win.c:4079: Test failed: message 0202 available
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3900: Test failed: message 0738 available win.c:4025: Test failed: hwnd 000202FE message 7fff win.c:4104: Test failed: hwnd 000202FE/00120320 message 7fff win.c:4107: Test failed: hwnd 000202FE/00120320 message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:9627: Test failed: Timed out waiting for the child process win.c:4025: Test failed: hwnd 00040198 message 0282 win.c:4104: Test failed: hwnd 00040198/000D0144 message 0282 win.c:4107: Test failed: hwnd 00040198/000D0144 message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000003004A win.c:3167: Test failed: GetFocus() = 0000000000000000 win.c:3179: Test failed: GetFocus() = 0000000000000000 win.c:3182: Test failed: GetFocus() = 0000000000000000 win.c:3185: Test failed: GetFocus() = 0000000000000000 win.c:3188: Test failed: GetActiveWindow() = 000000000003004A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:4065: Test failed: hwnd 00000000000200E4/00000000000C02C4 message 0737 win.c:4070: Test failed: hwnd 00000000000C02C4/00000000000C02C4 message 0202 win.c:4075: Test failed: hwnd 00000000000C02C4/00000000000C02C4 message 0203 win.c:4079: Test failed: message 0202 available
=== debiant (32 bit Chinese:China report) ===
user32: win.c:10262: Test failed: GetForegroundWindow() = 00020052
I believe these failures are unrelated, as the happen in test_SetActiveWindow, test_mouse_input and test_keyboard_input, which are called before the changes included here.
They are also happening randomly before the patch, for instance here:
https://testbot.winehq.org/JobDetails.pl?Key=70651#k304