Author: jimtabor
Date: Sun Dec 8 00:40:54 2013
New Revision: 61244
URL:
http://svn.reactos.org/svn/reactos?rev=61244&view=rev
Log:
[Win32k]
- Restore code from revision 48982 by Giannis Adamopoulos. See CORE-6554.
- Port sync wine winpos code. Fixes all the wine win:test_children/popup_zorder tests
except "move hwnd_F and its popups down" that is if'ed out. Side effect,
ReactOS regressed from 29 to 48 failures for the DeferWindowPos API test. That is not bad
compared to wine ran 347 tests and 52 failures, ReactOS ran 385 tests.
- Keeping code if'ed out for now and added a flag to set most bottom window.
Modified:
trunk/reactos/win32ss/user/ntuser/window.c
trunk/reactos/win32ss/user/ntuser/window.h
trunk/reactos/win32ss/user/ntuser/winpos.c
Modified: trunk/reactos/win32ss/user/ntuser/window.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/window.c [iso-8859-1] Sun Dec 8 00:40:54 2013
@@ -305,6 +305,64 @@
Depth++;
}
return FALSE;
+}
+
+HWND FASTCALL
+IntGetWindow(HWND hWnd,
+ UINT uCmd)
+{
+ PWND Wnd, FoundWnd;
+ HWND Ret = NULL;
+
+ Wnd = ValidateHwndNoErr(hWnd);
+ if (!Wnd)
+ return NULL;
+
+ FoundWnd = NULL;
+ switch (uCmd)
+ {
+ case GW_OWNER:
+ if (Wnd->spwndOwner != NULL)
+ FoundWnd = Wnd->spwndOwner;
+ break;
+
+ case GW_HWNDFIRST:
+ if(Wnd->spwndParent != NULL)
+ {
+ FoundWnd = Wnd->spwndParent;
+ if (FoundWnd->spwndChild != NULL)
+ FoundWnd = FoundWnd->spwndChild;
+ }
+ break;
+ case GW_HWNDNEXT:
+ if (Wnd->spwndNext != NULL)
+ FoundWnd = Wnd->spwndNext;
+ break;
+
+ case GW_HWNDPREV:
+ if (Wnd->spwndPrev != NULL)
+ FoundWnd = Wnd->spwndPrev;
+ break;
+
+ case GW_CHILD:
+ if (Wnd->spwndChild != NULL)
+ FoundWnd = Wnd->spwndChild;
+ break;
+
+ case GW_HWNDLAST:
+ FoundWnd = Wnd;
+ while ( FoundWnd->spwndNext != NULL)
+ FoundWnd = FoundWnd->spwndNext;
+ break;
+
+ default:
+ Wnd = NULL;
+ break;
+ }
+
+ if (FoundWnd != NULL)
+ Ret = UserHMGetHandle(FoundWnd);
+ return Ret;
}
/***********************************************************************
@@ -3403,6 +3461,7 @@
}
UserRefObjectCo(WndShell, &Ref);
+ WndShell->state2 |= WNDS2_BOTTOMMOST;
co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
WinStaObject->ShellWindow = hwndShell;
Modified: trunk/reactos/win32ss/user/ntuser/window.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/window…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/window.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/window.h [iso-8859-1] Sun Dec 8 00:40:54 2013
@@ -61,5 +61,6 @@
PWND FASTCALL VerifyWnd(PWND);
PWND FASTCALL IntGetNonChildAncestor(PWND);
LONG FASTCALL co_UserSetWindowLong(HWND,DWORD,LONG,BOOL);
+HWND FASTCALL IntGetWindow(HWND,UINT);
/* EOF */
Modified: trunk/reactos/win32ss/user/ntuser/winpos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/winpos…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] Sun Dec 8 00:40:54 2013
@@ -1349,21 +1349,23 @@
Y = WinPos->y;
//ERR("Not SWP_NOMOVE\n");
Parent = Window->spwndParent;
- if ((0 != (Window->style & WS_CHILD)) && Parent &&
- Parent != Window->head.rpdesk->pDeskInfo->spwnd)
- {
- //ERR("Not SWP_NOMOVE Parent client offset\n");
+ if (((Window->style & WS_CHILD) != 0) &&
+ Parent &&
+ Parent != Window->head.rpdesk->pDeskInfo->spwnd)
+ {
+ //ERR("Not SWP_NOMOVE 1 Parent client offset X %d Y %d\n",X,Y);
X += Parent->rcClient.left;
Y += Parent->rcClient.top;
+ //ERR("Not SWP_NOMOVE 2 Parent client offset X %d Y %d\n",X,Y);
}
WindowRect->left = X;
WindowRect->top = Y;
WindowRect->right += X - Window->rcWindow.left;
WindowRect->bottom += Y - Window->rcWindow.top;
- RECTL_vOffsetRect(ClientRect,
- X - Window->rcWindow.left,
- Y - Window->rcWindow.top);
+
+ RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left,
+ Y - Window->rcWindow.top);
}
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
@@ -1382,7 +1384,11 @@
* FIXME: hide/show owned popups when owner visibility changes.
*
* ReactOS: See bug 6751 and 7228.
+ *
*/
+ ////
+ // Pass all the win:test_children/popup_zorder tests except "move hwnd_F and its
popups down" which is if'ed out.
+ // Side effect, breaks more of the DeferWindowPos api tests, but wine breaks more!!!!
static
HWND FASTCALL
WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
@@ -1393,13 +1399,20 @@
PWND DesktopWindow, ChildObject;
int i;
+ TRACE("(%p) hInsertAfter = %p\n", Window, hWndInsertAfter );
+
Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
Style = Window->style;
- if ((Style & WS_POPUP) && Owner)
+ if (Style & WS_CHILD)
+ {
+ TRACE("Window is child\n");
+ return hWndInsertAfter;
+ }
+
+ if (Owner)
{
/* Make sure this popup stays above the owner */
- HWND hWndLocalPrev = HWND_TOPMOST;
if (hWndInsertAfter != HWND_TOPMOST)
{
@@ -1410,31 +1423,38 @@
{
for (i = 0; List[i]; i++)
{
+ BOOL topmost = FALSE;
+
+ ChildObject = ValidateHwndNoErr(List[i]);
+ if (ChildObject)
+ {
+ topmost = (ChildObject->ExStyle & WS_EX_TOPMOST) != 0;
+ }
+
if (List[i] == Owner)
+ {
+ if (i > 0) hWndInsertAfter = List[i-1];
+ else hWndInsertAfter = topmost ? HWND_TOPMOST : HWND_TOP;
break;
- if (HWND_TOP == hWndInsertAfter)
+ }
+
+ if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
{
- ChildObject = ValidateHwndNoErr(List[i]);
- if (NULL != ChildObject)
- {
- if (0 == (ChildObject->ExStyle & WS_EX_TOPMOST))
- {
- break;
- }
- }
+ if (!topmost) break;
}
- if (List[i] != Window->head.h)
- hWndLocalPrev = List[i];
- if (hWndLocalPrev == hWndInsertAfter)
- break;
+ else if (List[i] == hWndInsertAfter) break;
}
- hWndInsertAfter = hWndLocalPrev;
- }
- }
- }
- else if (Style & WS_CHILD)
- {
- return hWndInsertAfter;
+ }
+ else
+ return hWndInsertAfter;
+ }
+ }
+
+ if (hWndInsertAfter == HWND_BOTTOM)
+ {
+ TRACE("Window is HWND_BOTTOM\n");
+ if (List) ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ goto done;
}
if (!List)
@@ -1442,11 +1462,40 @@
DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
}
+
if (List != NULL)
{
- for (i = 0; List[i]; i++)
+ i = 0;
+
+ if (hWndInsertAfter == HWND_TOP || hWndInsertAfter == HWND_NOTOPMOST)
+ {
+ if (hWndInsertAfter == HWND_NOTOPMOST || !(Window->ExStyle &
WS_EX_TOPMOST))
+ {
+ TRACE("skip all the topmost windows\n");
+ /* skip all the topmost windows */
+ while (List[i] &&
+ (ChildObject = ValidateHwndNoErr(List[i])) &&
+ (ChildObject->ExStyle & WS_EX_TOPMOST)) i++;
+ }
+ }
+ else if (hWndInsertAfter != HWND_TOPMOST)
+ {
+ /* skip windows that are already placed correctly */
+ for (i = 0; List[i]; i++)
+ {
+ if (List[i] == hWndInsertAfter) break;
+ if (List[i] == UserHMGetHandle(Window))
+ {
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ goto done; /* nothing to do if window is moving backwards in z-order */
+ }
+ }
+ }
+
+ for (; List[i]; i++)
{
PWND Wnd;
+ USER_REFERENCE_ENTRY Ref;
if (List[i] == UserHMGetHandle(Window))
break;
@@ -1454,24 +1503,24 @@
if (!(Wnd = ValidateHwndNoErr(List[i])))
continue;
- if (Wnd->style & WS_POPUP && Wnd->spwndOwner == Window)
- {
- USER_REFERENCE_ENTRY Ref;
- UserRefObjectCo(Wnd, &Ref);
-
- co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOSENDCHANGING| SWP_DEFERERASE);
-
- UserDerefObjectCo(Wnd);
-
- hWndInsertAfter = List[i];
- }
+ Owner = Wnd->spwndOwner ? Wnd->spwndOwner->head.h : NULL;
+
+ if (Owner != UserHMGetHandle(Window)) continue;
+
+ UserRefObjectCo(Wnd, &Ref);
+ TRACE( "moving %p owned by %p after %p\n", List[i],
UserHMGetHandle(Window), hWndInsertAfter );
+ co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOSENDCHANGING| SWP_DEFERERASE);
+
+ UserDerefObjectCo(Wnd);
+ hWndInsertAfter = List[i];
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
-
+done:
return hWndInsertAfter;
}
+////
/***********************************************************************
* WinPosInternalMoveWindow
@@ -1527,15 +1576,11 @@
Parent = UserGetAncestor( Wnd, GA_PARENT );
if (!IntIsWindowVisible( Parent )) WinPos->flags |= SWP_NOREDRAW;
- if (Wnd->style & WS_VISIBLE)
- {
- WinPos->flags &= ~SWP_SHOWWINDOW;
- }
+ if (Wnd->style & WS_VISIBLE) WinPos->flags &= ~SWP_SHOWWINDOW;
else
{
WinPos->flags &= ~SWP_HIDEWINDOW;
- if (!(WinPos->flags & SWP_SHOWWINDOW))
- WinPos->flags |= SWP_NOREDRAW;
+ if (!(WinPos->flags & SWP_SHOWWINDOW)) WinPos->flags |= SWP_NOREDRAW;
}
/* Check for right size */
@@ -1548,12 +1593,11 @@
pt.x = WinPos->x;
pt.y = WinPos->y;
IntClientToScreen( Parent, &pt );
-// ERR("WPFU C2S wpx %d wpy %d ptx %d pty
%d\n",WinPos->x,WinPos->y,pt.x,pt.y);
+ //ERR("WPFU C2S wpx %d wpy %d ptx %d pty
%d\n",WinPos->x,WinPos->y,pt.x,pt.y);
/* Check for right position */
- if (Wnd->rcWindow.left == pt.x &&
- Wnd->rcWindow.top == pt.y)
- {
-// ERR("In right pos\n");
+ if (Wnd->rcWindow.left == pt.x && Wnd->rcWindow.top == pt.y)
+ {
+ //ERR("In right pos\n");
WinPos->flags |= SWP_NOMOVE;
}
@@ -1565,12 +1609,12 @@
if ((Wnd->style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
{
/* Bring to the top when activating */
- if (!(WinPos->flags & SWP_NOACTIVATE))
+ if (!(WinPos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW)) &&
+ (WinPos->flags & SWP_NOZORDER ||
+ (WinPos->hwndInsertAfter != HWND_TOPMOST &&
WinPos->hwndInsertAfter != HWND_NOTOPMOST)))
{
WinPos->flags &= ~SWP_NOZORDER;
- WinPos->hwndInsertAfter = (0 != (Wnd->ExStyle & WS_EX_TOPMOST) ?
- HWND_TOPMOST : HWND_TOP);
- return TRUE;
+ WinPos->hwndInsertAfter = (0 != (Wnd->ExStyle & WS_EX_TOPMOST) ?
HWND_TOPMOST : HWND_TOP);
}
}
@@ -1587,25 +1631,31 @@
WinPos->hwndInsertAfter = HWND_NOTOPMOST;
}
- if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
+ if (WinPos->hwndInsertAfter == HWND_TOP)
+ {
+ /* Keep it topmost when it's already topmost */
+ if ((Wnd->ExStyle & WS_EX_TOPMOST) != 0)
+ WinPos->hwndInsertAfter = HWND_TOPMOST;
+
+ if (IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else if (WinPos->hwndInsertAfter == HWND_BOTTOM)
+ {
+ if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDLAST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else if (WinPos->hwndInsertAfter == HWND_TOPMOST)
+ {
+ if ((Wnd->ExStyle & WS_EX_TOPMOST) &&
IntGetWindow(WinPos->hwnd, GW_HWNDFIRST) == WinPos->hwnd)
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ else if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
{
if (!(Wnd->ExStyle & WS_EX_TOPMOST))
WinPos->flags |= SWP_NOZORDER;
-
- WinPos->hwndInsertAfter = HWND_TOP;
- }
- else if (HWND_TOP == WinPos->hwndInsertAfter
- && 0 != (Wnd->ExStyle & WS_EX_TOPMOST))
- {
- /* Keep it topmost when it's already topmost */
- WinPos->hwndInsertAfter = HWND_TOPMOST;
- }
-
- /* hwndInsertAfter must be a sibling of the window */
- if (HWND_TOPMOST != WinPos->hwndInsertAfter
- && HWND_TOP != WinPos->hwndInsertAfter
- && HWND_NOTOPMOST != WinPos->hwndInsertAfter
- && HWND_BOTTOM != WinPos->hwndInsertAfter)
+ }
+ else /* hwndInsertAfter must be a sibling of the window */
{
PWND InsAfterWnd;
@@ -1673,7 +1723,7 @@
RECTL CopyRect;
PWND Ancestor;
BOOL bPointerInWindow;
- BOOL bNoTopMost;
+ //BOOL bNoTopMost;
ASSERT_REFS_CO(Window);
@@ -1713,7 +1763,7 @@
co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect,
&NewClientRect);
// HWND_NOTOPMOST is redirected in WinPosFixupFlags.
- bNoTopMost = WndInsertAfter == HWND_NOTOPMOST;
+ //bNoTopMost = WndInsertAfter == HWND_NOTOPMOST;
/* Does the window still exist? */
if (!IntIsWindow(WinPos.hwnd))
@@ -1774,6 +1824,8 @@
/* Validate link windows. (also take into account shell window in hwndShellWindow) */
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd !=
UserGetShellWindow())
{
+ IntLinkHwnd(Window, WinPos.hwndInsertAfter);
+#if 0
//// Fix bug 6751 & 7228 see WinPosDoOwnedPopups wine Fixme.
PWND ParentWindow;
PWND Sibling;
@@ -1836,6 +1888,7 @@
}
}
////
+#endif
}
OldWindowRect = Window->rcWindow;