From b7a4aade29f2ccbe984afdc3a55baedb9a0ffdf1 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 20 Dec 2018 12:40:39 -0600 Subject: [PATCH] user32-minimized_windows: Add patch set. --- patches/patchinstall.sh | 51 ++- ...-tests-for-GetWindowPlacement-and-Se.patch | 224 +++++++++++ ...Pos-shouldn-t-change-the-client-rect.patch | 51 +++ ...-calculate-the-client-size-of-a-mini.patch | 115 ++++++ ...-XY-MINIMIZED-rather-than-C-XY-ICON-.patch | 96 +++++ ...dowRect-shouldn-t-ignore-WS_MINIMIZE.patch | 50 +++ ...-tests-for-maximizing-and-minimizing.patch | 157 ++++++++ ...-tests-for-maximizing-and-minimizing.patch | 163 ++++++++ ...-tests-for-maximizing-and-minimizing.patch | 159 ++++++++ ...s-Add-tests-for-ArrangeIconicWindows.patch | 192 +++++++++ ...nt-ArrangeIconicWindows-using-minimi.patch | 227 +++++++++++ ...32-Correctly-place-minimized-windows.patch | 380 ++++++++++++++++++ ...int-title-bars-for-minimized-windows.patch | 86 ++++ ...cking-the-restore-and-maximize-boxes.patch | 43 ++ .../0014-user32-Get-rid-of-icon-titles.patch | 257 ++++++++++++ ...ic-windows-as-their-border-instead-o.patch | 119 ++++++ patches/user32-minimized_windows/definition | 2 + 17 files changed, 2371 insertions(+), 1 deletion(-) create mode 100644 patches/user32-minimized_windows/0001-user32-tests-Add-tests-for-GetWindowPlacement-and-Se.patch create mode 100644 patches/user32-minimized_windows/0002-user32-SetWindowPos-shouldn-t-change-the-client-rect.patch create mode 100644 patches/user32-minimized_windows/0003-user32-Correctly-calculate-the-client-size-of-a-mini.patch create mode 100644 patches/user32-minimized_windows/0004-user32-Use-the-C-XY-MINIMIZED-rather-than-C-XY-ICON-.patch create mode 100644 patches/user32-minimized_windows/0005-user32-AdjustWindowRect-shouldn-t-ignore-WS_MINIMIZE.patch create mode 100644 patches/user32-minimized_windows/0006-user32-tests-Add-tests-for-maximizing-and-minimizing.patch create mode 100644 patches/user32-minimized_windows/0007-user32-tests-Add-tests-for-maximizing-and-minimizing.patch create mode 100644 patches/user32-minimized_windows/0008-user32-tests-Add-tests-for-maximizing-and-minimizing.patch create mode 100644 patches/user32-minimized_windows/0009-user32-tests-Add-tests-for-ArrangeIconicWindows.patch create mode 100644 patches/user32-minimized_windows/0010-user32-Reimplement-ArrangeIconicWindows-using-minimi.patch create mode 100644 patches/user32-minimized_windows/0011-user32-Correctly-place-minimized-windows.patch create mode 100644 patches/user32-minimized_windows/0012-user32-Paint-title-bars-for-minimized-windows.patch create mode 100644 patches/user32-minimized_windows/0013-user32-Allow-clicking-the-restore-and-maximize-boxes.patch create mode 100644 patches/user32-minimized_windows/0014-user32-Get-rid-of-icon-titles.patch create mode 100644 patches/user32-minimized_windows/0015-user32-Move-iconic-windows-as-their-border-instead-o.patch create mode 100644 patches/user32-minimized_windows/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 74ba2187..0ce3388f 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,7 +52,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "5a8e430b96ab429a85f82f26ba9d2de4729954c2" + echo "3d5036e31769b0400d6cea08460e7fdb1cbf3556" } # Show version information @@ -317,6 +317,7 @@ patch_enable_all () enable_user32_Refresh_MDI_Menus="$1" enable_user32_ScrollWindowEx="$1" enable_user32_ShowWindow="$1" + enable_user32_minimized_windows="$1" enable_user32_msgbox_Support_WM_COPY_mesg="$1" enable_uxtheme_CloseThemeClass="$1" enable_uxtheme_GTK_Theming="$1" @@ -1110,6 +1111,9 @@ patch_enable () user32-ShowWindow) enable_user32_ShowWindow="$2" ;; + user32-minimized_windows) + enable_user32_minimized_windows="$2" + ;; user32-msgbox-Support-WM_COPY-mesg) enable_user32_msgbox_Support_WM_COPY_mesg="$2" ;; @@ -6516,6 +6520,51 @@ if test "$enable_user32_ShowWindow" -eq 1; then ) >> "$patchlist" fi +# Patchset user32-minimized_windows +# | +# | This patchset fixes the following Wine bugs: +# | * [#7287] Redundant "tabs" appear with tabbed MDI (test with LTSpice) +# | +# | Modified files: +# | * dlls/user32/controls.h, dlls/user32/icontitle.c, dlls/user32/nonclient.c, dlls/user32/tests/win.c, dlls/user32/win.c, +# | dlls/user32/win.h, dlls/user32/winpos.c, dlls/wineandroid.drv/window.c, dlls/wineandroid.drv/wineandroid.drv.spec, +# | dlls/winemac.drv/window.c, dlls/winex11.drv/window.c +# | +if test "$enable_user32_minimized_windows" -eq 1; then + patch_apply user32-minimized_windows/0001-user32-tests-Add-tests-for-GetWindowPlacement-and-Se.patch + patch_apply user32-minimized_windows/0002-user32-SetWindowPos-shouldn-t-change-the-client-rect.patch + patch_apply user32-minimized_windows/0003-user32-Correctly-calculate-the-client-size-of-a-mini.patch + patch_apply user32-minimized_windows/0004-user32-Use-the-C-XY-MINIMIZED-rather-than-C-XY-ICON-.patch + patch_apply user32-minimized_windows/0005-user32-AdjustWindowRect-shouldn-t-ignore-WS_MINIMIZE.patch + patch_apply user32-minimized_windows/0006-user32-tests-Add-tests-for-maximizing-and-minimizing.patch + patch_apply user32-minimized_windows/0007-user32-tests-Add-tests-for-maximizing-and-minimizing.patch + patch_apply user32-minimized_windows/0008-user32-tests-Add-tests-for-maximizing-and-minimizing.patch + patch_apply user32-minimized_windows/0009-user32-tests-Add-tests-for-ArrangeIconicWindows.patch + patch_apply user32-minimized_windows/0010-user32-Reimplement-ArrangeIconicWindows-using-minimi.patch + patch_apply user32-minimized_windows/0011-user32-Correctly-place-minimized-windows.patch + patch_apply user32-minimized_windows/0012-user32-Paint-title-bars-for-minimized-windows.patch + patch_apply user32-minimized_windows/0013-user32-Allow-clicking-the-restore-and-maximize-boxes.patch + patch_apply user32-minimized_windows/0014-user32-Get-rid-of-icon-titles.patch + patch_apply user32-minimized_windows/0015-user32-Move-iconic-windows-as-their-border-instead-o.patch + ( + printf '%s\n' '+ { "Zebediah Figura", "user32/tests: Add tests for GetWindowPlacement() and SetWindowPlacement().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: SetWindowPos() shouldn'\''t change the client rect of a minimized window.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Correctly calculate the client size of a minimized window.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Use the C[XY]MINIMIZED rather than C[XY]ICON size for minimized windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: AdjustWindowRect() shouldn'\''t ignore WS_MINIMIZE.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32/tests: Add tests for maximizing and minimizing owned windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32/tests: Add tests for maximizing and minimizing child windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32/tests: Add tests for maximizing and minimizing MDI child windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32/tests: Add tests for ArrangeIconicWindows().", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Reimplement ArrangeIconicWindows() using minimized metrics.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Correctly place minimized windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Paint title bars for minimized windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Allow clicking the restore and maximize boxes for on minimized windows.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Get rid of icon titles.", 1 },'; + printf '%s\n' '+ { "Zebediah Figura", "user32: Move iconic windows as their border instead of their icon.", 1 },'; + ) >> "$patchlist" +fi + # Patchset user32-msgbox-Support-WM_COPY-mesg # | # | This patchset fixes the following Wine bugs: diff --git a/patches/user32-minimized_windows/0001-user32-tests-Add-tests-for-GetWindowPlacement-and-Se.patch b/patches/user32-minimized_windows/0001-user32-tests-Add-tests-for-GetWindowPlacement-and-Se.patch new file mode 100644 index 00000000..5a7e9f83 --- /dev/null +++ b/patches/user32-minimized_windows/0001-user32-tests-Add-tests-for-GetWindowPlacement-and-Se.patch @@ -0,0 +1,224 @@ +From b80ed82abdd82dcf8fe40c7618db978ebb094ecc Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 19 Dec 2018 10:31:22 -0600 +Subject: [PATCH 01/15] user32/tests: Add tests for GetWindowPlacement() and + SetWindowPlacement(). + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 192 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 192 insertions(+) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 94eff5ee4f..85b2b3a514 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -10721,6 +10721,197 @@ static void test_IsWindowEnabled(void) + DestroyWindow(hwnd); + } + ++static void test_window_placement(void) ++{ ++ RECT orig = {100, 200, 300, 400}, orig2 = {200, 300, 400, 500}, rect; ++ WINDOWPLACEMENT wp = {sizeof(wp)}; ++ HWND hwnd; ++ BOOL ret; ++ ++ hwnd = CreateWindowA("MainWindowClass", "wp", WS_OVERLAPPEDWINDOW, ++ orig.left, orig.top, orig.right - orig.left, orig.bottom - orig.top, 0, 0, 0, 0); ++ ok(!!hwnd, "failed to create window, error %u\n", GetLastError()); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWNORMAL, "got show cmd %u\n", wp.showCmd); ++ ok(wp.ptMinPosition.x == -1 && wp.ptMinPosition.y == -1, ++ "got minimized pos (%d,%d)\n", wp.ptMinPosition.x, wp.ptMinPosition.y); ++ 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)); ++ ++ ShowWindow(hwnd, SW_MINIMIZE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(!wp.flags, "got flags %#x\n", wp.flags); ++ 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); ++ 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)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWNORMAL, "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); ++ 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)); ++ ++ ShowWindow(hwnd, SW_MAXIMIZE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWMAXIMIZED, "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)); ++ ++ SetWindowPos(hwnd, 0, 100, 100, 100, 100, SWP_NOZORDER | SWP_NOACTIVATE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWMAXIMIZED, "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); ++ ok(wp.ptMaxPosition.x == 100 && wp.ptMaxPosition.y == 100, ++ "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)); ++ ++ ShowWindow(hwnd, SW_MINIMIZE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.flags == WPF_RESTORETOMAXIMIZED, "got flags %#x\n", wp.flags); ++ 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)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWMAXIMIZED, "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)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWNORMAL, "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)); ++ ++ wp.flags = WPF_SETMINPOSITION; ++ wp.ptMinPosition.x = wp.ptMinPosition.y = 100; ++ wp.ptMaxPosition.x = wp.ptMaxPosition.y = 100; ++ wp.rcNormalPosition = orig2; ++ ret = SetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to set window placement, error %u\n", GetLastError()); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWNORMAL, "got show cmd %u\n", wp.showCmd); ++ ok(wp.ptMinPosition.x == 100 && wp.ptMinPosition.y == 100, ++ "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, &orig2), "got normal pos %s\n", ++ wine_dbgstr_rect(&wp.rcNormalPosition)); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&rect, &orig2), "got window rect %s\n", wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_MINIMIZE); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(!wp.flags, "got flags %#x\n", wp.flags); ++ 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, &orig2), "got normal pos %s\n", ++ wine_dbgstr_rect(&wp.rcNormalPosition)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ++ wp.flags = WPF_SETMINPOSITION; ++ wp.showCmd = SW_MINIMIZE; ++ 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()); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(!wp.flags, "got flags %#x\n", wp.flags); ++ 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)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ++ wp.flags = WPF_SETMINPOSITION; ++ wp.showCmd = SW_MAXIMIZE; ++ 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()); ++ ++ ret = GetWindowPlacement(hwnd, &wp); ++ ok(ret, "failed to get window placement, error %u\n", GetLastError()); ++ ok(wp.showCmd == SW_SHOWMAXIMIZED, "got show cmd %u\n", wp.showCmd); ++ ok(wp.ptMinPosition.x == 100 && wp.ptMinPosition.y == 100, ++ "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)); ++ ++ DestroyWindow(hwnd); ++} ++ + START_TEST(win) + { + char **argv; +@@ -10878,6 +11069,7 @@ START_TEST(win) + test_minimize_window(hwndMain); + test_destroy_quit(); + test_IsWindowEnabled(); ++ test_window_placement(); + + /* add the tests above this line */ + if (hhook) UnhookWindowsHookEx(hhook); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0002-user32-SetWindowPos-shouldn-t-change-the-client-rect.patch b/patches/user32-minimized_windows/0002-user32-SetWindowPos-shouldn-t-change-the-client-rect.patch new file mode 100644 index 00000000..3c58d734 --- /dev/null +++ b/patches/user32-minimized_windows/0002-user32-SetWindowPos-shouldn-t-change-the-client-rect.patch @@ -0,0 +1,51 @@ +From dfa57f43321be68d80204bcc960e62b1f341b5ad Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 23:51:26 -0600 +Subject: [PATCH 02/15] user32: SetWindowPos() shouldn't change the client rect + of a minimized window. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 12 ++++++++++++ + dlls/user32/winpos.c | 2 +- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 85b2b3a514..5f34b11e4b 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6503,6 +6503,18 @@ static void test_ShowWindow(void) + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); + todo_wine ++ ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", ++ wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); ++ /* SetWindowPos shouldn't affect the client rect */ ++ ret = SetWindowPos(hwnd, 0, 0, 0, 0, 0, ++ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "not expected ret: %lu\n", ret); ++ GetWindowRect(hwnd, &rc); ++ todo_wine ++ ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", ++ wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); ++ GetClientRect(hwnd, &rc); ++ todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index 4b39d0aa39..38444b243f 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -1699,7 +1699,7 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS *pWinpos, RECT *old_window_rect, REC + + WIN_GetRectangles( pWinpos->hwnd, COORDS_PARENT, old_window_rect, old_client_rect ); + *new_window_rect = *old_window_rect; +- *new_client_rect = (wndPtr->dwStyle & WS_MINIMIZE) ? *old_window_rect : *old_client_rect; ++ *new_client_rect = *old_client_rect; + + if (!(pWinpos->flags & SWP_NOSIZE)) + { +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0003-user32-Correctly-calculate-the-client-size-of-a-mini.patch b/patches/user32-minimized_windows/0003-user32-Correctly-calculate-the-client-size-of-a-mini.patch new file mode 100644 index 00000000..9fbcae70 --- /dev/null +++ b/patches/user32-minimized_windows/0003-user32-Correctly-calculate-the-client-size-of-a-mini.patch @@ -0,0 +1,115 @@ +From f3effe1fc888e89a32c8cad4c7af7e41d09f979a Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 19:49:03 -0600 +Subject: [PATCH 03/15] user32: Correctly calculate the client size of a + minimized window. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/nonclient.c | 5 +++++ + dlls/user32/tests/win.c | 17 ++++++++++------- + 2 files changed, 15 insertions(+), 7 deletions(-) + +diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c +index 4444a2c91e..26bb0a01b5 100644 +--- a/dlls/user32/nonclient.c ++++ b/dlls/user32/nonclient.c +@@ -414,6 +414,11 @@ LRESULT NC_HandleNCCalcSize( HWND hwnd, WPARAM wparam, RECT *winRect ) + if (winRect->left > winRect->right) + winRect->right = winRect->left; + } ++ else ++ { ++ winRect->right = winRect->left; ++ winRect->bottom = winRect->top; ++ } + return result; + } + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 5f34b11e4b..d17288abcc 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6488,7 +6488,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + /* shouldn't be able to resize minimized windows */ +@@ -6502,7 +6501,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + /* SetWindowPos shouldn't affect the client rect */ +@@ -6514,7 +6512,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + +@@ -6606,7 +6603,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + +@@ -6622,7 +6618,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + +@@ -6665,7 +6660,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + DestroyWindow(hwnd); +@@ -6684,7 +6678,6 @@ static void test_ShowWindow(void) + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcEmpty, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcEmpty), wine_dbgstr_rect(&rc)); + DestroyWindow(hwnd); +@@ -9925,6 +9918,7 @@ static void test_hide_window(void) + static void test_minimize_window(HWND hwndMain) + { + HWND hwnd, hwnd2, hwnd3; ++ RECT rc, rc_expect; + + hwnd = CreateWindowExA(0, "MainWindowClass", "Main window", WS_POPUP | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, GetModuleHandleA(NULL), NULL); +@@ -10033,6 +10027,15 @@ static void test_minimize_window(HWND hwndMain) + DestroyWindow(hwnd3); + DestroyWindow(hwnd2); + DestroyWindow(hwnd); ++ ++ /* test NC area */ ++ ShowWindow(hwndMain, SW_MINIMIZE); ++ GetWindowRect(hwndMain, &rc); ++ SetRect(&rc_expect, rc.left, rc.top, rc.left, rc.top); ++ DefWindowProcA(hwndMain, WM_NCCALCSIZE, 0, (LPARAM)&rc); ++ ok(EqualRect(&rc, &rc_expect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&rc_expect), wine_dbgstr_rect(&rc)); ++ ShowWindow(hwndMain, SW_RESTORE); + } + + static void test_desktop( void ) +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0004-user32-Use-the-C-XY-MINIMIZED-rather-than-C-XY-ICON-.patch b/patches/user32-minimized_windows/0004-user32-Use-the-C-XY-MINIMIZED-rather-than-C-XY-ICON-.patch new file mode 100644 index 00000000..68196864 --- /dev/null +++ b/patches/user32-minimized_windows/0004-user32-Use-the-C-XY-MINIMIZED-rather-than-C-XY-ICON-.patch @@ -0,0 +1,96 @@ +From 9e69106979756e7a78e724a6773c557aef83f367 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 17:15:11 -0600 +Subject: [PATCH 04/15] user32: Use the C[XY]MINIMIZED rather than C[XY]ICON + size for minimized windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 5 ----- + dlls/user32/winpos.c | 12 ++++++------ + 2 files changed, 6 insertions(+), 11 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index d17288abcc..d8cbc3b010 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6484,7 +6484,6 @@ static void test_ShowWindow(void) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6497,7 +6496,6 @@ static void test_ShowWindow(void) + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "not expected ret: %lu\n", ret); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6599,7 +6597,6 @@ static void test_ShowWindow(void) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6614,7 +6611,6 @@ static void test_ShowWindow(void) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6656,7 +6652,6 @@ static void test_ShowWindow(void) + style = GetWindowLongA(hwnd, GWL_STYLE); + ok(style & WS_MINIMIZE, "window should be minimized\n"); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index 38444b243f..bca50ca12a 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -975,8 +975,8 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition ); + + SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, +- wpl.ptMinPosition.x + GetSystemMetrics(SM_CXICON), +- wpl.ptMinPosition.y + GetSystemMetrics(SM_CYICON) ); ++ wpl.ptMinPosition.x + GetSystemMetrics(SM_CXMINIMIZED), ++ wpl.ptMinPosition.y + GetSystemMetrics(SM_CYMINIMIZED) ); + return SWP_NOSIZE | SWP_NOMOVE; + } + if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE; +@@ -1006,8 +1006,8 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + + if (!(old_style & WS_MINIMIZE)) swpFlags |= SWP_STATECHANGED; + SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, +- wpl.ptMinPosition.x + GetSystemMetrics(SM_CXICON), +- wpl.ptMinPosition.y + GetSystemMetrics(SM_CYICON) ); ++ wpl.ptMinPosition.x + GetSystemMetrics(SM_CXMINIMIZED), ++ wpl.ptMinPosition.y + GetSystemMetrics(SM_CYMINIMIZED) ); + swpFlags |= SWP_NOCOPYBITS; + break; + +@@ -1705,8 +1705,8 @@ static BOOL SWP_DoWinPosChanging( WINDOWPOS *pWinpos, RECT *old_window_rect, REC + { + if (wndPtr->dwStyle & WS_MINIMIZE) + { +- new_window_rect->right = new_window_rect->left + GetSystemMetrics(SM_CXICON); +- new_window_rect->bottom = new_window_rect->top + GetSystemMetrics(SM_CYICON); ++ new_window_rect->right = new_window_rect->left + GetSystemMetrics(SM_CXMINIMIZED); ++ new_window_rect->bottom = new_window_rect->top + GetSystemMetrics(SM_CYMINIMIZED); + } + else + { +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0005-user32-AdjustWindowRect-shouldn-t-ignore-WS_MINIMIZE.patch b/patches/user32-minimized_windows/0005-user32-AdjustWindowRect-shouldn-t-ignore-WS_MINIMIZE.patch new file mode 100644 index 00000000..a16cce37 --- /dev/null +++ b/patches/user32-minimized_windows/0005-user32-AdjustWindowRect-shouldn-t-ignore-WS_MINIMIZE.patch @@ -0,0 +1,50 @@ +From 823215d44e7b0e670aee7a6719fb4a99f1a5bcdf Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 18:06:19 -0600 +Subject: [PATCH 05/15] user32: AdjustWindowRect() shouldn't ignore + WS_MINIMIZE. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/nonclient.c | 4 ---- + dlls/user32/tests/win.c | 2 +- + 2 files changed, 1 insertion(+), 5 deletions(-) + +diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c +index 26bb0a01b5..0dea3a2376 100644 +--- a/dlls/user32/nonclient.c ++++ b/dlls/user32/nonclient.c +@@ -315,8 +315,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL + { + NONCLIENTMETRICSW ncm; + +- if (style & WS_MINIMIZE) return TRUE; +- + TRACE("(%s) %08x %d %08x\n", wine_dbgstr_rect(rect), style, menu, exStyle ); + + ncm.cbSize = sizeof(ncm); +@@ -335,8 +333,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH AdjustWindowRectExForDpi( LPRECT rect, DWORD style + { + NONCLIENTMETRICSW ncm; + +- if (style & WS_MINIMIZE) return TRUE; +- + TRACE("(%s) %08x %d %08x %u\n", wine_dbgstr_rect(rect), style, menu, exStyle, dpi ); + + ncm.cbSize = sizeof(ncm); +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index d8cbc3b010..2687702ed8 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -5297,7 +5297,7 @@ static void test_AWR_window_size(BOOL menu) + + static void test_AWR_flags(void) + { +- static const DWORD styles[] = { WS_POPUP, WS_BORDER, WS_DLGFRAME, WS_THICKFRAME }; ++ static const DWORD styles[] = { WS_POPUP, WS_BORDER, WS_DLGFRAME, WS_THICKFRAME, WS_MINIMIZE }; + static const DWORD exStyles[] = { WS_EX_CLIENTEDGE, WS_EX_TOOLWINDOW, WS_EX_WINDOWEDGE, + WS_EX_APPWINDOW, WS_EX_DLGMODALFRAME, WS_EX_STATICEDGE }; + +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0006-user32-tests-Add-tests-for-maximizing-and-minimizing.patch b/patches/user32-minimized_windows/0006-user32-tests-Add-tests-for-maximizing-and-minimizing.patch new file mode 100644 index 00000000..5218c349 --- /dev/null +++ b/patches/user32-minimized_windows/0006-user32-tests-Add-tests-for-maximizing-and-minimizing.patch @@ -0,0 +1,157 @@ +From a2b9a0b19756843a345ed1cd0a9021f438bf2a3c Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 14:24:50 -0600 +Subject: [PATCH 06/15] user32/tests: Add tests for maximizing and minimizing + owned windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 125 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 125 insertions(+) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 2687702ed8..f40f4057a1 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6680,6 +6680,130 @@ static void test_ShowWindow(void) + flush_events(TRUE); + } + ++static void test_ShowWindow_owned(HWND hwndMain) ++{ ++ MONITORINFO mon_info = {sizeof(mon_info)}; ++ RECT rect, orig, expect; ++ BOOL ret; ++ HWND hwnd, hwnd2; ++ LONG style; ++ ++ GetMonitorInfoW(MonitorFromWindow(hwndMain, MONITOR_DEFAULTTOPRIMARY), &mon_info); ++ SetRect(&orig, 20, 20, 210, 110); ++ hwnd = CreateWindowA("MainWindowClass", "owned", WS_CAPTION | WS_SYSMENU | ++ WS_MINIMIZEBOX | WS_MAXIMIZEBOX, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, hwndMain, 0, 0, NULL); ++ ok(!!hwnd, "failed to create window, error %u\n", GetLastError()); ++ hwnd2 = CreateWindowA("MainWindowClass", "owned2", WS_CAPTION | WS_SYSMENU | ++ WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, hwndMain, 0, 0, NULL); ++ ok(!!hwnd2, "failed to create window, error %u\n", GetLastError()); ++ ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(!(style & WS_VISIBLE), "window should not be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ret = ShowWindow(hwnd, SW_SHOW); ++ ok(!ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ret = ShowWindow(hwnd, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ SetRect(&expect, 0, mon_info.rcWork.bottom - GetSystemMetrics(SM_CYMINIMIZED), ++ GetSystemMetrics(SM_CXMINIMIZED), mon_info.rcWork.bottom); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* shouldn't be able to resize minimized windows */ ++ ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ /* multiple minimized owned windows stack next to each other (and eventually ++ * on top of each other) */ ++ OffsetRect(&expect, GetSystemMetrics(SM_CXMINIMIZED), 0); ++ ret = ShowWindow(hwnd2, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd2, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd2, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_MAXIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should be minimized\n"); ++ ok(style & WS_MAXIMIZE, "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ expect = mon_info.rcWork; ++ AdjustWindowRectEx(&expect, GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BORDER, ++ 0, GetWindowLongA(hwnd, GWL_EXSTYLE)); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* maximized windows can be resized */ ++ ret = SetWindowPos(hwnd, 0, 300, 300, 200, 200, SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ SetRect(&expect, 300, 300, 500, 500); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ DestroyWindow(hwnd2); ++ DestroyWindow(hwnd); ++} ++ + static DWORD CALLBACK enablewindow_thread(LPVOID arg) + { + HWND hwnd = arg; +@@ -11054,6 +11178,7 @@ START_TEST(win) + test_SetWindowLong(); + test_set_window_style(); + test_ShowWindow(); ++ test_ShowWindow_owned(hwndMain); + test_EnableWindow(); + test_gettext(); + test_GetUpdateRect(); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0007-user32-tests-Add-tests-for-maximizing-and-minimizing.patch b/patches/user32-minimized_windows/0007-user32-tests-Add-tests-for-maximizing-and-minimizing.patch new file mode 100644 index 00000000..e0aad2c3 --- /dev/null +++ b/patches/user32-minimized_windows/0007-user32-tests-Add-tests-for-maximizing-and-minimizing.patch @@ -0,0 +1,163 @@ +From 703fc352f012c3edd1495937ff3b29bcbeeb90c6 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 23:08:28 -0600 +Subject: [PATCH 07/15] user32/tests: Add tests for maximizing and minimizing + child windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 131 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 131 insertions(+) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index f40f4057a1..9153789d34 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6804,6 +6804,136 @@ static void test_ShowWindow_owned(HWND hwndMain) + DestroyWindow(hwnd); + } + ++static void test_ShowWindow_child(HWND hwndMain) ++{ ++ RECT rect, orig, expect; ++ BOOL ret; ++ HWND hwnd, hwnd2; ++ LONG style; ++ POINT pt = {0}; ++ ++ SetRect(&orig, 20, 20, 210, 110); ++ hwnd = CreateWindowA("MainWindowClass", "child", WS_CAPTION | WS_SYSMENU | ++ WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CHILD, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, hwndMain, 0, 0, NULL); ++ ok(!!hwnd, "failed to create window, error %u\n", GetLastError()); ++ hwnd2 = CreateWindowA("MainWindowClass", "child2", WS_CAPTION | WS_SYSMENU | ++ WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CHILD | WS_VISIBLE, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, hwndMain, 0, 0, NULL); ++ ok(!!hwnd2, "failed to create window, error %u\n", GetLastError()); ++ ++ ClientToScreen(hwndMain, &pt); ++ OffsetRect(&orig, pt.x, pt.y); ++ ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(!(style & WS_VISIBLE), "window should not be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ret = ShowWindow(hwnd, SW_SHOW); ++ ok(!ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ret = ShowWindow(hwnd, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ GetClientRect(hwndMain, &expect); ++ SetRect(&expect, 0, expect.bottom - GetSystemMetrics(SM_CYMINIMIZED), ++ GetSystemMetrics(SM_CXMINIMIZED), expect.bottom); ++ OffsetRect(&expect, pt.x, pt.y); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* shouldn't be able to resize minimized windows */ ++ ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ /* multiple minimized children also stack; here the parent is too small to ++ * fit more than one per row */ ++ OffsetRect(&expect, 0, -GetSystemMetrics(SM_CYMINIMIZED)); ++ ret = ShowWindow(hwnd2, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd2, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd2, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_MAXIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should be minimized\n"); ++ ok(style & WS_MAXIMIZE, "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ GetClientRect(hwndMain, &expect); ++ AdjustWindowRectEx(&expect, GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BORDER, ++ 0, GetWindowLongA(hwnd, GWL_EXSTYLE)); ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* maximized windows can be resized */ ++ ret = SetWindowPos(hwnd, 0, 300, 300, 200, 200, SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ SetRect(&expect, 300, 300, 500, 500); ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ DestroyWindow(hwnd2); ++ DestroyWindow(hwnd); ++} ++ + static DWORD CALLBACK enablewindow_thread(LPVOID arg) + { + HWND hwnd = arg; +@@ -11179,6 +11309,7 @@ START_TEST(win) + test_set_window_style(); + test_ShowWindow(); + test_ShowWindow_owned(hwndMain); ++ test_ShowWindow_child(hwndMain); + test_EnableWindow(); + test_gettext(); + test_GetUpdateRect(); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0008-user32-tests-Add-tests-for-maximizing-and-minimizing.patch b/patches/user32-minimized_windows/0008-user32-tests-Add-tests-for-maximizing-and-minimizing.patch new file mode 100644 index 00000000..cc1bd907 --- /dev/null +++ b/patches/user32-minimized_windows/0008-user32-tests-Add-tests-for-maximizing-and-minimizing.patch @@ -0,0 +1,159 @@ +From 63f66f2673889555c1483d5d52cae3a639084f43 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Mon, 17 Dec 2018 23:23:27 -0600 +Subject: [PATCH 08/15] user32/tests: Add tests for maximizing and minimizing + MDI child windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 127 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 127 insertions(+) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 9153789d34..0026454838 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6934,6 +6934,132 @@ static void test_ShowWindow_child(HWND hwndMain) + DestroyWindow(hwnd); + } + ++static void test_ShowWindow_mdichild(HWND hwndMain) ++{ ++ RECT rect, orig, expect; ++ BOOL ret; ++ HWND mdiclient, hwnd, hwnd2; ++ LONG style; ++ POINT pt = {0}; ++ CLIENTCREATESTRUCT mdi_client_cs = {0,1}; ++ ++ SetRect(&orig, 20, 20, 210, 110); ++ GetClientRect(hwndMain, &rect); ++ mdiclient = CreateWindowA("mdiclient", "MDI client", WS_CHILD, ++ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, ++ hwndMain, 0, 0, &mdi_client_cs); ++ ok(!!mdiclient, "failed to create window, error %u\n", GetLastError()); ++ hwnd = CreateWindowExA(WS_EX_MDICHILD, "MainWindowClass", "MDI child", ++ WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, mdiclient, 0, 0, NULL); ++ ok(!!hwnd, "failed to create window, error %u\n", GetLastError()); ++ hwnd2 = CreateWindowExA(WS_EX_MDICHILD, "MainWindowClass", "MDI child 2", ++ WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, ++ orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, mdiclient, 0, 0, NULL); ++ ok(!!hwnd2, "failed to create window, error %u\n", GetLastError()); ++ ++ ClientToScreen(hwndMain, &pt); ++ OffsetRect(&orig, pt.x, pt.y); ++ ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should not be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ret = ShowWindow(hwnd, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ GetClientRect(hwndMain, &expect); ++ SetRect(&expect, 0, expect.bottom - GetSystemMetrics(SM_CYMINIMIZED), ++ GetSystemMetrics(SM_CXMINIMIZED), expect.bottom); ++ OffsetRect(&expect, pt.x, pt.y); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* shouldn't be able to resize minimized windows */ ++ ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ /* multiple minimized children also stack; here the parent is too small to ++ * fit more than one per row */ ++ OffsetRect(&expect, 0, -GetSystemMetrics(SM_CYMINIMIZED)); ++ ret = ShowWindow(hwnd2, SW_MINIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd2, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(style & WS_MINIMIZE, "window should be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd2, &rect); ++ todo_wine ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_MAXIMIZE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should be minimized\n"); ++ ok(style & WS_MAXIMIZE, "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ GetClientRect(hwndMain, &expect); ++ AdjustWindowRectEx(&expect, GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BORDER, ++ 0, GetWindowLongA(hwnd, GWL_EXSTYLE)); ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ /* maximized windows can be resized */ ++ ret = SetWindowPos(hwnd, 0, 300, 300, 200, 200, SWP_NOACTIVATE | SWP_NOZORDER); ++ ok(ret, "wrong ret %d\n", ret); ++ GetWindowRect(hwnd, &rect); ++ SetRect(&expect, 300, 300, 500, 500); ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&expect, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ ShowWindow(hwnd, SW_RESTORE); ++ ok(ret, "wrong ret %d\n", ret); ++ style = GetWindowLongA(hwnd, GWL_STYLE); ++ ok(!(style & WS_DISABLED), "window should not be disabled\n"); ++ ok(style & WS_VISIBLE, "window should be visible\n"); ++ ok(!(style & WS_MINIMIZE), "window should not be minimized\n"); ++ ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); ++ GetWindowRect(hwnd, &rect); ++ ok(EqualRect(&orig, &rect), "expected %s, got %s\n", ++ wine_dbgstr_rect(&orig), wine_dbgstr_rect(&rect)); ++ ++ DestroyWindow(hwnd2); ++ DestroyWindow(hwnd); ++ DestroyWindow(mdiclient); ++} ++ + static DWORD CALLBACK enablewindow_thread(LPVOID arg) + { + HWND hwnd = arg; +@@ -11310,6 +11436,7 @@ START_TEST(win) + test_ShowWindow(); + test_ShowWindow_owned(hwndMain); + test_ShowWindow_child(hwndMain); ++ test_ShowWindow_mdichild(hwndMain); + test_EnableWindow(); + test_gettext(); + test_GetUpdateRect(); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0009-user32-tests-Add-tests-for-ArrangeIconicWindows.patch b/patches/user32-minimized_windows/0009-user32-tests-Add-tests-for-ArrangeIconicWindows.patch new file mode 100644 index 00000000..6ae9168a --- /dev/null +++ b/patches/user32-minimized_windows/0009-user32-tests-Add-tests-for-ArrangeIconicWindows.patch @@ -0,0 +1,192 @@ +From 5716e0d868c32fc287d2ae7779521eff7b2f722b Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Tue, 18 Dec 2018 17:53:38 -0600 +Subject: [PATCH 09/15] user32/tests: Add tests for ArrangeIconicWindows(). + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 161 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 161 insertions(+) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 0026454838..a1224557ab 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -11302,6 +11302,166 @@ todo_wine + DestroyWindow(hwnd); + } + ++static void test_arrange_iconic_windows(void) ++{ ++ MINIMIZEDMETRICS mm = {sizeof(mm)}, oldmm = {sizeof(oldmm)}; ++ RECT orig = {100, 200, 300, 400}, rect, expect, parent_rect; ++ POINT pt = {0}; ++ HWND parent, hwnds[10]; ++ UINT ret; ++ int i, row, col; ++ ++ parent = CreateWindowA("MainWindowClass", "parent", WS_OVERLAPPEDWINDOW, ++ 100, 200, 500, 300, NULL, 0, 0, NULL); ++ ok(!!parent, "failed to create window, error %u\n", GetLastError()); ++ ++ GetClientRect(parent, &parent_rect); ++ ClientToScreen(parent, &pt); ++ SystemParametersInfoA(SPI_GETMINIMIZEDMETRICS, sizeof(oldmm), &oldmm, 0); ++ ++ mm.iWidth = 100; ++ mm.iHorzGap = 40; ++ mm.iVertGap = 3; ++ mm.iArrange = ARW_TOPLEFT | ARW_RIGHT; ++ ret = SystemParametersInfoA(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0); ++ ok(ret, "failed to set minimized metrics, error %u\n", GetLastError()); ++ ++ SetLastError(0xdeadbeef); ++ ret = ArrangeIconicWindows(parent); ++todo_wine ++ ok(!ret, "wrong ret %u\n", ret); ++ ok(GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError()); ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ hwnds[i] = CreateWindowA("MainWindowClass", "child", WS_CHILD | ++ WS_OVERLAPPEDWINDOW, orig.left, orig.top, orig.right - orig.left, ++ orig.bottom - orig.top, parent, 0, 0, NULL); ++ ok(!!hwnds[i], "failed to create window %u, error %u\n", i, GetLastError()); ++ } ++ ++ SetLastError(0xdeadbeef); ++ ret = ArrangeIconicWindows(parent); ++todo_wine ++ ok(!ret, "wrong ret %u\n", ret); ++ ok(GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError()); ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ GetWindowRect(hwnds[i], &rect); ++ expect = orig; ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ } ++ ++ ShowWindow(hwnds[0], SW_MINIMIZE); ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ ret = SetWindowPos(hwnds[i], 0, orig.left, orig.top, 0, 0, ++ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); ++ ok(ret, "hwnd %u: failed to move window, error %u\n", i, GetLastError()); ++ } ++ ++ ret = ArrangeIconicWindows(parent); ++todo_wine ++ ok(ret == 1, "wrong ret %u\n", ret); ++ ++ GetWindowRect(hwnds[0], &rect); ++ SetRect(&expect, 0, 0, GetSystemMetrics(SM_CXMINIMIZED), GetSystemMetrics(SM_CYMINIMIZED)); ++ OffsetRect(&expect, mm.iHorzGap, mm.iVertGap); ++ OffsetRect(&expect, pt.x, pt.y); ++todo_wine ++ ok(EqualRect(&rect, &expect), "expected rect %s, got %s\n", ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ for (i = 1; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ GetWindowRect(hwnds[i], &rect); ++ expect = orig; ++ OffsetRect(&expect, pt.x, pt.y); ++ ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ ShowWindow(hwnds[i], SW_MINIMIZE); ++ ret = SetWindowPos(hwnds[i], 0, orig.left, orig.top, 0, 0, ++ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); ++ ok(ret, "hwnd %u: failed to move window, error %u\n", i, GetLastError()); ++ } ++ ++ ret = ArrangeIconicWindows(parent); ++todo_wine ++ ok(ret == 10, "wrong ret %u\n", ret); ++ ++ col = mm.iHorzGap; ++ row = mm.iVertGap; ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ if (col + GetSystemMetrics(SM_CXMINIMIZED) > parent_rect.right - parent_rect.left) ++ { ++ col = mm.iHorzGap; ++ row += GetSystemMetrics(SM_CYMINIMIZED) + mm.iVertGap; ++ } ++ ++ GetWindowRect(hwnds[i], &rect); ++ SetRect(&expect, col, row, col + GetSystemMetrics(SM_CXMINIMIZED), ++ row + GetSystemMetrics(SM_CYMINIMIZED)); ++ OffsetRect(&expect, pt.x, pt.y); ++todo_wine ++ ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ col += GetSystemMetrics(SM_CXMINIMIZED) + mm.iHorzGap; ++ } ++ ++ mm.iArrange = ARW_BOTTOMRIGHT | ARW_UP; ++ mm.iVertGap = 10; ++ ret = SystemParametersInfoA(SPI_SETMINIMIZEDMETRICS, sizeof(mm), &mm, 0); ++ ok(ret, "failed to set minimized metrics, error %u\n", GetLastError()); ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ ret = SetWindowPos(hwnds[i], 0, orig.left, orig.top, 0, 0, ++ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); ++ ok(ret, "hwnd %u: failed to move window, error %u\n", i, GetLastError()); ++ } ++ ++ ret = ArrangeIconicWindows(parent); ++todo_wine ++ ok(ret == 10, "wrong ret %u\n", ret); ++ ++ col = parent_rect.right - mm.iHorzGap; ++ row = parent_rect.bottom - mm.iVertGap; ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ { ++ if (row - GetSystemMetrics(SM_CYMINIMIZED) < parent_rect.top) ++ { ++ row = parent_rect.bottom - mm.iVertGap; ++ col -= GetSystemMetrics(SM_CXMINIMIZED) + mm.iHorzGap; ++ } ++ ++ GetWindowRect(hwnds[i], &rect); ++ SetRect(&expect, col - GetSystemMetrics(SM_CXMINIMIZED), ++ row - GetSystemMetrics(SM_CYMINIMIZED), col, row); ++ OffsetRect(&expect, pt.x, pt.y); ++todo_wine ++ ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, ++ wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); ++ ++ row -= GetSystemMetrics(SM_CYMINIMIZED) + mm.iVertGap; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(hwnds); ++i) ++ DestroyWindow(hwnds[i]); ++ ++ ret = SystemParametersInfoA(SPI_SETMINIMIZEDMETRICS, sizeof(oldmm), &oldmm, 0); ++ ok(ret, "failed to restore minimized metrics, error %u\n", GetLastError()); ++} ++ + START_TEST(win) + { + char **argv; +@@ -11463,6 +11623,7 @@ START_TEST(win) + test_destroy_quit(); + test_IsWindowEnabled(); + test_window_placement(); ++ test_arrange_iconic_windows(); + + /* add the tests above this line */ + if (hhook) UnhookWindowsHookEx(hhook); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0010-user32-Reimplement-ArrangeIconicWindows-using-minimi.patch b/patches/user32-minimized_windows/0010-user32-Reimplement-ArrangeIconicWindows-using-minimi.patch new file mode 100644 index 00000000..167faab8 --- /dev/null +++ b/patches/user32-minimized_windows/0010-user32-Reimplement-ArrangeIconicWindows-using-minimi.patch @@ -0,0 +1,227 @@ +From 2b5b700cf45de221633d1c1c24d61114f219ca2c Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 19 Dec 2018 12:57:36 -0600 +Subject: [PATCH 10/15] user32: Reimplement ArrangeIconicWindows() using + minimized metrics. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 8 ---- + dlls/user32/winpos.c | 103 ++++++++++++++++++++++++++++++---------- + 2 files changed, 77 insertions(+), 34 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index a1224557ab..4ba2d045f0 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -11328,7 +11328,6 @@ static void test_arrange_iconic_windows(void) + + SetLastError(0xdeadbeef); + ret = ArrangeIconicWindows(parent); +-todo_wine + ok(!ret, "wrong ret %u\n", ret); + ok(GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError()); + +@@ -11342,7 +11341,6 @@ todo_wine + + SetLastError(0xdeadbeef); + ret = ArrangeIconicWindows(parent); +-todo_wine + ok(!ret, "wrong ret %u\n", ret); + ok(GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError()); + +@@ -11365,14 +11363,12 @@ todo_wine + } + + ret = ArrangeIconicWindows(parent); +-todo_wine + ok(ret == 1, "wrong ret %u\n", ret); + + GetWindowRect(hwnds[0], &rect); + SetRect(&expect, 0, 0, GetSystemMetrics(SM_CXMINIMIZED), GetSystemMetrics(SM_CYMINIMIZED)); + OffsetRect(&expect, mm.iHorzGap, mm.iVertGap); + OffsetRect(&expect, pt.x, pt.y); +-todo_wine + ok(EqualRect(&rect, &expect), "expected rect %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -11394,7 +11390,6 @@ todo_wine + } + + ret = ArrangeIconicWindows(parent); +-todo_wine + ok(ret == 10, "wrong ret %u\n", ret); + + col = mm.iHorzGap; +@@ -11411,7 +11406,6 @@ todo_wine + SetRect(&expect, col, row, col + GetSystemMetrics(SM_CXMINIMIZED), + row + GetSystemMetrics(SM_CYMINIMIZED)); + OffsetRect(&expect, pt.x, pt.y); +-todo_wine + ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -11431,7 +11425,6 @@ todo_wine + } + + ret = ArrangeIconicWindows(parent); +-todo_wine + ok(ret == 10, "wrong ret %u\n", ret); + + col = parent_rect.right - mm.iHorzGap; +@@ -11448,7 +11441,6 @@ todo_wine + SetRect(&expect, col - GetSystemMetrics(SM_CXMINIMIZED), + row - GetSystemMetrics(SM_CYMINIMIZED), col, row); + OffsetRect(&expect, pt.x, pt.y); +-todo_wine + ok(EqualRect(&rect, &expect), "hwnd %u: expected rect %s, got %s\n", i, + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index bca50ca12a..6d137d75d7 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -852,6 +852,75 @@ MINMAXINFO WINPOS_GetMinMaxInfo( HWND hwnd ) + return MinMax; + } + ++static POINT get_first_minimized_child_pos( const RECT *parent, const MINIMIZEDMETRICS *mm, ++ int width, int height ) ++{ ++ POINT ret; ++ ++ if (mm->iArrange & ARW_STARTRIGHT) ++ ret.x = parent->right - mm->iHorzGap - width; ++ else ++ ret.x = parent->left + mm->iHorzGap; ++ if (mm->iArrange & ARW_STARTTOP) ++ ret.y = parent->top + mm->iVertGap; ++ else ++ ret.y = parent->bottom - mm->iVertGap - height; ++ ++ return ret; ++} ++ ++static void get_next_minimized_child_pos( const RECT *parent, const MINIMIZEDMETRICS *mm, ++ int width, int height, POINT *pos ) ++{ ++ BOOL next; ++ ++ if (mm->iArrange & ARW_UP) /* == ARW_DOWN */ ++ { ++ if (mm->iArrange & ARW_STARTTOP) ++ { ++ pos->y += height + mm->iVertGap; ++ if ((next = pos->y + height > parent->bottom)) ++ pos->y = parent->top + mm->iVertGap; ++ } ++ else ++ { ++ pos->y -= height + mm->iVertGap; ++ if ((next = pos->y < parent->top)) ++ pos->y = parent->bottom - mm->iVertGap - height; ++ } ++ ++ if (next) ++ { ++ if (mm->iArrange & ARW_STARTRIGHT) ++ pos->x -= width + mm->iHorzGap; ++ else ++ pos->x += width + mm->iHorzGap; ++ } ++ } ++ else ++ { ++ if (mm->iArrange & ARW_STARTRIGHT) ++ { ++ pos->x -= width + mm->iHorzGap; ++ if ((next = pos->x < parent->left)) ++ pos->x = parent->right - mm->iHorzGap - width; ++ } ++ else ++ { ++ pos->x += width + mm->iHorzGap; ++ if ((next = pos->x + width > parent->right)) ++ pos->x = parent->left + mm->iHorzGap; ++ } ++ ++ if (next) ++ { ++ if (mm->iArrange & ARW_STARTTOP) ++ pos->y += height + mm->iVertGap; ++ else ++ pos->y -= height + mm->iVertGap; ++ } ++ } ++} + + /*********************************************************************** + * WINPOS_FindIconPos +@@ -2567,14 +2636,16 @@ BOOL WINAPI EndDeferWindowPos( HDWP hdwp ) + */ + UINT WINAPI ArrangeIconicWindows( HWND parent ) + { ++ int width, height, count = 0; + RECT rectParent; + HWND hwndChild; +- INT x, y, xspacing, yspacing; + POINT pt; + MINIMIZEDMETRICS metrics; + + metrics.cbSize = sizeof(metrics); + SystemParametersInfoW( SPI_GETMINIMIZEDMETRICS, sizeof(metrics), &metrics, 0 ); ++ width = GetSystemMetrics( SM_CXMINIMIZED ); ++ height = GetSystemMetrics( SM_CYMINIMIZED ); + + if (parent == GetDesktopWindow()) + { +@@ -2587,41 +2658,21 @@ UINT WINAPI ArrangeIconicWindows( HWND parent ) + } + else GetClientRect( parent, &rectParent ); + +- x = y = 0; +- xspacing = GetSystemMetrics(SM_CXICONSPACING); +- yspacing = GetSystemMetrics(SM_CYICONSPACING); ++ pt = get_first_minimized_child_pos( &rectParent, &metrics, width, height ); + + hwndChild = GetWindow( parent, GW_CHILD ); + while (hwndChild) + { + if( IsIconic( hwndChild ) ) + { +- WINPOS_ShowIconTitle( hwndChild, FALSE ); +- +- if (metrics.iArrange & ARW_STARTRIGHT) +- pt.x = rectParent.right - (x + 1) * xspacing; +- else +- pt.x = rectParent.left + x * xspacing; +- if (metrics.iArrange & ARW_STARTTOP) +- pt.y = rectParent.top + y * yspacing; +- else +- pt.y = rectParent.bottom - (y + 1) * yspacing; +- +- SetWindowPos( hwndChild, 0, pt.x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2, +- pt.y + (yspacing - GetSystemMetrics(SM_CYICON)) / 2, 0, 0, ++ SetWindowPos( hwndChild, 0, pt.x, pt.y, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); +- if( IsWindow(hwndChild) ) +- WINPOS_ShowIconTitle(hwndChild , TRUE ); +- +- if (++x >= (rectParent.right - rectParent.left) / xspacing) +- { +- x = 0; +- y++; +- } ++ get_next_minimized_child_pos( &rectParent, &metrics, width, height, &pt ); ++ count++; + } + hwndChild = GetWindow( hwndChild, GW_HWNDNEXT ); + } +- return yspacing; ++ return count; + } + + +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0011-user32-Correctly-place-minimized-windows.patch b/patches/user32-minimized_windows/0011-user32-Correctly-place-minimized-windows.patch new file mode 100644 index 00000000..f6ad6999 --- /dev/null +++ b/patches/user32-minimized_windows/0011-user32-Correctly-place-minimized-windows.patch @@ -0,0 +1,380 @@ +From e8ef3930a640e5802f83f14b4512878b9a321448 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 20 Dec 2017 23:11:19 -0600 +Subject: [PATCH 11/15] user32: Correctly place minimized windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/tests/win.c | 11 -- + dlls/user32/winpos.c | 128 +++++++++------------- + dlls/wineandroid.drv/window.c | 17 --- + dlls/wineandroid.drv/wineandroid.drv.spec | 1 - + dlls/winemac.drv/window.c | 10 +- + dlls/winex11.drv/window.c | 21 +--- + 6 files changed, 51 insertions(+), 137 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 4ba2d045f0..0f3c2a9798 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -6506,7 +6506,6 @@ static void test_ShowWindow(void) + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "not expected ret: %lu\n", ret); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6669,7 +6668,6 @@ static void test_ShowWindow(void) + style = GetWindowLongA(hwnd, GWL_STYLE); + ok(style & WS_MINIMIZE, "window should be minimized\n"); + GetWindowRect(hwnd, &rc); +- todo_wine + ok(EqualRect(&rcMinimized, &rc), "expected %s, got %s\n", + wine_dbgstr_rect(&rcMinimized), wine_dbgstr_rect(&rc)); + GetClientRect(hwnd, &rc); +@@ -6731,14 +6729,12 @@ static void test_ShowWindow_owned(HWND hwndMain) + GetWindowRect(hwnd, &rect); + SetRect(&expect, 0, mon_info.rcWork.bottom - GetSystemMetrics(SM_CYMINIMIZED), + GetSystemMetrics(SM_CXMINIMIZED), mon_info.rcWork.bottom); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + /* shouldn't be able to resize minimized windows */ + ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "wrong ret %d\n", ret); + GetWindowRect(hwnd, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -6753,7 +6749,6 @@ static void test_ShowWindow_owned(HWND hwndMain) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd2, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -6859,14 +6854,12 @@ static void test_ShowWindow_child(HWND hwndMain) + SetRect(&expect, 0, expect.bottom - GetSystemMetrics(SM_CYMINIMIZED), + GetSystemMetrics(SM_CXMINIMIZED), expect.bottom); + OffsetRect(&expect, pt.x, pt.y); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + /* shouldn't be able to resize minimized windows */ + ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "wrong ret %d\n", ret); + GetWindowRect(hwnd, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -6881,7 +6874,6 @@ static void test_ShowWindow_child(HWND hwndMain) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd2, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -6984,14 +6976,12 @@ static void test_ShowWindow_mdichild(HWND hwndMain) + SetRect(&expect, 0, expect.bottom - GetSystemMetrics(SM_CYMINIMIZED), + GetSystemMetrics(SM_CXMINIMIZED), expect.bottom); + OffsetRect(&expect, pt.x, pt.y); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + /* shouldn't be able to resize minimized windows */ + ret = SetWindowPos(hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + ok(ret, "wrong ret %d\n", ret); + GetWindowRect(hwnd, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +@@ -7006,7 +6996,6 @@ static void test_ShowWindow_mdichild(HWND hwndMain) + ok(style & WS_MINIMIZE, "window should be minimized\n"); + ok(!(style & WS_MAXIMIZE), "window should not be maximized\n"); + GetWindowRect(hwnd2, &rect); +- todo_wine + ok(EqualRect(&expect, &rect), "expected %s, got %s\n", + wine_dbgstr_rect(&expect), wine_dbgstr_rect(&rect)); + +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index 6d137d75d7..4f936f8d30 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -922,95 +922,64 @@ static void get_next_minimized_child_pos( const RECT *parent, const MINIMIZEDMET + } + } + +-/*********************************************************************** +- * WINPOS_FindIconPos +- * +- * Find a suitable place for an iconic window. +- */ +-static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt ) ++/* detect whether another child window has already been minimized here */ ++static BOOL find_minimized_child( HWND hwnd, HWND parent, POINT pt ) + { +- RECT rect, rectParent; +- HWND parent, child; +- HRGN hrgn, tmp; +- int x, y, xspacing, yspacing; +- MINIMIZEDMETRICS metrics; +- +- metrics.cbSize = sizeof(metrics); +- SystemParametersInfoW( SPI_GETMINIMIZEDMETRICS, sizeof(metrics), &metrics, 0 ); +- +- parent = GetAncestor( hwnd, GA_PARENT ); +- if (parent == GetDesktopWindow()) +- { +- MONITORINFO mon_info; +- HMONITOR monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); +- +- mon_info.cbSize = sizeof( mon_info ); +- GetMonitorInfoW( monitor, &mon_info ); +- rectParent = mon_info.rcWork; +- } +- else GetClientRect( parent, &rectParent ); +- +- if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics(SM_CXICON) < rectParent.right) && +- (pt.y >= rectParent.top) && (pt.y + GetSystemMetrics(SM_CYICON) < rectParent.bottom)) +- return pt; /* The icon already has a suitable position */ +- +- xspacing = GetSystemMetrics(SM_CXICONSPACING); +- yspacing = GetSystemMetrics(SM_CYICONSPACING); +- +- /* Check if another icon already occupies this spot */ +- /* FIXME: this is completely inefficient */ ++ HWND child; ++ RECT rect; + +- hrgn = CreateRectRgn( 0, 0, 0, 0 ); +- tmp = CreateRectRgn( 0, 0, 0, 0 ); + for (child = GetWindow( parent, GW_CHILD ); child; child = GetWindow( child, GW_HWNDNEXT )) + { + if (child == hwnd) continue; + if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE)) + continue; +- if (WIN_GetRectangles( child, COORDS_PARENT, &rect, NULL )) ++ if (WIN_GetRectangles( child, COORDS_PARENT, &rect, NULL ) ++ && pt.x >= rect.left && pt.x < rect.right && pt.y >= rect.top && pt.y < rect.bottom) + { +- SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom ); +- CombineRgn( hrgn, hrgn, tmp, RGN_OR ); ++ return TRUE; + } + } +- DeleteObject( tmp ); + +- for (y = 0; y < (rectParent.bottom - rectParent.top) / yspacing; y++) ++ return FALSE; ++} ++ ++static POINT get_minimized_pos( HWND hwnd ) ++{ ++ MINIMIZEDMETRICS metrics; ++ int width, height; ++ HWND parent; ++ RECT rect; ++ POINT pt; ++ ++ if ((parent = GetAncestor( hwnd, GA_PARENT )) && parent != GetDesktopWindow()) + { +- if (metrics.iArrange & ARW_STARTTOP) +- { +- rect.top = rectParent.top + y * yspacing; +- rect.bottom = rect.top + yspacing; +- } +- else +- { +- rect.bottom = rectParent.bottom - y * yspacing; +- rect.top = rect.bottom - yspacing; +- } +- for (x = 0; x < (rectParent.right - rectParent.left) / xspacing; x++) +- { +- if (metrics.iArrange & ARW_STARTRIGHT) +- { +- rect.right = rectParent.right - x * xspacing; +- rect.left = rect.right - xspacing; +- } +- else +- { +- rect.left = rectParent.left + x * xspacing; +- rect.right = rect.left + xspacing; +- } +- if (!RectInRegion( hrgn, &rect )) +- { +- /* No window was found, so it's OK for us */ +- pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2; +- pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2; +- DeleteObject( hrgn ); +- return pt; +- } +- } ++ GetClientRect( parent, &rect ); + } +- DeleteObject( hrgn ); +- pt.x = pt.y = 0; ++ else if (GetWindow( hwnd, GW_OWNER )) ++ { ++ MONITORINFO mon_info; ++ HMONITOR monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY ); ++ ++ mon_info.cbSize = sizeof(mon_info); ++ GetMonitorInfoW( monitor, &mon_info ); ++ rect = mon_info.rcWork; ++ } ++ else ++ { ++ pt.x = pt.y = -32000; ++ return pt; ++ } ++ ++ width = GetSystemMetrics( SM_CXMINIMIZED ); ++ height = GetSystemMetrics( SM_CYMINIMIZED ); ++ ++ metrics.cbSize = sizeof(metrics); ++ SystemParametersInfoW( SPI_GETMINIMIZEDMETRICS, sizeof(metrics), &metrics, 0 ); ++ ++ pt = get_first_minimized_child_pos( &rect, &metrics, width, height ); ++ while (find_minimized_child( hwnd, parent, pt )) ++ get_next_minimized_child_pos( &rect, &metrics, width, height, &pt ); ++ + return pt; + } + +@@ -1041,7 +1010,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + case SW_SHOWMINIMIZED: + case SW_FORCEMINIMIZE: + case SW_MINIMIZE: +- wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition ); ++ wpl.ptMinPosition = get_minimized_pos( hwnd ); + + SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, + wpl.ptMinPosition.x + GetSystemMetrics(SM_CXMINIMIZED), +@@ -1071,7 +1040,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + + old_style = WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE ); + +- wpl.ptMinPosition = WINPOS_FindIconPos( hwnd, wpl.ptMinPosition ); ++ wpl.ptMinPosition = get_minimized_pos( hwnd ); + + if (!(old_style & WS_MINIMIZE)) swpFlags |= SWP_STATECHANGED; + SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y, +@@ -1220,7 +1189,8 @@ static BOOL show_window( HWND hwnd, INT cmd ) + if (!IsWindow( hwnd )) goto done; + } + +- swp = USER_Driver->pShowWindow( hwnd, cmd, &newPos, swp ); ++ if (!IsIconic( hwnd )) ++ swp = USER_Driver->pShowWindow( hwnd, cmd, &newPos, swp ); + + parent = GetAncestor( hwnd, GA_PARENT ); + if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED)) +diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c +index 861b216852..04bdad62b6 100644 +--- a/dlls/wineandroid.drv/window.c ++++ b/dlls/wineandroid.drv/window.c +@@ -1380,23 +1380,6 @@ void CDECL ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flag + } + + +-/*********************************************************************** +- * ANDROID_ShowWindow +- */ +-UINT CDECL ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) +-{ +- if (IsRectEmpty( rect )) return swp; +- if (!IsIconic( hwnd )) return swp; +- /* always hide icons off-screen */ +- if (rect->left != -32000 || rect->top != -32000) +- { +- OffsetRect( rect, -32000 - rect->left, -32000 - rect->top ); +- swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE); +- } +- return swp; +-} +- +- + /***************************************************************** + * ANDROID_SetParent + */ +diff --git a/dlls/wineandroid.drv/wineandroid.drv.spec b/dlls/wineandroid.drv/wineandroid.drv.spec +index 00de23de27..50d7668373 100644 +--- a/dlls/wineandroid.drv/wineandroid.drv.spec ++++ b/dlls/wineandroid.drv/wineandroid.drv.spec +@@ -22,7 +22,6 @@ + @ cdecl SetParent(long long long) ANDROID_SetParent + @ cdecl SetWindowRgn(long long long) ANDROID_SetWindowRgn + @ cdecl SetWindowStyle(ptr long ptr) ANDROID_SetWindowStyle +-@ cdecl ShowWindow(long long ptr long) ANDROID_ShowWindow + @ cdecl UpdateLayeredWindow(long ptr ptr) ANDROID_UpdateLayeredWindow + @ cdecl WindowMessage(long long long long) ANDROID_WindowMessage + @ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) ANDROID_WindowPosChanging +diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c +index 6dbc432a1e..6a13d955f3 100644 +--- a/dlls/winemac.drv/window.c ++++ b/dlls/winemac.drv/window.c +@@ -1794,15 +1794,7 @@ UINT CDECL macdrv_ShowWindow(HWND hwnd, INT cmd, RECT *rect, UINT swp) + + if (!data || !data->cocoa_window) goto done; + if (IsRectEmpty(rect)) goto done; +- if (GetWindowLongW(hwnd, GWL_STYLE) & WS_MINIMIZE) +- { +- if (rect->left != -32000 || rect->top != -32000) +- { +- OffsetRect(rect, -32000 - rect->left, -32000 - rect->top); +- swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE); +- } +- goto done; +- } ++ if (GetWindowLongW(hwnd, GWL_STYLE) & WS_MINIMIZE) goto done; + if (!data->on_screen) goto done; + + /* only fetch the new rectangle if the ShowWindow was a result of an external event */ +diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c +index 1a61b6cf2c..7e08abdfa2 100644 +--- a/dlls/winex11.drv/window.c ++++ b/dlls/winex11.drv/window.c +@@ -2443,17 +2443,6 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags + release_win_data( data ); + } + +-/* check if the window icon should be hidden (i.e. moved off-screen) */ +-static BOOL hide_icon( struct x11drv_win_data *data ) +-{ +- static const WCHAR trayW[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d',0}; +- +- if (data->managed) return TRUE; +- /* hide icons in desktop mode when the taskbar is active */ +- if (root_window == DefaultRootWindow( gdi_display )) return FALSE; +- return IsWindowVisible( FindWindowW( trayW, NULL )); +-} +- + /*********************************************************************** + * ShowWindow (X11DRV.@) + */ +@@ -2469,15 +2458,7 @@ UINT CDECL X11DRV_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ) + + if (!data || !data->whole_window) goto done; + if (IsRectEmpty( rect )) goto done; +- if (style & WS_MINIMIZE) +- { +- if (((rect->left != -32000 || rect->top != -32000)) && hide_icon( data )) +- { +- OffsetRect( rect, -32000 - rect->left, -32000 - rect->top ); +- swp &= ~(SWP_NOMOVE | SWP_NOCLIENTMOVE); +- } +- goto done; +- } ++ if (style & WS_MINIMIZE) goto done; + if (!data->managed || !data->mapped || data->iconic) goto done; + + /* only fetch the new rectangle if the ShowWindow was a result of a window manager event */ +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0012-user32-Paint-title-bars-for-minimized-windows.patch b/patches/user32-minimized_windows/0012-user32-Paint-title-bars-for-minimized-windows.patch new file mode 100644 index 00000000..bd33d7cc --- /dev/null +++ b/patches/user32-minimized_windows/0012-user32-Paint-title-bars-for-minimized-windows.patch @@ -0,0 +1,86 @@ +From 11e03f7ce94b82413b808a30cc4ee10203fc2373 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 19 Dec 2018 14:52:18 -0600 +Subject: [PATCH 12/15] user32: Paint title bars for minimized windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/nonclient.c | 34 ++++++++++------------------------ + 1 file changed, 10 insertions(+), 24 deletions(-) + +diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c +index 0dea3a2376..0e15e954fa 100644 +--- a/dlls/user32/nonclient.c ++++ b/dlls/user32/nonclient.c +@@ -430,8 +430,6 @@ static void NC_GetInsideRect( HWND hwnd, enum coords_relative relative, RECT *re + { + WIN_GetRectangles( hwnd, relative, rect, NULL ); + +- if (style & WS_MINIMIZE) return; +- + /* Remove frame from rectangle */ + if (HAS_THICKFRAME( style, ex_style )) + { +@@ -955,9 +953,6 @@ static void NC_DoNCPaint( HWND hwnd, HRGN clip ) + flags = wndPtr->flags; + WIN_ReleasePtr( wndPtr ); + +- if ( dwStyle & WS_MINIMIZE || +- !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */ +- + active = flags & WIN_NCACTIVATED; + + TRACE("%p %d\n", hwnd, active ); +@@ -1065,10 +1060,7 @@ LRESULT NC_HandleNCPaint( HWND hwnd , HRGN clip) + + if( dwStyle & WS_VISIBLE ) + { +- if( dwStyle & WS_MINIMIZE ) +- WINPOS_RedrawIconTitle( hwnd ); +- else +- NC_DoNCPaint( hwnd, clip ); ++ NC_DoNCPaint( hwnd, clip ); + + if (parent == GetDesktopWindow()) + PostMessageW( parent, WM_PARENTNOTIFY, WM_NCPAINT, (LPARAM)hwnd ); +@@ -1097,10 +1089,7 @@ LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) + */ + if (lParam != -1) + { +- if (IsIconic(hwnd)) +- WINPOS_RedrawIconTitle( hwnd ); +- else +- NC_DoNCPaint( hwnd, (HRGN)1 ); ++ NC_DoNCPaint( hwnd, (HRGN)1 ); + + if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) + PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd ); +@@ -1372,17 +1361,14 @@ LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) + } + + case HTSYSMENU: +- if( style & WS_SYSMENU ) +- { +- if( !(style & WS_MINIMIZE) ) +- { +- HDC hDC = GetWindowDC(hwnd); +- NC_DrawSysButton( hwnd, hDC, TRUE ); +- ReleaseDC( hwnd, hDC ); +- } +- SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam ); +- } +- break; ++ if (style & WS_SYSMENU) ++ { ++ HDC hDC = GetWindowDC( hwnd ); ++ NC_DrawSysButton( hwnd, hDC, TRUE ); ++ ReleaseDC( hwnd, hDC ); ++ SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam ); ++ } ++ break; + + case HTMENU: + SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam ); +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0013-user32-Allow-clicking-the-restore-and-maximize-boxes.patch b/patches/user32-minimized_windows/0013-user32-Allow-clicking-the-restore-and-maximize-boxes.patch new file mode 100644 index 00000000..ce59a6fb --- /dev/null +++ b/patches/user32-minimized_windows/0013-user32-Allow-clicking-the-restore-and-maximize-boxes.patch @@ -0,0 +1,43 @@ +From 0f07118d46c8ade3c2ed5f0fc295941d5cb9a4d7 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 19 Dec 2018 14:58:03 -0600 +Subject: [PATCH 13/15] user32: Allow clicking the restore and maximize boxes + for on minimized windows. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/nonclient.c | 1 - + dlls/user32/winpos.c | 5 ----- + 2 files changed, 6 deletions(-) + +diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c +index 0e15e954fa..372b1be707 100644 +--- a/dlls/user32/nonclient.c ++++ b/dlls/user32/nonclient.c +@@ -473,7 +473,6 @@ LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) + + style = GetWindowLongW( hwnd, GWL_STYLE ); + ex_style = GetWindowLongW( hwnd, GWL_EXSTYLE ); +- if (style & WS_MINIMIZE) return HTCAPTION; + + if (PtInRect( &rcClient, pt )) return HTCLIENT; + +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index 4f936f8d30..656064ebec 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -305,11 +305,6 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) + LONG style = GetWindowLongW( list[i], GWL_STYLE ); + + /* If window is minimized or disabled, return at once */ +- if (style & WS_MINIMIZE) +- { +- *hittest = HTCAPTION; +- break; +- } + if (style & WS_DISABLED) + { + *hittest = HTERROR; +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0014-user32-Get-rid-of-icon-titles.patch b/patches/user32-minimized_windows/0014-user32-Get-rid-of-icon-titles.patch new file mode 100644 index 00000000..9a38abca --- /dev/null +++ b/patches/user32-minimized_windows/0014-user32-Get-rid-of-icon-titles.patch @@ -0,0 +1,257 @@ +From 40e3c499a335c847e2c5587a49116afba72b2aed Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Wed, 19 Dec 2018 15:10:53 -0600 +Subject: [PATCH 14/15] user32: Get rid of icon titles. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/controls.h | 3 -- + dlls/user32/icontitle.c | 26 --------------- + dlls/user32/win.c | 3 -- + dlls/user32/win.h | 2 -- + dlls/user32/winpos.c | 74 ----------------------------------------- + 5 files changed, 108 deletions(-) + +diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h +index 164164506e..d372bafcef 100644 +--- a/dlls/user32/controls.h ++++ b/dlls/user32/controls.h +@@ -155,9 +155,6 @@ extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN; + /* desktop */ + extern BOOL update_wallpaper( const WCHAR *wallpaper, const WCHAR *pattern ) DECLSPEC_HIDDEN; + +-/* icon title */ +-extern HWND ICONTITLE_Create( HWND hwnd ) DECLSPEC_HIDDEN; +- + /* menu controls */ + extern HWND MENU_IsMenuActive(void) DECLSPEC_HIDDEN; + extern UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, +diff --git a/dlls/user32/icontitle.c b/dlls/user32/icontitle.c +index 77e286ebc1..e10717de41 100644 +--- a/dlls/user32/icontitle.c ++++ b/dlls/user32/icontitle.c +@@ -51,32 +51,6 @@ const struct builtin_class_descr ICONTITLE_builtin_class = + 0 /* brush */ + }; + +- +- +-/*********************************************************************** +- * ICONTITLE_Create +- */ +-HWND ICONTITLE_Create( HWND owner ) +-{ +- HWND hWnd; +- HINSTANCE instance = (HINSTANCE)GetWindowLongPtrA( owner, GWLP_HINSTANCE ); +- LONG style = WS_CLIPSIBLINGS; +- +- if (!IsWindowEnabled(owner)) style |= WS_DISABLED; +- if( GetWindowLongA( owner, GWL_STYLE ) & WS_CHILD ) +- hWnd = CreateWindowExA( 0, (LPCSTR)ICONTITLE_CLASS_ATOM, NULL, +- style | WS_CHILD, 0, 0, 1, 1, +- GetParent(owner), 0, instance, NULL ); +- else +- hWnd = CreateWindowExA( 0, (LPCSTR)ICONTITLE_CLASS_ATOM, NULL, +- style, 0, 0, 1, 1, +- owner, 0, instance, NULL ); +- WIN_SetOwner( hWnd, owner ); /* MDI depends on this */ +- SetWindowLongW( hWnd, GWL_STYLE, +- GetWindowLongW( hWnd, GWL_STYLE ) & ~(WS_CAPTION | WS_BORDER) ); +- return hWnd; +-} +- + /*********************************************************************** + * ICONTITLE_SetTitlePos + */ +diff --git a/dlls/user32/win.c b/dlls/user32/win.c +index dd6142d16c..24b2a2ffd5 100644 +--- a/dlls/user32/win.c ++++ b/dlls/user32/win.c +@@ -970,7 +970,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) + WND *wndPtr; + HWND *list; + HMENU menu = 0, sys_menu; +- HWND icon_title; + struct window_surface *surface; + + TRACE("%p\n", hwnd ); +@@ -1018,7 +1017,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) + sys_menu = wndPtr->hSysMenu; + free_dce( wndPtr->dce, hwnd ); + wndPtr->dce = NULL; +- icon_title = wndPtr->icon_title; + HeapFree( GetProcessHeap(), 0, wndPtr->text ); + wndPtr->text = NULL; + HeapFree( GetProcessHeap(), 0, wndPtr->pScroll ); +@@ -1028,7 +1026,6 @@ LRESULT WIN_DestroyWindow( HWND hwnd ) + wndPtr->surface = NULL; + WIN_ReleasePtr( wndPtr ); + +- if (icon_title) DestroyWindow( icon_title ); + if (menu) DestroyMenu( menu ); + if (sys_menu) DestroyMenu( sys_menu ); + if (surface) +diff --git a/dlls/user32/win.h b/dlls/user32/win.h +index f3bdfd38d9..81b08fc95e 100644 +--- a/dlls/user32/win.h ++++ b/dlls/user32/win.h +@@ -49,7 +49,6 @@ typedef struct tagWND + RECT normal_rect; /* Normal window rect saved when maximized/minimized */ + POINT min_pos; /* Position for minimized window */ + POINT max_pos; /* Position for maximized window */ +- HWND icon_title; /* Icon title window */ + LPWSTR text; /* Window text */ + void *pScroll; /* Scroll-bar info */ + DWORD dwStyle; /* Window style (from CreateWindow) */ +@@ -120,7 +119,6 @@ static inline void WIN_ReleasePtr( WND *ptr ) + + extern LRESULT HOOK_CallHooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) DECLSPEC_HIDDEN; + +-extern BOOL WINPOS_RedrawIconTitle( HWND hWnd ) DECLSPEC_HIDDEN; + extern MINMAXINFO WINPOS_GetMinMaxInfo( HWND hwnd ) DECLSPEC_HIDDEN; + extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos) DECLSPEC_HIDDEN; + extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) DECLSPEC_HIDDEN; +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index 656064ebec..a36ee178f6 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -678,67 +678,6 @@ BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, + } + + +-/*********************************************************************** +- * WINPOS_RedrawIconTitle +- */ +-BOOL WINPOS_RedrawIconTitle( HWND hWnd ) +-{ +- HWND icon_title = 0; +- WND *win = WIN_GetPtr( hWnd ); +- +- if (win && win != WND_OTHER_PROCESS && win != WND_DESKTOP) +- { +- icon_title = win->icon_title; +- WIN_ReleasePtr( win ); +- } +- if (!icon_title) return FALSE; +- SendMessageW( icon_title, WM_SHOWWINDOW, TRUE, 0 ); +- InvalidateRect( icon_title, NULL, TRUE ); +- return TRUE; +-} +- +-/*********************************************************************** +- * WINPOS_ShowIconTitle +- */ +-static void WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow ) +-{ +- WND *win = WIN_GetPtr( hwnd ); +- HWND title = 0; +- +- TRACE("%p %i\n", hwnd, (bShow != 0) ); +- +- if (!win || win == WND_OTHER_PROCESS || win == WND_DESKTOP) return; +- if (win->window_rect.left == -32000 || win->window_rect.top == -32000) +- { +- TRACE( "not showing title for hidden icon %p\n", hwnd ); +- bShow = FALSE; +- } +- else title = win->icon_title; +- WIN_ReleasePtr( win ); +- +- if (bShow) +- { +- if (!title) +- { +- title = ICONTITLE_Create( hwnd ); +- if (!(win = WIN_GetPtr( hwnd )) || win == WND_OTHER_PROCESS) +- { +- DestroyWindow( title ); +- return; +- } +- win->icon_title = title; +- WIN_ReleasePtr( win ); +- } +- if (!IsWindowVisible(title)) +- { +- SendMessageW( title, WM_SHOWWINDOW, TRUE, 0 ); +- SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | +- SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW ); +- } +- } +- else if (title) ShowWindow( title, SW_HIDE ); +-} +- + /******************************************************************* + * WINPOS_GetMinMaxInfo + * +@@ -1052,10 +991,7 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + + old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE ); + if (old_style & WS_MINIMIZE) +- { + win_set_flags( hwnd, WIN_RESTORE_MAX, 0 ); +- WINPOS_ShowIconTitle( hwnd, FALSE ); +- } + + if (!(old_style & WS_MAXIMIZE)) swpFlags |= SWP_STATECHANGED; + SetRect( rect, minmax.ptMaxPosition.x, minmax.ptMaxPosition.y, +@@ -1071,7 +1007,6 @@ UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) + old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE ); + if (old_style & WS_MINIMIZE) + { +- WINPOS_ShowIconTitle( hwnd, FALSE ); + if (win_get_flags( hwnd ) & WIN_RESTORE_MAX) + { + /* Restore to maximized position */ +@@ -1202,8 +1137,6 @@ static BOOL show_window( HWND hwnd, INT cmd ) + { + HWND hFocus; + +- WINPOS_ShowIconTitle( hwnd, FALSE ); +- + /* FIXME: This will cause the window to be activated irrespective + * of whether it is owned by the same thread. Has to be done + * asynchronously. +@@ -1223,8 +1156,6 @@ static BOOL show_window( HWND hwnd, INT cmd ) + goto done; + } + +- if (IsIconic(hwnd)) WINPOS_ShowIconTitle( hwnd, TRUE ); +- + if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) goto done; + + if (wndPtr->flags & WIN_NEED_SIZE) +@@ -1477,7 +1408,6 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f + { + if (flags & PLACE_MIN) + { +- WINPOS_ShowIconTitle( hwnd, FALSE ); + SetWindowPos( hwnd, 0, wp.ptMinPosition.x, wp.ptMinPosition.y, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); + } +@@ -1498,8 +1428,6 @@ static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT f + + if (IsIconic( hwnd )) + { +- if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE) WINPOS_ShowIconTitle( hwnd, TRUE ); +- + /* SDK: ...valid only the next time... */ + if( wndpl->flags & WPF_RESTORETOMAXIMIZED ) + win_set_flags( hwnd, WIN_RESTORE_MAX, 0 ); +@@ -2947,7 +2875,6 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + { + hOldCursor = SetCursor(hDragCursor); + ShowCursor( TRUE ); +- WINPOS_ShowIconTitle( hwnd, FALSE ); + } + else if(!DragFullWindows) + draw_moving_frame( parent, hdc, &sizingRect, thickframe ); +@@ -3051,6 +2978,5 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + SendMessageW( hwnd, WM_SYSCOMMAND, + SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y)); + } +- else WINPOS_ShowIconTitle( hwnd, TRUE ); + } + } +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/0015-user32-Move-iconic-windows-as-their-border-instead-o.patch b/patches/user32-minimized_windows/0015-user32-Move-iconic-windows-as-their-border-instead-o.patch new file mode 100644 index 00000000..f1b05a8a --- /dev/null +++ b/patches/user32-minimized_windows/0015-user32-Move-iconic-windows-as-their-border-instead-o.patch @@ -0,0 +1,119 @@ +From a62a7fbe80572fdc7be431766da60273a30f0ec9 Mon Sep 17 00:00:00 2001 +From: Zebediah Figura +Date: Thu, 20 Dec 2018 11:15:58 -0600 +Subject: [PATCH 15/15] user32: Move iconic windows as their border instead of + their icon. + +Signed-off-by: Zebediah Figura +--- + dlls/user32/winpos.c | 50 +++++++++++--------------------------------- + 1 file changed, 12 insertions(+), 38 deletions(-) + +diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c +index a36ee178f6..4640dff906 100644 +--- a/dlls/user32/winpos.c ++++ b/dlls/user32/winpos.c +@@ -2709,12 +2709,10 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + HWND parent; + LONG hittest = (LONG)(wParam & 0x0f); + WPARAM syscommand = wParam & 0xfff0; +- HCURSOR hDragCursor = 0, hOldCursor = 0; + MINMAXINFO minmax; + POINT capturePoint, pt; + LONG style = GetWindowLongW( hwnd, GWL_STYLE ); + BOOL thickframe = HAS_THICKFRAME( style ); +- BOOL iconic = style & WS_MINIMIZE; + BOOL moved = FALSE; + DWORD dwPoint = GetMessagePos (); + BOOL DragFullWindows = TRUE; +@@ -2794,13 +2792,6 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + /* Retrieve a default cache DC (without using the window style) */ + hdc = GetDCEx( parent, 0, DCX_CACHE ); + +- if( iconic ) /* create a cursor for dragging */ +- { +- hDragCursor = (HCURSOR)GetClassLongPtrW( hwnd, GCLP_HICON); +- if( !hDragCursor ) hDragCursor = (HCURSOR)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L); +- if( !hDragCursor ) iconic = FALSE; +- } +- + /* we only allow disabling the full window drag for child windows */ + if (parent) SystemParametersInfoW( SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0 ); + +@@ -2870,20 +2861,14 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + if( !moved ) + { + moved = TRUE; +- +- if( iconic ) /* ok, no system popup tracking */ +- { +- hOldCursor = SetCursor(hDragCursor); +- ShowCursor( TRUE ); +- } +- else if(!DragFullWindows) ++ if (!DragFullWindows) + draw_moving_frame( parent, hdc, &sizingRect, thickframe ); + } + + if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y ); + else + { +- if(!iconic && !DragFullWindows) draw_moving_frame( parent, hdc, &sizingRect, thickframe ); ++ if (!DragFullWindows) draw_moving_frame( parent, hdc, &sizingRect, thickframe ); + if (hittest == HTCAPTION) OffsetRect( &sizingRect, dx, dy ); + if (ON_LEFT_BORDER(hittest)) sizingRect.left += dx; + else if (ON_RIGHT_BORDER(hittest)) sizingRect.right += dx; +@@ -2903,32 +2888,21 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + else + SendMessageW( hwnd, WM_MOVING, 0, (LPARAM)&sizingRect ); + +- if (!iconic) ++ if (!DragFullWindows) ++ draw_moving_frame( parent, hdc, &sizingRect, thickframe ); ++ else + { +- if(!DragFullWindows) +- draw_moving_frame( parent, hdc, &sizingRect, thickframe ); +- else +- { +- RECT rect = sizingRect; +- MapWindowPoints( 0, parent, (POINT *)&rect, 2 ); +- SetWindowPos( hwnd, 0, rect.left, rect.top, +- rect.right - rect.left, rect.bottom - rect.top, +- ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ); +- } ++ RECT rect = sizingRect; ++ MapWindowPoints( 0, parent, (POINT *)&rect, 2 ); ++ SetWindowPos( hwnd, 0, rect.left, rect.top, ++ rect.right - rect.left, rect.bottom - rect.top, ++ (hittest == HTCAPTION) ? SWP_NOSIZE : 0 ); + } + } + } + } + +- if( iconic ) +- { +- if( moved ) /* restore cursors, show icon title later on */ +- { +- ShowCursor( FALSE ); +- SetCursor( hOldCursor ); +- } +- } +- else if (moved && !DragFullWindows) ++ if (moved && !DragFullWindows) + { + draw_moving_frame( parent, hdc, &sizingRect, thickframe ); + } +@@ -2952,7 +2926,7 @@ void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) + if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) ) + { + /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */ +- if(!DragFullWindows || iconic) ++ if (!DragFullWindows) + SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top, + sizingRect.right - sizingRect.left, + sizingRect.bottom - sizingRect.top, +-- +2.19.2 + diff --git a/patches/user32-minimized_windows/definition b/patches/user32-minimized_windows/definition new file mode 100644 index 00000000..1eeb790d --- /dev/null +++ b/patches/user32-minimized_windows/definition @@ -0,0 +1,2 @@ +Fixes: [7287] Redundant "tabs" appear with tabbed MDI (test with LTSpice) +# Switch from Win95-style "iconic" windows to later "minimized" windows.