Fix a regression from "bb496ea8 - server: Always queue mouse messages delivered to another window."
Fix ETHER VAPOR Remaster (214570) launches to black screen when the cursor is in the game window.
The game calls ReleaseCapture() when handling WM_MOUSEMOVE. After bb496ea8, WM_MOUSEMOVE is always queued because the message window is NULL. So ReleaseCapture() ends up queuing another WM_MOUSEMOVE. So the game ends up handling infinite WM_MOUSEMOVE messages at startup and is not able to do anything.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/user32/tests/win.c | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 1b03e64181a..c1c2cc52059 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -13064,6 +13064,82 @@ static void test_shell_tray(void) DestroyWindow(hwnd); }
+static int wm_mousemove_count; +static BOOL do_release_capture; + +static LRESULT WINAPI test_ReleaseCapture_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) +{ + if (msg == WM_MOUSEMOVE) + { + wm_mousemove_count++; + if (wm_mousemove_count >= 100) + return 1; + + if (do_release_capture) + ReleaseCapture(); + return 0; + } + return DefWindowProcA(hwnd, msg, wp, lp); +} + +static void test_ReleaseCapture(void) +{ + WNDCLASSA cls = {0}; + ATOM atom; + HWND hwnd; + POINT pt; + BOOL ret; + + cls.lpfnWndProc = test_ReleaseCapture_proc; + cls.hInstance = GetModuleHandleA(0); + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(BLACK_BRUSH); + cls.lpszClassName = "test_ReleaseCapture_class"; + atom = RegisterClassA(&cls); + ok(!!atom, "RegisterClassA failed, error %#lx.\n", GetLastError()); + + hwnd = CreateWindowExA(WS_EX_TOPMOST, cls.lpszClassName, "", WS_POPUP | WS_VISIBLE, 100, 100, + 100, 100, NULL, NULL, 0, NULL); + ok(!!hwnd, "CreateWindowA failed, error %#lx.\n", GetLastError()); + ret = SetForegroundWindow(hwnd); + ok(ret, "SetForegroundWindow failed, error %#lx.\n", GetLastError()); + GetCursorPos(&pt); + ret = SetCursorPos(150, 150); + ok(ret, "SetCursorPos failed, error %#lx.\n", GetLastError()); + flush_events(TRUE); + + /* Test a Wine bug that WM_MOUSEMOVE is post too many times when calling ReleaseCapture() during + * handling WM_MOUSEMOVE and the cursor is on the window */ + do_release_capture = TRUE; + ret = ReleaseCapture(); + ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError()); + flush_events(TRUE); + do_release_capture = FALSE; + todo_wine + ok(wm_mousemove_count < 10, "Got too many WM_MOUSEMOVE.\n"); + + /* Test that ReleaseCapture() should send a WM_MOUSEMOVE if a window is captured */ + SetCapture(hwnd); + wm_mousemove_count = 0; + ret = ReleaseCapture(); + ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError()); + flush_events(TRUE); + ok(wm_mousemove_count == 1, "Got no WM_MOUSEMOVE.\n"); + + /* Test that ReleaseCapture() shouldn't send WM_MOUSEMOVE if no window is captured */ + wm_mousemove_count = 0; + ret = ReleaseCapture(); + ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError()); + flush_events(TRUE); + todo_wine + ok(wm_mousemove_count == 0, "Got WM_MOUSEMOVE.\n"); + + ret = SetCursorPos(pt.x, pt.y); + ok(ret, "SetCursorPos failed, error %#lx.\n", GetLastError()); + DestroyWindow(hwnd); + UnregisterClassA(cls.lpszClassName, GetModuleHandleA(0)); +} + START_TEST(win) { char **argv; @@ -13246,6 +13322,7 @@ START_TEST(win) test_cancel_mode(); test_DragDetect(); test_WM_NCCALCSIZE(); + test_ReleaseCapture();
/* add the tests above this line */ if (hhook) UnhookWindowsHookEx(hhook);
From: Zhiyi Zhang zzhang@codeweavers.com
Fix a regression from "bb496ea8 - server: Always queue mouse messages delivered to another window."
Fix ETHER VAPOR Remaster (214570) launches to black screen when the cursor is in the game window.
The game calls ReleaseCapture() when handling WM_MOUSEMOVE. After bb496ea8, WM_MOUSEMOVE is always queued because the message window is NULL. So ReleaseCapture() ends up queuing another WM_MOUSEMOVE. So the game ends up handling infinite WM_MOUSEMOVE messages at startup and is not able to do anything. --- dlls/user32/tests/win.c | 2 -- dlls/win32u/input.c | 7 +++++-- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index c1c2cc52059..775164e3e9f 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -13115,7 +13115,6 @@ static void test_ReleaseCapture(void) ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError()); flush_events(TRUE); do_release_capture = FALSE; - todo_wine ok(wm_mousemove_count < 10, "Got too many WM_MOUSEMOVE.\n");
/* Test that ReleaseCapture() should send a WM_MOUSEMOVE if a window is captured */ @@ -13131,7 +13130,6 @@ static void test_ReleaseCapture(void) ret = ReleaseCapture(); ok(ret, "ReleaseCapture failed, error %#lx.\n", GetLastError()); flush_events(TRUE); - todo_wine ok(wm_mousemove_count == 0, "Got WM_MOUSEMOVE.\n");
ret = SetCursorPos(pt.x, pt.y); diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 0f6b9482942..4a7c04f66c5 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1770,10 +1770,13 @@ HWND WINAPI NtUserSetCapture( HWND hwnd ) */ BOOL release_capture(void) { - BOOL ret = set_capture_window( 0, 0, NULL ); + HWND previous = NULL; + BOOL ret; + + ret = set_capture_window( 0, 0, &previous );
/* Somebody may have missed some mouse movements */ - if (ret) + if (ret && previous) { INPUT input = { .type = INPUT_MOUSE }; input.mi.dwFlags = MOUSEEVENTF_MOVE;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=143878
Your paranoid android.
=== w1064v1507 (32 bit report) ===
user32: win.c:13062: Test failed: window is minimized.
=== w10pro64_ar (64 bit report) ===
user32: win.c:190: Test failed: didn't get start_event win.c:10332: Test failed: WindowFromPoint returned 000000000002035E, expected 0000000000000000 win.c:10342: Test failed: WindowFromPoint returned 000000000002035E, expected 0000000000000000 win.c:10345: Test failed: Timed out waiting for the child process win.c:10236: Test failed: WindowFromPoint returned 00000000000202FE, expected 000000000002035E win.c:10244: Test failed: WindowFromPoint returned 00000000000202FE, expected 000000000003035C win.c:10250: Test failed: CreateWindowEx failed win.c:10265: Test failed: transparent window didn't get WM_NCHITTEST message
This merge request was approved by Rémi Bernon.
Unrelated test failures.