Fixes black screen in SWTOR after window minimize / maximize or switching window in full screen mode.
Signed-off-by: Paul Gofman gofmanp@gmail.com --- v2: Do not add an explicit server call.
dlls/user32/tests/win.c | 125 ++++++++++++++++++++++++++++++++++++++-- dlls/user32/winpos.c | 20 +++++-- 2 files changed, 136 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 639eef4c42..c6fbd7c12a 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -11733,6 +11733,114 @@ static void test_arrange_iconic_windows(void) ok(ret, "failed to restore minimized metrics, error %u\n", GetLastError()); }
+static void other_process_proc(HWND hwnd) +{ + HANDLE window_ready_event, test_done_event; + WINDOWPLACEMENT wp; + DWORD ret; + + window_ready_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_opw_window"); + ok(!!window_ready_event, "OpenEvent failed.\n"); + test_done_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_opw_test"); + ok(!!test_done_event, "OpenEvent failed.\n"); + + /* SW_SHOW */ + ret = WaitForSingleObject(window_ready_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "Unexpected ret %#x.\n", ret); + ok(wp.showCmd == SW_SHOWNORMAL, "Unexpected showCmd %#x.\n", wp.showCmd); + ok(!wp.flags, "Unexpected flags %#x.\n", wp.flags); + SetEvent(test_done_event); + + /* SW_SHOWMAXIMIZED */ + ret = WaitForSingleObject(window_ready_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "Unexpected ret %#x.\n", ret); + ok(wp.showCmd == SW_SHOWMAXIMIZED, "Unexpected showCmd %#x.\n", wp.showCmd); + todo_wine ok(wp.flags == WPF_RESTORETOMAXIMIZED, "Unexpected flags %#x.\n", wp.flags); + SetEvent(test_done_event); + + /* SW_SHOWMINIMIZED */ + ret = WaitForSingleObject(window_ready_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "Unexpected ret %#x.\n", ret); + ok(wp.showCmd == SW_SHOWMINIMIZED, "Unexpected showCmd %#x.\n", wp.showCmd); + todo_wine ok(wp.flags == WPF_RESTORETOMAXIMIZED, "Unexpected flags %#x.\n", wp.flags); + SetEvent(test_done_event); + + /* SW_RESTORE */ + ret = WaitForSingleObject(window_ready_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "Unexpected ret %#x.\n", ret); + ok(wp.showCmd == SW_SHOWMAXIMIZED, "Unexpected showCmd %#x.\n", wp.showCmd); + todo_wine ok(wp.flags == WPF_RESTORETOMAXIMIZED, "Unexpected flags %#x.\n", wp.flags); + SetEvent(test_done_event); + + CloseHandle(window_ready_event); + CloseHandle(test_done_event); +} + +static void test_other_process_window(const char *argv0) +{ + HANDLE window_ready_event, test_done_event; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + char cmd[MAX_PATH]; + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, + 100, 100, 100, 100, 0, 0, NULL, NULL); + ok(!!hwnd, "CreateWindowEx failed.\n"); + + window_ready_event = CreateEventA(NULL, FALSE, FALSE, "test_opw_window"); + ok(!!window_ready_event, "CreateEvent failed.\n"); + test_done_event = CreateEventA(NULL, FALSE, FALSE, "test_opw_test"); + ok(!!test_done_event, "CreateEvent failed.\n"); + + sprintf(cmd, "%s win test_other_process_window %p", argv0, hwnd); + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + + ok(CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, + &startup, &info), "CreateProcess failed.\n"); + + ret = ShowWindow(hwnd, SW_SHOW); + ok(!ret, "Unexpected ret %#x.\n", ret); + SetEvent(window_ready_event); + ret = WaitForSingleObject(test_done_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + + ret = ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok(ret, "Unexpected ret %#x.\n", ret); + SetEvent(window_ready_event); + ret = WaitForSingleObject(test_done_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + + ret = ShowWindow(hwnd, SW_SHOWMINIMIZED); + ok(ret, "Unexpected ret %#x.\n", ret); + SetEvent(window_ready_event); + ret = WaitForSingleObject(test_done_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + + ret = ShowWindow(hwnd, SW_RESTORE); + ok(ret, "Unexpected ret %#x.\n", ret); + SetEvent(window_ready_event); + ret = WaitForSingleObject(test_done_event, 5000); + ok(ret == WAIT_OBJECT_0, "Unexpected ret %x.\n", ret); + + winetest_wait_child_process(info.hProcess); + CloseHandle(window_ready_event); + CloseHandle(test_done_event); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + DestroyWindow(hwnd); +} + START_TEST(win) { char **argv; @@ -11762,16 +11870,24 @@ START_TEST(win) pAdjustWindowRectExForDpi = (void *)GetProcAddress( user32, "AdjustWindowRectExForDpi" ); pSystemParametersInfoForDpi = (void *)GetProcAddress( user32, "SystemParametersInfoForDpi" );
- if (argc==4 && !strcmp(argv[2], "create_children")) + if (argc == 4) { HWND hwnd;
sscanf(argv[3], "%p", &hwnd); - window_from_point_proc(hwnd); - return; + if (!strcmp(argv[2], "create_children")) + { + window_from_point_proc(hwnd); + return; + } + else if (!strcmp(argv[2], "test_other_process_window")) + { + other_process_proc(hwnd); + return; + } }
- if (argc==3 && !strcmp(argv[2], "winproc_limit")) + if (argc == 3 && !strcmp(argv[2], "winproc_limit")) { test_winproc_limit(); return; @@ -11894,6 +12010,7 @@ START_TEST(win) test_IsWindowEnabled(); test_window_placement(); test_arrange_iconic_windows(); + test_other_process_window(argv[0]);
/* add the tests above this line */ if (hhook) UnhookWindowsHookEx(hhook); diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index 5837c179e4..b3e259429e 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1280,17 +1280,27 @@ BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) } if (pWnd == WND_OTHER_PROCESS) { - if (!IsWindow( hwnd )) return FALSE; - FIXME( "not supported on other process window %p\n", hwnd ); - /* provide some dummy information */ + RECT normal_position; + DWORD style; + + FIXME("not fully supported on other process window %p.\n", hwnd); + + if (!GetWindowRect(hwnd, &normal_position)) + return FALSE; + wndpl->length = sizeof(*wndpl); - wndpl->showCmd = SW_SHOWNORMAL; + style = GetWindowLongW(hwnd, GWL_STYLE); + if (style & WS_MINIMIZE) + wndpl->showCmd = SW_SHOWMINIMIZED; + else + wndpl->showCmd = (style & WS_MAXIMIZE) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL; + /* provide some dummy information */ wndpl->flags = 0; wndpl->ptMinPosition.x = -1; wndpl->ptMinPosition.y = -1; wndpl->ptMaxPosition.x = -1; wndpl->ptMaxPosition.y = -1; - GetWindowRect( hwnd, &wndpl->rcNormalPosition ); + wndpl->rcNormalPosition = normal_position; return TRUE; }
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=55806
Your paranoid android.
=== wvistau64_he (32 bit report) ===
user32: win.c:9447: Test failed: didn't get start_event win.c:9451: Test failed: WindowFromPoint returned 000401AE, expected 00000000 win.c:9459: Test failed: WindowFromPoint returned 000401AE, expected 00000000 win.c:9360: Test failed: WindowFromPoint returned 0002019E, expected 000401AE win.c:9367: Test failed: WindowFromPoint returned 0002019E, expected 000301F2 win.c:9373: Test failed: CreateWindowEx failed win.c:9388: Test failed: transparent window didn't get WM_NCHITTEST message win.c:9389: Test failed: button under static window didn't get WM_LBUTTONUP
=== w2008s64 (32 bit report) ===
Report errors: user32:win is missing some failure messages
=== w1064v1809 (32 bit report) ===
user32: win.c:3141: Test failed: SetActiveWindow returned 00000000 instead of 000803BE win.c:3199: Test failed: expected 000803BE, got 00000000 win.c:3811: Test failed: hwnd 00040038 message 0060 win.c:3951: Test failed: hwnd 00BB0380/00BB0380 message 00a1 win.c:3255: Test failed: SetActiveWindow(0) returned 00000000 instead of 000803BE
=== w1064v1809 (64 bit report) ===
user32: win.c:3141: Test failed: SetActiveWindow returned 0000000000000000 instead of 00000000000803BE win.c:3199: Test failed: expected 00000000000803BE, got 0000000000000000 win.c:3811: Test failed: hwnd 0000000000040038 message 0060 win.c:3951: Test failed: hwnd 0000000000180422/0000000000180422 message 00a1 win.c:3255: Test failed: SetActiveWindow(0) returned 0000000000000000 instead of 00000000000803BE
=== debian10 (32 bit report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit Chinese:China report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (32 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds
Report errors: user32:msg prints too much data (35221 bytes)
=== debian10 (64 bit WoW report) ===
user32: msg.c:5145: Test succeeded inside todo block: ShowWindow(SW_SHOWMINIMIZED):overlapped: marked "todo_wine" but succeeds win.c:10097: Test failed: GetForegroundWindow() = 00000000
Report errors: user32:msg prints too much data (35221 bytes)