[0.4.11] [WIN32K:NTUSER] Do not try to reposition an off-screen menu

as if it were a popup menu #1360

fixes regression CORE-15733
Many thanks to the patches author Mark Jansen!

The fix has not been merged to master to date, but will most likely be merged
there as well before branching releases/0.4.12
This commit is contained in:
Joachim Henze 2019-02-16 16:33:54 +01:00
parent 5e059e71c8
commit a9be77c640

View file

@ -2858,16 +2858,17 @@ static BOOL MENU_InitPopup( PWND pWndOwner, PMENU menu, UINT flags )
* Display a popup menu. * Display a popup menu.
*/ */
static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT flags, static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT flags,
INT x, INT y, INT xanchor, INT yanchor ) INT x, INT y)
{ {
UINT width, height; UINT width, height;
POINT pt; POINT pt;
PMONITOR monitor; PMONITOR monitor;
PWND pWnd; PWND pWnd;
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
BOOL bIsPopup = (flags & TPM_POPUPMENU) != 0;
TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n", TRACE("owner=%p menu=%p id=0x%04x x=0x%04x y=0x%04x\n",
pwndOwner, menu, id, x, y, xanchor, yanchor); pwndOwner, menu, id, x, y);
if (menu->iItem != NO_SELECTED_ITEM) if (menu->iItem != NO_SELECTED_ITEM)
{ {
@ -2888,7 +2889,7 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
pt.y = y; pt.y = y;
monitor = UserMonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ); monitor = UserMonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
if (flags & TPM_LAYOUTRTL) if (flags & TPM_LAYOUTRTL)
flags ^= TPM_RIGHTALIGN; flags ^= TPM_RIGHTALIGN;
if( flags & TPM_RIGHTALIGN ) x -= width; if( flags & TPM_RIGHTALIGN ) x -= width;
@ -2899,14 +2900,11 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
if( x + width > monitor->rcMonitor.right) if( x + width > monitor->rcMonitor.right)
{ {
if( xanchor && x >= width - xanchor )
x -= width - xanchor;
if( x + width > monitor->rcMonitor.right) if( x + width > monitor->rcMonitor.right)
{ {
/* If we would flip around our origin, would we go off screen on the other side? /* 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? */ Or is our origin itself too far to the right already? */
if (x - width < monitor->rcMonitor.left || x > monitor->rcMonitor.right) if (!bIsPopup || x - width < monitor->rcMonitor.left || x > monitor->rcMonitor.right)
x = monitor->rcMonitor.right - width; x = monitor->rcMonitor.right - width;
else else
x -= width; x -= width;
@ -2915,7 +2913,7 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
if( x < monitor->rcMonitor.left ) if( x < monitor->rcMonitor.left )
{ {
/* If we would flip around our origin, would we go off screen on the other side? */ /* If we would flip around our origin, would we go off screen on the other side? */
if (x + width > monitor->rcMonitor.right) if (!bIsPopup || x + width > monitor->rcMonitor.right)
x = monitor->rcMonitor.left; x = monitor->rcMonitor.left;
else else
x += width; x += width;
@ -2923,14 +2921,11 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
if( y + height > monitor->rcMonitor.bottom) if( y + height > monitor->rcMonitor.bottom)
{ {
if( yanchor && y >= height + yanchor )
y -= height + yanchor;
if( y + height > monitor->rcMonitor.bottom) if( y + height > monitor->rcMonitor.bottom)
{ {
/* If we would flip around our origin, would we go off screen on the other side? /* 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? */ Or is our origin itself too far to the bottom already? */
if (y - height < monitor->rcMonitor.top || y > monitor->rcMonitor.bottom) if (!bIsPopup || y - height < monitor->rcMonitor.top || y > monitor->rcMonitor.bottom)
y = monitor->rcMonitor.bottom - height; y = monitor->rcMonitor.bottom - height;
else else
y -= height; y -= height;
@ -2939,7 +2934,7 @@ static BOOL FASTCALL MENU_ShowPopup(PWND pwndOwner, PMENU menu, UINT id, UINT fl
if( y < monitor->rcMonitor.top ) if( y < monitor->rcMonitor.top )
{ {
/* If we would flip around our origin, would we go off screen on the other side? */ /* If we would flip around our origin, would we go off screen on the other side? */
if (y + height > monitor->rcMonitor.bottom) if (!bIsPopup || y + height > monitor->rcMonitor.bottom)
y = monitor->rcMonitor.top; y = monitor->rcMonitor.top;
else else
y += height; y += height;
@ -3302,7 +3297,7 @@ static PMENU FASTCALL MENU_ShowSubPopup(PWND WndOwner, PMENU Menu, BOOL SelectFi
MENU_InitPopup( WndOwner, Item->spSubMenu, Flags ); MENU_InitPopup( WndOwner, Item->spSubMenu, Flags );
MENU_ShowPopup( WndOwner, Item->spSubMenu, Menu->iItem, Flags, MENU_ShowPopup( WndOwner, Item->spSubMenu, Menu->iItem, Flags,
Rect.left, Rect.top, Rect.right, Rect.bottom ); Rect.left, Rect.top);
if (SelectFirst) if (SelectFirst)
{ {
MENU_MoveSelection(WndOwner, Item->spSubMenu, ITEM_NEXT); MENU_MoveSelection(WndOwner, Item->spSubMenu, ITEM_NEXT);
@ -4444,7 +4439,7 @@ BOOL WINAPI IntTrackPopupMenuEx( PMENU menu, UINT wFlags, int x, int y,
if (menu->fFlags & MNF_SYSMENU) if (menu->fFlags & MNF_SYSMENU)
MENU_InitSysMenuPopup( menu, pWnd->style, pWnd->pcls->style, HTSYSMENU); MENU_InitSysMenuPopup( menu, pWnd->style, pWnd->pcls->style, HTSYSMENU);
if (MENU_ShowPopup(pWnd, menu, 0, wFlags, x, y, 0, 0 )) if (MENU_ShowPopup(pWnd, menu, 0, wFlags | TPM_POPUPMENU, x, y))
ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, pWnd, ret = MENU_TrackMenu( menu, wFlags | TPM_POPUPMENU, 0, 0, pWnd,
lpTpm ? &lpTpm->rcExclude : NULL); lpTpm ? &lpTpm->rcExclude : NULL);
else else