Some applications (e.g. Lego Worlds) use (-32000,-32000) to determine whether a window is minimized.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/user32/tests/win.c | 52 +++++++++++++++++++++++++++++++++++++++++ dlls/user32/winpos.c | 8 +++++++ 2 files changed, 60 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 843da89..19a0db2 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -11593,6 +11593,58 @@ todo_wine ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n", wine_dbgstr_rect(&wp.rcNormalPosition));
+ wp.flags = WPF_SETMINPOSITION; + wp.showCmd = SW_NORMAL; + wp.ptMinPosition.x = wp.ptMinPosition.y = 100; + wp.ptMaxPosition.x = wp.ptMaxPosition.y = 100; + wp.rcNormalPosition = orig; + ret = SetWindowPlacement(hwnd, &wp); + ok(ret, "failed to set window placement, error %u\n", GetLastError()); + + ShowWindow(hwnd, SW_MINIMIZE); + + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "failed to get window placement, error %u\n", GetLastError()); + ok(wp.showCmd == SW_SHOWMINIMIZED, "got show cmd %u\n", wp.showCmd); + ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000, + "got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y); +todo_wine + ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1, + "got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y); + ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n", + wine_dbgstr_rect(&wp.rcNormalPosition)); + + ret = SetWindowPos(hwnd, NULL, 100, 100, 151, 151, SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "failed to set window pos, error %u\n", GetLastError()); + + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "failed to get window placement, error %u\n", GetLastError()); + ok(wp.showCmd == SW_SHOWMINIMIZED, "got show cmd %u\n", wp.showCmd); + ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000, + "got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y); +todo_wine + ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1, + "got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y); + ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n", + wine_dbgstr_rect(&wp.rcNormalPosition)); + GetWindowRect(hwnd, &rect); + ok(rect.left == -32000 && rect.top == -32000, "got window rect %s\n", wine_dbgstr_rect(&rect)); + + ShowWindow(hwnd, SW_SHOWNORMAL); + + ret = GetWindowPlacement(hwnd, &wp); + ok(ret, "failed to get window placement, error %u\n", GetLastError()); + ok(wp.showCmd == SW_NORMAL, "got show cmd %u\n", wp.showCmd); + ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000, + "got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y); +todo_wine + ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1, + "got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y); + ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n", + wine_dbgstr_rect(&wp.rcNormalPosition)); + GetWindowRect(hwnd, &rect); + ok(EqualRect(&rect, &orig), "got window rect %s\n", wine_dbgstr_rect(&rect)); + DestroyWindow(hwnd); }
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index b45b74c..3ccd939 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1688,6 +1688,14 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS *pWinpos, RECT *old_window_rect, REC } if (!(pWinpos->flags & SWP_NOMOVE)) { + /* If the window is toplevel minimized off-screen, force keep it there */ + if ((wndPtr->dwStyle & WS_MINIMIZE) && + wndPtr->window_rect.left <= -32000 && wndPtr->window_rect.top <= -32000 && + (!wndPtr->parent || wndPtr->parent == GetDesktopWindow())) + { + pWinpos->x = -32000; + pWinpos->y = -32000; + } new_window_rect->left = pWinpos->x; new_window_rect->top = pWinpos->y; new_window_rect->right += pWinpos->x - old_window_rect->left;
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=77578
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:3889: Test failed: hwnd 000200E4/001502E0 message 0737 win.c:3894: Test failed: hwnd 001502E0/001502E0 message 0202 win.c:3899: Test failed: hwnd 001502E0/001502E0 message 0203 win.c:3903: Test failed: message 0202 available
=== w1064v1809_2scr (32 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000302AC 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() = 000302AC win.c:3192: Test failed: GetFocus() = 00000000 win.c:3195: Test failed: GetFocus() = 00000000 win.c:3889: Test failed: hwnd 0006001C/000C01A2 message 0737 win.c:3894: Test failed: hwnd 000C01A2/000C01A2 message 0202 win.c:3899: Test failed: hwnd 000C01A2/000C01A2 message 0203 win.c:3903: Test failed: message 0202 available win.c:9974: Test failed: pos = 00e700d0 win.c:9978: Test failed: pos = 00e700d0 win.c:9982: Test failed: pos = 00e700d0
=== w1064v1809_he (32 bit report) ===
user32: win.c:9478: Test failed: Timed out waiting for the child process
=== w1064v1809_ja (32 bit report) ===
user32: win.c:3724: Test failed: message 0738 available win.c:3849: Test failed: hwnd 000202FE message 7fff win.c:3928: Test failed: hwnd 000202FE/001501DA message 7fff win.c:3931: Test failed: hwnd 000202FE/001501DA message 7fff
=== w1064v1809_zh_CN (32 bit report) ===
user32: win.c:3849: Test failed: hwnd 00030198 message 0282 win.c:3928: Test failed: hwnd 00030198/000D03DC message 0282 win.c:3931: Test failed: hwnd 00030198/000D03DC message 0282
=== w1064v1809 (64 bit report) ===
user32: win.c:3164: Test failed: GetActiveWindow() = 000000000005006A 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() = 000000000005006A win.c:3192: Test failed: GetFocus() = 0000000000000000 win.c:3195: Test failed: GetFocus() = 0000000000000000 win.c:3889: Test failed: hwnd 00000000000200E4/00000000000602CC message 0737 win.c:3894: Test failed: hwnd 00000000000602CC/00000000000602CC message 0202 win.c:3899: Test failed: hwnd 00000000000602CC/00000000000602CC message 0203 win.c:3903: Test failed: message 0202 available
=== debiant (32 bit report) ===
user32: monitor: Timeout
=== debiant (32 bit Chinese:China report) ===
user32: monitor: Timeout
=== debiant (32 bit WoW report) ===
user32: monitor: Timeout
=== debiant (64 bit WoW report) ===
user32: clipboard.c:1501: Test failed: gle 5 clipboard.c:1549: Test failed: wrong data 00000000 clipboard.c:1552: Test failed: wrong data 00000000, cf 0000c040 clipboard.c:1555: Test failed: wrong data 00000000 clipboard.c:1558: Test failed: wrong data 00000000 clipboard.c:1561: Test failed: wrong data 00000000 clipboard.c:1564: Test failed: wrong data 00000000 clipboard.c:1567: Test failed: wrong data 00000000 clipboard.c:1570: Test failed: wrong data 00000000 clipboard.c:1574: Test failed: expected fixed mem 00000000 clipboard.c:1576: Test failed: expected fixed mem 00000000 clipboard.c:1578: Test failed: expected fixed mem 00000000 clipboard.c:1580: Test failed: expected bitmap 00000000 clipboard.c:1582: Test failed: expected bitmap 00000000 clipboard.c:1584: Test failed: expected palette 00000000 clipboard.c:1586: Test failed: expected fixed mem 00000000 clipboard.c:1588: Test failed: expected fixed mem 00000000 clipboard.c:1597: Test failed: gle 1418 clipboard.c:1600: Test failed: expected freed mem 0020186A clipboard.c:1601: Test failed: expected freed mem 00BF14F2 clipboard.c:1602: Test failed: expected freed mem 00BF152A clipboard.c:1603: Test failed: expected freed mem 00BE9F62 clipboard.c:1604: Test failed: expected freed mem 00BF0AF2 clipboard.c:1609: Test failed: gle 1418 clipboard.c:1799: Test failed: gle 5 clipboard.c:1801: Test failed: gle 1418 clipboard.c:1829: Test failed: gle 1418 clipboard.c:1626: Test failed: gle 5 clipboard.c:1628: Test failed: expected moveable mem 00000000 clipboard.c:1633: Test failed: expected moveable mem 00000000 clipboard.c:1638: Test failed: expected moveable mem 00000000 clipboard.c:1644: Test failed: expected moveable mem 00000000 clipboard.c:1650: Test failed: expected bitmap 00000000 clipboard.c:1651: Test failed: different bitmap 00000000 / 000F0043 clipboard.c:1654: Test failed: expected bitmap 00000000 clipboard.c:1655: Test failed: different bitmap 00000000 / 00020044 clipboard.c:1658: Test failed: expected palette 00000000 clipboard.c:1659: Test failed: different palette 00000000 / 00010046 clipboard.c:1662: Test failed: expected fixed mem 00000000 clipboard.c:1664: Test failed: expected fixed mem 00000000 clipboard.c:1666: Test failed: gle 1418 monitor: Timeout
Hi Gabriel,
The patch seems okay to me. It would be better if you put the tests in a separate patch.
Thanks, Zhiyi
On 8/25/20 11:05 PM, Gabriel Ivăncescu wrote:
Some applications (e.g. Lego Worlds) use (-32000,-32000) to determine whether a window is minimized.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/user32/tests/win.c | 52 +++++++++++++++++++++++++++++++++++++++++ dlls/user32/winpos.c | 8 +++++++ 2 files changed, 60 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 843da89..19a0db2 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -11593,6 +11593,58 @@ todo_wine ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n", wine_dbgstr_rect(&wp.rcNormalPosition));
- wp.flags = WPF_SETMINPOSITION;
- wp.showCmd = SW_NORMAL;
- wp.ptMinPosition.x = wp.ptMinPosition.y = 100;
- wp.ptMaxPosition.x = wp.ptMaxPosition.y = 100;
- wp.rcNormalPosition = orig;
- ret = SetWindowPlacement(hwnd, &wp);
- ok(ret, "failed to set window placement, error %u\n", GetLastError());
- ShowWindow(hwnd, SW_MINIMIZE);
- ret = GetWindowPlacement(hwnd, &wp);
- ok(ret, "failed to get window placement, error %u\n", GetLastError());
- ok(wp.showCmd == SW_SHOWMINIMIZED, "got show cmd %u\n", wp.showCmd);
- ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000,
"got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
+todo_wine
- ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
"got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
- ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n",
wine_dbgstr_rect(&wp.rcNormalPosition));
- ret = SetWindowPos(hwnd, NULL, 100, 100, 151, 151, SWP_NOACTIVATE | SWP_NOZORDER);
- ok(ret, "failed to set window pos, error %u\n", GetLastError());
- ret = GetWindowPlacement(hwnd, &wp);
- ok(ret, "failed to get window placement, error %u\n", GetLastError());
- ok(wp.showCmd == SW_SHOWMINIMIZED, "got show cmd %u\n", wp.showCmd);
- ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000,
"got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
+todo_wine
- ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
"got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
- ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n",
wine_dbgstr_rect(&wp.rcNormalPosition));
- GetWindowRect(hwnd, &rect);
- ok(rect.left == -32000 && rect.top == -32000, "got window rect %s\n", wine_dbgstr_rect(&rect));
- ShowWindow(hwnd, SW_SHOWNORMAL);
- ret = GetWindowPlacement(hwnd, &wp);
- ok(ret, "failed to get window placement, error %u\n", GetLastError());
- ok(wp.showCmd == SW_NORMAL, "got show cmd %u\n", wp.showCmd);
- ok(wp.ptMinPosition.x == -32000 && wp.ptMinPosition.y == -32000,
"got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
+todo_wine
- ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
"got maximized pos (%d,%d)\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
- ok(EqualRect(&wp.rcNormalPosition, &orig), "got normal pos %s\n",
wine_dbgstr_rect(&wp.rcNormalPosition));
- GetWindowRect(hwnd, &rect);
- ok(EqualRect(&rect, &orig), "got window rect %s\n", wine_dbgstr_rect(&rect));
- DestroyWindow(hwnd);
}
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index b45b74c..3ccd939 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1688,6 +1688,14 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS *pWinpos, RECT *old_window_rect, REC } if (!(pWinpos->flags & SWP_NOMOVE)) {
/* If the window is toplevel minimized off-screen, force keep it there */
if ((wndPtr->dwStyle & WS_MINIMIZE) &&
wndPtr->window_rect.left <= -32000 && wndPtr->window_rect.top <= -32000 &&
(!wndPtr->parent || wndPtr->parent == GetDesktopWindow()))
{
pWinpos->x = -32000;
pWinpos->y = -32000;
} new_window_rect->left = pWinpos->x; new_window_rect->top = pWinpos->y; new_window_rect->right += pWinpos->x - old_window_rect->left;
On 04/02/2021 17:26, Zhiyi Zhang wrote:
Hi Gabriel,
The patch seems okay to me. It would be better if you put the tests in a separate patch.
Thanks, Zhiyi
Good point, should make it more clear what the patch fixes. I'll send a v2.