[PATCH 07/10] user32: Correctly place minimized windows.
Zebediah Figura
z.figura12 at gmail.com
Mon Feb 18 21:15:59 CST 2019
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
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 285a8489e4..461b696f9b 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -6551,7 +6551,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);
@@ -6714,7 +6713,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);
@@ -6776,14 +6774,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));
@@ -6798,7 +6794,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));
@@ -6904,14 +6899,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));
@@ -6926,7 +6919,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));
@@ -7029,14 +7021,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));
@@ -7051,7 +7041,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 eb05aaf283..77aa46c55c 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.20.1
More information about the wine-devel
mailing list