mirror of
https://github.com/reactos/reactos.git
synced 2024-06-21 13:31:38 +00:00
[0.4.12][WIN32SS] MENU_ShowPopup() We chicken out for this rls still
as the release data is close and we have to manage the risk.
This reverts last commit and all menu related code back to the state of
0.4.12-dev-369-g
007ec0310c
Although Mark Jansen seems to be on a very promising path in master,
we still revert one last time for this release to the more well known
state we had during 0.4.12dev'ing.
This will fix regressions CORE-16298, CORE-16297
and will keep CORE-15863 in fixed state.
Systray and nested desktop popups do work very well like this.
We therefore intentionally and willingly have to accept the broken
partial-offscreen-menus of CORE-15733.
Those are not as important as the other tickets.
Meanwhile we keep on improving master based on the more recent states.
This commit is contained in:
parent
3113d13793
commit
d52cac4ca1
|
@ -2860,110 +2860,22 @@ static BOOL MENU_InitPopup( PWND pWndOwner, PMENU menu, UINT flags )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#define SHOW_DEBUGRECT 0
|
||||
|
||||
#if SHOW_DEBUGRECT
|
||||
static void DebugRect(const RECT* rectl, COLORREF color)
|
||||
{
|
||||
HBRUSH brush;
|
||||
RECT rr;
|
||||
HDC hdc;
|
||||
|
||||
if (!rectl)
|
||||
return;
|
||||
|
||||
hdc = UserGetDCEx(NULL, 0, DCX_USESTYLE);
|
||||
|
||||
brush = IntGdiCreateSolidBrush(color);
|
||||
|
||||
rr = *rectl;
|
||||
RECTL_vInflateRect(&rr, 1, 1);
|
||||
FrameRect(hdc, rectl, brush);
|
||||
FrameRect(hdc, &rr, brush);
|
||||
|
||||
NtGdiDeleteObjectApp(brush);
|
||||
UserReleaseDC(NULL, hdc, TRUE);
|
||||
}
|
||||
|
||||
static void DebugPoint(INT x, INT y, COLORREF color)
|
||||
{
|
||||
RECT rr = {x, y, x, y};
|
||||
DebugRect(&rr, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL RECTL_Intersect(const RECT* pRect, INT x, INT y, UINT width, UINT height)
|
||||
{
|
||||
RECT other = {x, y, x + width, y + height};
|
||||
RECT dum;
|
||||
|
||||
return RECTL_bIntersectRect(&dum, pRect, &other);
|
||||
}
|
||||
|
||||
static BOOL MENU_MoveRect(UINT flags, INT* x, INT* y, INT width, INT height, const RECT* pExclude, PMONITOR monitor)
|
||||
{
|
||||
/* Figure out if we should move vertical or horizontal */
|
||||
if (flags & TPM_VERTICAL)
|
||||
{
|
||||
/* Move in the vertical direction: TPM_BOTTOMALIGN means drop it above, otherways drop it below */
|
||||
if (flags & TPM_BOTTOMALIGN)
|
||||
{
|
||||
if (pExclude->top - height >= monitor->rcMonitor.top)
|
||||
{
|
||||
*y = pExclude->top - height;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pExclude->bottom + height < monitor->rcMonitor.bottom)
|
||||
{
|
||||
*y = pExclude->bottom;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move in the horizontal direction: TPM_RIGHTALIGN means drop it to the left, otherways go right */
|
||||
if (flags & TPM_RIGHTALIGN)
|
||||
{
|
||||
if (pExclude->left - width >= monitor->rcMonitor.left)
|
||||
{
|
||||
*x = pExclude->left - width;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pExclude->right + width < monitor->rcMonitor.right)
|
||||
{
|
||||
*x = pExclude->right;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MenuShowPopup
|
||||
*
|
||||
* Display a popup menu.
|
||||
*/
|
||||
static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT flags,
|
||||
INT x, INT y, const RECT* pExclude)
|
||||
INT x, INT y, INT xanchor, INT yanchor )
|
||||
{
|
||||
UINT width, height;
|
||||
POINT ptx;
|
||||
POINT pt;
|
||||
PMONITOR monitor;
|
||||
PWND pWnd;
|
||||
USER_REFERENCE_ENTRY Ref;
|
||||
BOOL bIsPopup = (flags & TPM_POPUPMENU) != 0;
|
||||
|
||||
TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x\n",
|
||||
pwndOwner, menu, id, x, y);
|
||||
TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
|
||||
pwndOwner, menu, id, x, y, xanchor, yanchor);
|
||||
|
||||
if (menu->iItem != NO_SELECTED_ITEM)
|
||||
{
|
||||
|
@ -2971,11 +2883,6 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
|
|||
menu->iItem = NO_SELECTED_ITEM;
|
||||
}
|
||||
|
||||
#if SHOW_DEBUGRECT
|
||||
if (pExclude)
|
||||
DebugRect(pExclude, RGB(255, 0, 0));
|
||||
#endif
|
||||
|
||||
menu->dwArrowsOn = 0;
|
||||
MENU_PopupMenuCalcSize(menu, pwndOwner);
|
||||
|
||||
|
@ -2984,102 +2891,67 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
|
|||
width = menu->cxMenu + UserGetSystemMetrics(SM_CXBORDER);
|
||||
height = menu->cyMenu + UserGetSystemMetrics(SM_CYBORDER);
|
||||
|
||||
if (flags & TPM_LAYOUTRTL)
|
||||
/* FIXME: should use item rect */
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
monitor = UserMonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
|
||||
|
||||
if (flags & TPM_LAYOUTRTL)
|
||||
flags ^= TPM_RIGHTALIGN;
|
||||
|
||||
if (flags & TPM_RIGHTALIGN)
|
||||
x -= width;
|
||||
if (flags & TPM_CENTERALIGN)
|
||||
x -= width / 2;
|
||||
if( flags & TPM_RIGHTALIGN ) x -= width;
|
||||
if( flags & TPM_CENTERALIGN ) x -= width / 2;
|
||||
|
||||
if (flags & TPM_BOTTOMALIGN)
|
||||
y -= height;
|
||||
if (flags & TPM_VCENTERALIGN)
|
||||
y -= height / 2;
|
||||
if( flags & TPM_BOTTOMALIGN ) y -= height;
|
||||
if( flags & TPM_VCENTERALIGN ) y -= height / 2;
|
||||
|
||||
/* FIXME: should use item rect */
|
||||
ptx.x = x;
|
||||
ptx.y = y;
|
||||
#if SHOW_DEBUGRECT
|
||||
DebugPoint(x, y, RGB(0, 0, 255));
|
||||
#endif
|
||||
monitor = UserMonitorFromPoint( ptx, MONITOR_DEFAULTTONEAREST );
|
||||
|
||||
/* We are off the right side of the screen */
|
||||
if (x + width > monitor->rcMonitor.right)
|
||||
if( x + width > monitor->rcMonitor.right)
|
||||
{
|
||||
if ((x - width) < monitor->rcMonitor.left || x >= monitor->rcMonitor.right)
|
||||
x = monitor->rcMonitor.right - width;
|
||||
else
|
||||
x -= width;
|
||||
}
|
||||
if( xanchor && x >= width - xanchor )
|
||||
x -= width - xanchor;
|
||||
|
||||
/* We are off the left side of the screen */
|
||||
if (x < monitor->rcMonitor.left)
|
||||
{
|
||||
/* Re-orient the menu around the x-axis */
|
||||
x += width;
|
||||
|
||||
if (x < monitor->rcMonitor.left || x >= monitor->rcMonitor.right || bIsPopup)
|
||||
x = monitor->rcMonitor.left;
|
||||
}
|
||||
|
||||
/* Same here, but then the top */
|
||||
if (y < monitor->rcMonitor.top)
|
||||
{
|
||||
y += height;
|
||||
|
||||
if (y < monitor->rcMonitor.top || y >= monitor->rcMonitor.bottom || bIsPopup)
|
||||
y = monitor->rcMonitor.top;
|
||||
}
|
||||
|
||||
/* And the bottom */
|
||||
if (y + height > monitor->rcMonitor.bottom)
|
||||
{
|
||||
if ((y - height) < monitor->rcMonitor.top || y >= monitor->rcMonitor.bottom || bIsPopup)
|
||||
y = monitor->rcMonitor.bottom - height;
|
||||
else
|
||||
y -= height;
|
||||
}
|
||||
|
||||
if (pExclude)
|
||||
{
|
||||
RECT Cleaned;
|
||||
|
||||
if (RECTL_bIntersectRect(&Cleaned, pExclude, &monitor->rcMonitor) &&
|
||||
RECTL_Intersect(&Cleaned, x, y, width, height))
|
||||
if( x + width > monitor->rcMonitor.right)
|
||||
{
|
||||
UINT flag_mods[] = {
|
||||
0, /* First try the 'normal' way */
|
||||
TPM_BOTTOMALIGN | TPM_RIGHTALIGN, /* Then try the opposite side */
|
||||
TPM_VERTICAL, /* Then swap horizontal / vertical */
|
||||
TPM_BOTTOMALIGN | TPM_RIGHTALIGN | TPM_VERTICAL, /* Then the other side again (still swapped hor/ver) */
|
||||
};
|
||||
UINT n;
|
||||
for (n = 0; n < RTL_NUMBER_OF(flag_mods); ++n)
|
||||
{
|
||||
INT tx = x;
|
||||
INT ty = y;
|
||||
|
||||
/* Try to move a bit around */
|
||||
if (MENU_MoveRect(flags ^ flag_mods[n], &tx, &ty, width, height, &Cleaned, monitor) &&
|
||||
!RECTL_Intersect(&Cleaned, tx, ty, width, height))
|
||||
{
|
||||
x = tx;
|
||||
y = ty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If none worked, we go with the original x/y */
|
||||
/* If we would flip around our origin, would we go off screen on the other side?
|
||||
Or is our origin itself too far to the right already? */
|
||||
if (x - width < monitor->rcMonitor.left || x > monitor->rcMonitor.right)
|
||||
x = monitor->rcMonitor.right - width;
|
||||
else
|
||||
x -= width;
|
||||
}
|
||||
}
|
||||
|
||||
#if SHOW_DEBUGRECT
|
||||
if( x < monitor->rcMonitor.left )
|
||||
{
|
||||
RECT rr = {x, y, x + width, y + height};
|
||||
DebugRect(&rr, RGB(0, 255, 0));
|
||||
/* If we would flip around our origin, would we go off screen on the other side? */
|
||||
if (x + width > monitor->rcMonitor.right)
|
||||
x = monitor->rcMonitor.left;
|
||||
else
|
||||
x += width;
|
||||
}
|
||||
|
||||
if( y + height > monitor->rcMonitor.bottom)
|
||||
{
|
||||
if( yanchor && y >= height + yanchor )
|
||||
y -= height + yanchor;
|
||||
|
||||
if( y + height > monitor->rcMonitor.bottom)
|
||||
{
|
||||
/* If we would flip around our origin, would we go off screen on the other side?
|
||||
Or is our origin itself too far to the bottom already? */
|
||||
if (y - height < monitor->rcMonitor.top || y > monitor->rcMonitor.bottom)
|
||||
y = monitor->rcMonitor.bottom - height;
|
||||
else
|
||||
y -= height;
|
||||
}
|
||||
}
|
||||
if( y < monitor->rcMonitor.top )
|
||||
{
|
||||
/* If we would flip around our origin, would we go off screen on the other side? */
|
||||
if (y + height > monitor->rcMonitor.bottom)
|
||||
y = monitor->rcMonitor.top;
|
||||
else
|
||||
y += height;
|
||||
}
|
||||
#endif
|
||||
|
||||
pWnd = ValidateHwndNoErr( menu->hWnd );
|
||||
|
||||
|
@ -3327,7 +3199,7 @@ static void FASTCALL MENU_HideSubPopups(PWND pWndOwner, PMENU Menu,
|
|||
*/
|
||||
static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFirst, UINT Flags)
|
||||
{
|
||||
RECT Rect, ParentRect;
|
||||
RECT Rect;
|
||||
ITEM *Item;
|
||||
HDC Dc;
|
||||
PWND pWnd;
|
||||
|
@ -3362,13 +3234,6 @@ static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFi
|
|||
|
||||
pWnd = ValidateHwndNoErr(Menu->hWnd);
|
||||
|
||||
/* Grab the rect of our (entire) parent menu, so we can try to not overlap it */
|
||||
if (!IntGetWindowRect(pWnd, &ParentRect))
|
||||
{
|
||||
ERR("No pWnd\n");
|
||||
ParentRect = Rect;
|
||||
}
|
||||
|
||||
/* correct item if modified as a reaction to WM_INITMENUPOPUP message */
|
||||
if (!(Item->fState & MF_HILITE))
|
||||
{
|
||||
|
@ -3445,7 +3310,7 @@ static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFi
|
|||
MENU_InitPopup( WndOwner, Item->spSubMenu, Flags );
|
||||
|
||||
MENU_ShowPopup( WndOwner, Item->spSubMenu, Menu->iItem, Flags,
|
||||
Rect.left, Rect.top, &ParentRect);
|
||||
Rect.left, Rect.top, Rect.right, Rect.bottom );
|
||||
if (SelectFirst)
|
||||
{
|
||||
MENU_MoveSelection(WndOwner, Item->spSubMenu, ITEM_NEXT);
|
||||
|
@ -4045,7 +3910,7 @@ static void FASTCALL MENU_KeyRight(MTRACKER *pmt, UINT Flags, UINT msg)
|
|||
* Menu tracking code.
|
||||
*/
|
||||
static INT FASTCALL MENU_TrackMenu(PMENU pmenu, UINT wFlags, INT x, INT y,
|
||||
PWND pwnd)
|
||||
PWND pwnd, const RECT *lprect )
|
||||
{
|
||||
MSG msg;
|
||||
BOOL fRemove;
|
||||
|
@ -4068,8 +3933,9 @@ static INT FASTCALL MENU_TrackMenu(PMENU pmenu, UINT wFlags, INT x, INT y,
|
|||
mt.Pt.x = x;
|
||||
mt.Pt.y = y;
|
||||
|
||||
TRACE("MTM : hmenu=%p flags=0x%08x (%d,%d) hwnd=%x\n",
|
||||
UserHMGetHandle(pmenu), wFlags, x, y, UserHMGetHandle(pwnd));
|
||||
TRACE("MTM : hmenu=%p flags=0x%08x (%d,%d) hwnd=%x (%ld,%ld)-(%ld,%ld)\n",
|
||||
UserHMGetHandle(pmenu), wFlags, x, y, UserHMGetHandle(pwnd), lprect ? lprect->left : 0, lprect ? lprect->top : 0,
|
||||
lprect ? lprect->right : 0, lprect ? lprect->bottom : 0);
|
||||
|
||||
pti->MessageQueue->QF_flags &= ~QF_ACTIVATIONCHANGE;
|
||||
|
||||
|
@ -4480,7 +4346,7 @@ VOID MENU_TrackMouseMenuBar( PWND pWnd, ULONG ht, POINT pt)
|
|||
MENU_InitTracking(pWnd, pMenu, FALSE, wFlags);
|
||||
/* fetch the window menu again, it may have changed */
|
||||
pMenu = (ht == HTSYSMENU) ? get_win_sys_menu( UserHMGetHandle(pWnd) ) : IntGetMenu( UserHMGetHandle(pWnd) );
|
||||
MENU_TrackMenu(pMenu, wFlags, pt.x, pt.y, pWnd);
|
||||
MENU_TrackMenu(pMenu, wFlags, pt.x, pt.y, pWnd, NULL);
|
||||
MENU_ExitTracking(pWnd, FALSE, wFlags);
|
||||
}
|
||||
}
|
||||
|
@ -4544,7 +4410,7 @@ VOID MENU_TrackKbdMenuBar(PWND pwnd, UINT wParam, WCHAR wChar)
|
|||
}
|
||||
|
||||
track_menu:
|
||||
MENU_TrackMenu( TrackMenu, wFlags, 0, 0, pwnd );
|
||||
MENU_TrackMenu( TrackMenu, wFlags, 0, 0, pwnd, NULL );
|
||||
MENU_ExitTracking( pwnd, FALSE, wFlags);
|
||||
}
|
||||
|
||||
|
@ -4586,8 +4452,9 @@ BOOL WINAPI IntTrackPopupMenuEx( PMENU menu, UINT wFlags, int x, int y,
|
|||
if (menu->fFlags & MNF_SYSMENU)
|
||||
MENU_InitSysMenuPopup( menu, pWnd->style, pWnd->pcls->style, HTSYSMENU);
|
||||
|
||||
if (MENU_ShowPopup(pWnd, menu, 0, wFlags | TPM_POPUPMENU, x, y, lpTpm ? &lpTpm->rcExclude : NULL))
|
||||
ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, pWnd);
|
||||
if (MENU_ShowPopup(pWnd, menu, 0, wFlags, x, y, 0, 0 ))
|
||||
ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, pWnd,
|
||||
lpTpm ? &lpTpm->rcExclude : NULL);
|
||||
else
|
||||
{
|
||||
MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL);
|
||||
|
|
Loading…
Reference in a new issue