Avoid calling WIN_ListChildren from the graphics drivers.
This commit is contained in:
parent
cb7aa8753c
commit
23d9ac25b2
|
@ -404,6 +404,28 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct move_owned_info
|
||||||
|
{
|
||||||
|
HWND owner;
|
||||||
|
HWND insert_after;
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK move_owned_popups( HWND hwnd, LPARAM lparam )
|
||||||
|
{
|
||||||
|
struct move_owned_info *info = (struct move_owned_info *)lparam;
|
||||||
|
|
||||||
|
if (hwnd == info->owner) return FALSE;
|
||||||
|
if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) &&
|
||||||
|
GetWindow( hwnd, GW_OWNER ) == info->owner)
|
||||||
|
{
|
||||||
|
SetWindowPos( hwnd, info->insert_after, 0, 0, 0, 0,
|
||||||
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
||||||
|
SWP_NOSENDCHANGING | SWP_DEFERERASE );
|
||||||
|
info->insert_after = hwnd;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SWP_DoOwnedPopups
|
* SWP_DoOwnedPopups
|
||||||
*
|
*
|
||||||
|
@ -414,55 +436,36 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RE
|
||||||
*/
|
*/
|
||||||
static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
|
static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
|
||||||
{
|
{
|
||||||
HWND *list = NULL;
|
|
||||||
HWND owner = GetWindow( hwnd, GW_OWNER );
|
HWND owner = GetWindow( hwnd, GW_OWNER );
|
||||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||||
|
struct move_owned_info info;
|
||||||
|
|
||||||
WARN("(%p) hInsertAfter = %p\n", hwnd, hwndInsertAfter );
|
TRACE("(%p) hInsertAfter = %p\n", hwnd, hwndInsertAfter );
|
||||||
|
|
||||||
if ((style & WS_POPUP) && owner)
|
if ((style & WS_POPUP) && owner)
|
||||||
{
|
{
|
||||||
/* make sure this popup stays above the owner */
|
/* make sure this popup stays above the owner */
|
||||||
|
|
||||||
HWND hwndLocalPrev = HWND_TOP;
|
|
||||||
|
|
||||||
if( hwndInsertAfter != HWND_TOP )
|
if( hwndInsertAfter != HWND_TOP )
|
||||||
{
|
{
|
||||||
if ((list = WIN_ListChildren( GetDesktopWindow() )))
|
HWND hwndLocalPrev = HWND_TOP;
|
||||||
|
HWND prev = GetWindow( owner, GW_HWNDPREV );
|
||||||
|
|
||||||
|
while (prev && prev != hwndInsertAfter)
|
||||||
{
|
{
|
||||||
int i;
|
if (hwndLocalPrev == HWND_TOP && GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE)
|
||||||
for (i = 0; list[i]; i++)
|
hwndLocalPrev = prev;
|
||||||
{
|
prev = GetWindow( prev, GW_HWNDPREV );
|
||||||
if (list[i] == owner) break;
|
|
||||||
if (list[i] != hwnd) hwndLocalPrev = list[i];
|
|
||||||
if (hwndLocalPrev == hwndInsertAfter) break;
|
|
||||||
}
|
|
||||||
hwndInsertAfter = hwndLocalPrev;
|
|
||||||
}
|
}
|
||||||
|
if (!prev) hwndInsertAfter = hwndLocalPrev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (style & WS_CHILD) return hwndInsertAfter;
|
else if (style & WS_CHILD) return hwndInsertAfter;
|
||||||
|
|
||||||
if (!list) list = WIN_ListChildren( GetDesktopWindow() );
|
info.owner = hwnd;
|
||||||
if (list)
|
info.insert_after = hwndInsertAfter;
|
||||||
{
|
EnumWindows( move_owned_popups, (LPARAM)&info );
|
||||||
int i;
|
return info.insert_after;
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
if (list[i] == hwnd) break;
|
|
||||||
if ((GetWindowLongW( list[i], GWL_STYLE ) & WS_POPUP) &&
|
|
||||||
GetWindow( list[i], GW_OWNER ) == hwnd)
|
|
||||||
{
|
|
||||||
SetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
|
|
||||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
|
||||||
SWP_NOSENDCHANGING | SWP_DEFERERASE );
|
|
||||||
hwndInsertAfter = list[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
|
||||||
}
|
|
||||||
|
|
||||||
return hwndInsertAfter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -733,6 +733,5 @@
|
||||||
@ cdecl WINPOS_ShowIconTitle(long long)
|
@ cdecl WINPOS_ShowIconTitle(long long)
|
||||||
@ cdecl WIN_GetPtr(long)
|
@ cdecl WIN_GetPtr(long)
|
||||||
@ cdecl WIN_LinkWindow(long long long)
|
@ cdecl WIN_LinkWindow(long long long)
|
||||||
@ cdecl WIN_ListChildren(long)
|
|
||||||
@ cdecl WIN_SetStyle(long long long)
|
@ cdecl WIN_SetStyle(long long long)
|
||||||
@ cdecl WIN_UnlinkWindow(long)
|
@ cdecl WIN_UnlinkWindow(long)
|
||||||
|
|
|
@ -585,35 +585,19 @@ static HWND find_drop_window( HWND hQueryWnd, LPPOINT lpPt )
|
||||||
|
|
||||||
if (!IsIconic( hQueryWnd ))
|
if (!IsIconic( hQueryWnd ))
|
||||||
{
|
{
|
||||||
|
POINT pt = *lpPt;
|
||||||
|
ScreenToClient( hQueryWnd, &pt );
|
||||||
GetClientRect( hQueryWnd, &tempRect );
|
GetClientRect( hQueryWnd, &tempRect );
|
||||||
MapWindowPoints( hQueryWnd, 0, (LPPOINT)&tempRect, 2 );
|
|
||||||
|
|
||||||
if (PtInRect( &tempRect, *lpPt))
|
if (PtInRect( &tempRect, pt))
|
||||||
{
|
{
|
||||||
HWND *list = WIN_ListChildren( hQueryWnd );
|
HWND ret = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE|CWP_SKIPDISABLED );
|
||||||
HWND bResult = 0;
|
if (ret && ret != hQueryWnd)
|
||||||
|
|
||||||
if (list)
|
|
||||||
{
|
{
|
||||||
int i;
|
ret = find_drop_window( ret, lpPt );
|
||||||
|
if (ret) return ret;
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
if (GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)
|
|
||||||
{
|
|
||||||
GetWindowRect( list[i], &tempRect );
|
|
||||||
if (PtInRect( &tempRect, *lpPt )) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list[i])
|
|
||||||
{
|
|
||||||
if (IsWindowEnabled( list[i] ))
|
|
||||||
bResult = find_drop_window( list[i], lpPt );
|
|
||||||
}
|
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
|
||||||
}
|
|
||||||
if(bResult) return bResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0;
|
if(!(GetWindowLongA( hQueryWnd, GWL_EXSTYLE ) & WS_EX_ACCEPTFILES)) return 0;
|
||||||
|
|
|
@ -470,6 +470,28 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct move_owned_info
|
||||||
|
{
|
||||||
|
HWND owner;
|
||||||
|
HWND insert_after;
|
||||||
|
};
|
||||||
|
|
||||||
|
static BOOL CALLBACK move_owned_popups( HWND hwnd, LPARAM lparam )
|
||||||
|
{
|
||||||
|
struct move_owned_info *info = (struct move_owned_info *)lparam;
|
||||||
|
|
||||||
|
if (hwnd == info->owner) return FALSE;
|
||||||
|
if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) &&
|
||||||
|
GetWindow( hwnd, GW_OWNER ) == info->owner)
|
||||||
|
{
|
||||||
|
SetWindowPos( hwnd, info->insert_after, 0, 0, 0, 0,
|
||||||
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
||||||
|
SWP_NOSENDCHANGING | SWP_DEFERERASE );
|
||||||
|
info->insert_after = hwnd;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* SWP_DoOwnedPopups
|
* SWP_DoOwnedPopups
|
||||||
*
|
*
|
||||||
|
@ -480,55 +502,36 @@ static UINT SWP_DoNCCalcSize( WINDOWPOS* pWinpos, const RECT* pNewWindowRect, RE
|
||||||
*/
|
*/
|
||||||
static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
|
static HWND SWP_DoOwnedPopups(HWND hwnd, HWND hwndInsertAfter)
|
||||||
{
|
{
|
||||||
HWND *list = NULL;
|
|
||||||
HWND owner = GetWindow( hwnd, GW_OWNER );
|
HWND owner = GetWindow( hwnd, GW_OWNER );
|
||||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||||
|
struct move_owned_info info;
|
||||||
|
|
||||||
WARN("(%p) hInsertAfter = %p\n", hwnd, hwndInsertAfter );
|
TRACE("(%p) hInsertAfter = %p\n", hwnd, hwndInsertAfter );
|
||||||
|
|
||||||
if ((style & WS_POPUP) && owner)
|
if ((style & WS_POPUP) && owner)
|
||||||
{
|
{
|
||||||
/* make sure this popup stays above the owner */
|
/* make sure this popup stays above the owner */
|
||||||
|
|
||||||
HWND hwndLocalPrev = HWND_TOP;
|
|
||||||
|
|
||||||
if( hwndInsertAfter != HWND_TOP )
|
if( hwndInsertAfter != HWND_TOP )
|
||||||
{
|
{
|
||||||
if ((list = WIN_ListChildren( GetDesktopWindow() )))
|
HWND hwndLocalPrev = HWND_TOP;
|
||||||
|
HWND prev = GetWindow( owner, GW_HWNDPREV );
|
||||||
|
|
||||||
|
while (prev && prev != hwndInsertAfter)
|
||||||
{
|
{
|
||||||
int i;
|
if (hwndLocalPrev == HWND_TOP && GetWindowLongW( prev, GWL_STYLE ) & WS_VISIBLE)
|
||||||
for (i = 0; list[i]; i++)
|
hwndLocalPrev = prev;
|
||||||
{
|
prev = GetWindow( prev, GW_HWNDPREV );
|
||||||
if (list[i] == owner) break;
|
|
||||||
if (list[i] != hwnd) hwndLocalPrev = list[i];
|
|
||||||
if (hwndLocalPrev == hwndInsertAfter) break;
|
|
||||||
}
|
|
||||||
hwndInsertAfter = hwndLocalPrev;
|
|
||||||
}
|
}
|
||||||
|
if (!prev) hwndInsertAfter = hwndLocalPrev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (style & WS_CHILD) return hwndInsertAfter;
|
else if (style & WS_CHILD) return hwndInsertAfter;
|
||||||
|
|
||||||
if (!list) list = WIN_ListChildren( GetDesktopWindow() );
|
info.owner = hwnd;
|
||||||
if (list)
|
info.insert_after = hwndInsertAfter;
|
||||||
{
|
EnumWindows( move_owned_popups, (LPARAM)&info );
|
||||||
int i;
|
return info.insert_after;
|
||||||
for (i = 0; list[i]; i++)
|
|
||||||
{
|
|
||||||
if (list[i] == hwnd) break;
|
|
||||||
if ((GetWindowLongW( list[i], GWL_STYLE ) & WS_POPUP) &&
|
|
||||||
GetWindow( list[i], GW_OWNER ) == hwnd)
|
|
||||||
{
|
|
||||||
SetWindowPos( list[i], hwndInsertAfter, 0, 0, 0, 0,
|
|
||||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
|
|
||||||
SWP_NOSENDCHANGING | SWP_DEFERERASE );
|
|
||||||
hwndInsertAfter = list[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
|
||||||
}
|
|
||||||
|
|
||||||
return hwndInsertAfter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -924,9 +927,10 @@ BOOL X11DRV_SetWindowPos( WINDOWPOS *winpos )
|
||||||
*/
|
*/
|
||||||
static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
|
static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
|
||||||
{
|
{
|
||||||
RECT rectParent;
|
RECT rect, rectParent;
|
||||||
HWND *list, parent;
|
HWND parent, child;
|
||||||
short x, y, xspacing, yspacing;
|
HRGN hrgn, tmp;
|
||||||
|
int xspacing, yspacing;
|
||||||
|
|
||||||
parent = GetAncestor( hwnd, GA_PARENT );
|
parent = GetAncestor( hwnd, GA_PARENT );
|
||||||
GetClientRect( parent, &rectParent );
|
GetClientRect( parent, &rectParent );
|
||||||
|
@ -937,54 +941,46 @@ static POINT WINPOS_FindIconPos( HWND hwnd, POINT pt )
|
||||||
xspacing = GetSystemMetrics(SM_CXICONSPACING);
|
xspacing = GetSystemMetrics(SM_CXICONSPACING);
|
||||||
yspacing = GetSystemMetrics(SM_CYICONSPACING);
|
yspacing = GetSystemMetrics(SM_CYICONSPACING);
|
||||||
|
|
||||||
list = WIN_ListChildren( parent );
|
|
||||||
y = rectParent.bottom;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
x = rectParent.left;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Check if another icon already occupies this spot */
|
/* Check if another icon already occupies this spot */
|
||||||
/* FIXME: this is completely inefficient */
|
/* FIXME: this is completely inefficient */
|
||||||
if (list)
|
|
||||||
|
hrgn = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
|
tmp = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
|
for (child = GetWindow( parent, GW_HWNDFIRST ); child; child = GetWindow( child, GW_HWNDNEXT ))
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
WND *childPtr;
|
WND *childPtr;
|
||||||
|
if (child == hwnd) continue;
|
||||||
for (i = 0; list[i]; i++)
|
if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
|
||||||
{
|
|
||||||
if (list[i] == hwnd) continue;
|
|
||||||
if (!IsIconic( list[i] )) continue;
|
|
||||||
if (!(childPtr = WIN_GetPtr( list[i] )) || childPtr == WND_OTHER_PROCESS)
|
|
||||||
continue;
|
continue;
|
||||||
if ((childPtr->rectWindow.left < x + xspacing) &&
|
if (!(childPtr = WIN_GetPtr( child )) || childPtr == WND_OTHER_PROCESS)
|
||||||
(childPtr->rectWindow.right >= x) &&
|
continue;
|
||||||
(childPtr->rectWindow.top <= y) &&
|
SetRectRgn( tmp, childPtr->rectWindow.left, childPtr->rectWindow.top,
|
||||||
(childPtr->rectWindow.bottom > y - yspacing))
|
childPtr->rectWindow.right, childPtr->rectWindow.bottom );
|
||||||
{
|
CombineRgn( hrgn, hrgn, tmp, RGN_OR );
|
||||||
WIN_ReleasePtr( childPtr );
|
|
||||||
break; /* There's a window in there */
|
|
||||||
}
|
|
||||||
WIN_ReleasePtr( childPtr );
|
WIN_ReleasePtr( childPtr );
|
||||||
}
|
}
|
||||||
if (list[i])
|
DeleteObject( tmp );
|
||||||
{
|
|
||||||
/* found something here, try next spot */
|
|
||||||
x += xspacing;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
|
||||||
|
{
|
||||||
|
for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
|
||||||
|
{
|
||||||
|
rect.right = rect.left + xspacing;
|
||||||
|
rect.top = rect.bottom - yspacing;
|
||||||
|
if (!RectInRegion( hrgn, &rect ))
|
||||||
|
{
|
||||||
/* No window was found, so it's OK for us */
|
/* No window was found, so it's OK for us */
|
||||||
pt.x = x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
|
pt.x = rect.left + (xspacing - GetSystemMetrics(SM_CXICON)) / 2;
|
||||||
pt.y = y - (yspacing + GetSystemMetrics(SM_CYICON)) / 2;
|
pt.y = rect.top + (yspacing - GetSystemMetrics(SM_CYICON)) / 2;
|
||||||
HeapFree( GetProcessHeap(), 0, list );
|
DeleteObject( hrgn );
|
||||||
return pt;
|
return pt;
|
||||||
|
|
||||||
} while(x <= rectParent.right-xspacing);
|
|
||||||
y -= yspacing;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
DeleteObject( hrgn );
|
||||||
|
pt.x = pt.y = 0;
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
|
||||||
|
|
||||||
GetClientRect( hwndParent, &rect );
|
GetClientRect( hwndParent, &rect );
|
||||||
if (!PtInRect( &rect, pt )) return 0;
|
if (!PtInRect( &rect, pt )) return 0;
|
||||||
if (!(list = WIN_ListChildren( hwndParent ))) return 0;
|
if (!(list = WIN_ListChildren( hwndParent ))) return hwndParent;
|
||||||
|
|
||||||
for (i = 0; list[i]; i++)
|
for (i = 0; list[i]; i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue