[USER32][WIN32SS] Fix display of owned popup windows (#683)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Fri, 13 Jul 2018 14:03:45 +0000 (23:03 +0900)
committerHermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
Fri, 13 Jul 2018 14:03:45 +0000 (16:03 +0200)
An owned popup window should be hidden when its owner window was minimized.
- Add IntWinListOwnedPopups function.
- Fix ShowWindow and ShowOwnedPopups functions.

CORE-14818
See also: CORE-3326, CORE-12252, CORE-13168, and CORE-14824.

win32ss/user/ntuser/defwnd.c
win32ss/user/ntuser/window.c
win32ss/user/ntuser/window.h
win32ss/user/ntuser/winpos.c

index 367c5fa..eb72841 100644 (file)
@@ -619,14 +619,6 @@ IntDefWindowProc(
          if (!Wnd->spwndOwner) break;
          if (LOWORD(lParam))
          {
-            if (wParam)
-            {
-               if (!(Wnd->state & WNDS_HIDDENPOPUP)) break;
-               Wnd->state &= ~WNDS_HIDDENPOPUP;
-            }
-            else
-                Wnd->state |= WNDS_HIDDENPOPUP;
-
             co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
          }
          break;
index 838d854..95ffa02 100644 (file)
@@ -279,6 +279,39 @@ IntWinListChildren(PWND Window)
    return List;
 }
 
+HWND* FASTCALL
+IntWinListOwnedPopups(PWND Window)
+{
+    PWND Child, Desktop;
+    HWND *List;
+    UINT Index, NumChildren = 0;
+
+    Desktop = co_GetDesktopWindow(Window);
+    if (!Desktop)
+        return NULL;
+
+    for (Child = Desktop->spwndChild; Child; Child = Child->spwndNext)
+        ++NumChildren;
+
+    List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
+    if (!List)
+    {
+        ERR("Failed to allocate memory for children array\n");
+        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return NULL;
+    }
+
+    Index = 0;
+    for (Child = Desktop->spwndChild; Child; Child = Child->spwndNext)
+    {
+        if (Child->spwndOwner == Window)
+            List[Index++] = Child->head.h;
+    }
+    List[Index] = NULL;
+
+    return List;
+}
+
 PWND FASTCALL
 IntGetNonChildAncestor(PWND pWnd)
 {
@@ -4400,7 +4433,9 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
 //   ASSERT(OwnerWnd);
 
    TRACE("Enter ShowOwnedPopups Show: %s\n", (fShow ? "TRUE" : "FALSE"));
-   win_array = IntWinListChildren(OwnerWnd);
+
+   /* NOTE: Popups are not children */
+   win_array = IntWinListOwnedPopups(OwnerWnd);
 
    if (!win_array)
       return TRUE;
@@ -4423,6 +4458,7 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
              * regardless of the state of the owner
              */
             co_IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_SHOWNORMAL, SW_PARENTOPENING);
+            pWnd->state &= ~WNDS_HIDDENPOPUP;
             continue;
          }
       }
@@ -4435,10 +4471,10 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
              * regardless of the state of the owner
              */
             co_IntSendMessage(win_array[count], WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
+            pWnd->state |= WNDS_HIDDENPOPUP;
             continue;
          }
       }
-
    }
    ExFreePoolWithTag(win_array, USERTAG_WINDOWLIST);
    TRACE("Leave ShowOwnedPopups\n");
index 6c81191..24b6021 100644 (file)
@@ -41,6 +41,7 @@ PWND FASTCALL ValidateHwndNoErr(HWND);
 BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam);
 BOOL FASTCALL IntIsWindow(HWND hWnd);
 HWND* FASTCALL IntWinListChildren(PWND Window);
+HWND* FASTCALL IntWinListOwnedPopups(PWND Window);
 VOID FASTCALL IntGetClientRect (PWND WindowObject, RECTL *Rect);
 INT FASTCALL  IntMapWindowPoints(PWND FromWnd, PWND ToWnd, LPPOINT lpPoints, UINT cPoints);
 BOOL FASTCALL IntIsChildWindow (PWND Parent, PWND Child);
index d1f975e..b805e9f 100644 (file)
@@ -2275,11 +2275,11 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
 
                WinPosFindIconPos(Wnd, &wpl.ptMinPosition);
 
-               /*if (!(old_style & WS_MINIMIZE))
+               if (!(old_style & WS_MINIMIZE))
                {
                   SwpFlags |= SWP_STATECHANGED;
                   IntShowOwnedPopups(Wnd, FALSE);
-               }*/
+               }
 
                RECTL_vSetRect(NewPos, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
                              wpl.ptMinPosition.x + UserGetSystemMetrics(SM_CXMINIMIZED),
@@ -2325,7 +2325,7 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
                old_style = IntSetStyle( Wnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
                if (old_style & WS_MINIMIZE)
                {
-                  //IntShowOwnedPopups(Wnd, TRUE);
+                  IntShowOwnedPopups(Wnd, TRUE);
 
                   if (Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED)
                   {