[USER32][WIN32SS] Fix display of owned popup windows (#683)

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.
This commit is contained in:
Katayama Hirofumi MZ 2018-07-13 23:03:45 +09:00 committed by Hermès BÉLUSCA - MAÏTO
parent 75b09f3f88
commit 42353ecbad
4 changed files with 42 additions and 13 deletions

View 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;

View 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");

View 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);

View 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)
{