Blame SOURCES/0001-Resolves-rhbz-1021915-force-menubar-menus-to-be-up-d.patch

2135ec
From 0881ae68b0d7f977003e0798e52548caa2556f44 Mon Sep 17 00:00:00 2001
2135ec
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
2135ec
Date: Tue, 29 Oct 2013 16:10:18 +0000
2135ec
Subject: [PATCH] Resolves: rhbz#1021915 force menubar menus to be up/down only
2135ec
2135ec
If a menu won't fit in the desired location the default mode is to place it
2135ec
somewhere it will fit.  e.g. above, left, right. For some cases, e.g. menubars,
2135ec
it's desirable to limit the options to above/below and force the menu to scroll
2135ec
if it won't fit
2135ec
2135ec
Change-Id: I1998a842d25752389ec9032e54673408d1ed6cb5
2135ec
---
2135ec
 include/vcl/floatwin.hxx   |  1 +
2135ec
 include/vcl/menu.hxx       | 17 +++++++++++------
2135ec
 vcl/source/window/menu.cxx | 34 ++++++++++++++++++++++++++++------
2135ec
 3 files changed, 40 insertions(+), 12 deletions(-)
2135ec
2135ec
diff --git a/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx
2135ec
index 4e2f97c..9a9dbdc 100644
2135ec
--- a/include/vcl/floatwin.hxx
2135ec
+++ b/include/vcl/floatwin.hxx
2135ec
@@ -48,6 +48,7 @@ class ToolBox;
2135ec
 #define FLOATWIN_POPUPMODE_NEWLEVEL             ((sal_uLong)0x00008000)
2135ec
 #define FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE       ((sal_uLong)0x00010000)
2135ec
 #define FLOATWIN_POPUPMODE_GRABFOCUS            ((sal_uLong)0x00020000)
2135ec
+#define FLOATWIN_POPUPMODE_NOHORZPLACEMENT      ((sal_uLong)0x00040000)
2135ec
 
2135ec
 #define FLOATWIN_POPUPMODEEND_CANCEL            ((sal_uInt16)0x0001)
2135ec
 #define FLOATWIN_POPUPMODEEND_TEAROFF           ((sal_uInt16)0x0002)
2135ec
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
2135ec
index 5579149..637c701 100644
2135ec
--- a/include/vcl/menu.hxx
2135ec
+++ b/include/vcl/menu.hxx
2135ec
@@ -62,12 +62,17 @@ namespace vcl { struct MenuLayoutData; }
2135ec
 #define MENU_APPEND             ((sal_uInt16)0xFFFF)
2135ec
 #define MENU_ITEM_NOTFOUND      ((sal_uInt16)0xFFFF)
2135ec
 
2135ec
-#define POPUPMENU_EXECUTE_DOWN  ((sal_uInt16)0x0001)
2135ec
-#define POPUPMENU_EXECUTE_UP    ((sal_uInt16)0x0002)
2135ec
-#define POPUPMENU_EXECUTE_LEFT  ((sal_uInt16)0x0004)
2135ec
-#define POPUPMENU_EXECUTE_RIGHT ((sal_uInt16)0x0008)
2135ec
-
2135ec
-#define POPUPMENU_NOMOUSEUPCLOSE ((sal_uInt16)0x0010)
2135ec
+#define POPUPMENU_EXECUTE_DOWN     ((sal_uInt16)0x0001)
2135ec
+#define POPUPMENU_EXECUTE_UP       ((sal_uInt16)0x0002)
2135ec
+#define POPUPMENU_EXECUTE_LEFT     ((sal_uInt16)0x0004)
2135ec
+#define POPUPMENU_EXECUTE_RIGHT    ((sal_uInt16)0x0008)
2135ec
+#define POPUPMENU_NOMOUSEUPCLOSE   ((sal_uInt16)0x0010)
2135ec
+//If there isn't enough space to put the menu where it wants
2135ec
+//to go, then they will be autoplaced. Toggle this bit
2135ec
+//on to force menus to be placed either above or below
2135ec
+//the starting rectangle and shrunk to fit and then scroll rather than place
2135ec
+//the menu beside that rectangle
2135ec
+#define POPUPMENU_NOHORZ_PLACEMENT ((sal_uInt16)0x0020)
2135ec
 
2135ec
 #define MENU_FLAG_NOAUTOMNEMONICS       0x0001
2135ec
 #define MENU_FLAG_HIDEDISABLEDENTRIES   0x0002
2135ec
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
2135ec
index f567ba3..6083554 100644
2135ec
--- a/vcl/source/window/menu.cxx
2135ec
+++ b/vcl/source/window/menu.cxx
2135ec
@@ -3581,7 +3581,6 @@
2135ec
 {
2135ec
     ENSURE_OR_RETURN( pExecWindow, "PopupMenu::Execute: need a non-NULL window!", 0 );
2135ec
 
2135ec
-
2135ec
     sal_uLong nPopupModeFlags = 0;
2135ec
     if ( nFlags & POPUPMENU_EXECUTE_DOWN )
2135ec
         nPopupModeFlags = FLOATWIN_POPUPMODE_DOWN;
2135ec
@@ -3597,6 +3596,9 @@
2135ec
     if (nFlags & POPUPMENU_NOMOUSEUPCLOSE )                      // allow popup menus to stay open on mouse button up
2135ec
         nPopupModeFlags |= FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE;    // useful if the menu was opened on mousebutton down (eg toolbox configuration)
2135ec
 
2135ec
+    if (nFlags & POPUPMENU_NOHORZ_PLACEMENT)
2135ec
+        nPopupModeFlags |= FLOATWIN_POPUPMODE_NOHORZPLACEMENT;
2135ec
+
2135ec
     return ImplExecute( pExecWindow, rRect, nPopupModeFlags, 0, sal_False );
2135ec
 }
2135ec
 
2135ec
@@ -3700,17 +3702,37 @@
2135ec
 
2135ec
     Size aSz = ImplCalcSize( pWin );
2135ec
 
2135ec
-    long nMaxHeight = pWin->GetDesktopRectPixel().GetHeight();
2135ec
+    Rectangle aDesktopRect(pWin->GetDesktopRectPixel());
2135ec
     if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
2135ec
     {
2135ec
         Window* pDeskW = pWindow->GetWindow( WINDOW_REALPARENT );
2135ec
         if( ! pDeskW )
2135ec
             pDeskW = pWindow;
2135ec
         Point aDesktopTL( pDeskW->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) );
2135ec
-        nMaxHeight = Application::GetWorkAreaPosSizePixel(
2135ec
-            Application::GetBestScreen( Rectangle( aDesktopTL, aRect.GetSize() ) )
2135ec
-            ).GetHeight();
2135ec
+        aDesktopRect = Application::GetWorkAreaPosSizePixel(
2135ec
+            Application::GetBestScreen( Rectangle( aDesktopTL, aRect.GetSize() ) ));
2135ec
     }
2135ec
+
2135ec
+    long nMaxHeight = aDesktopRect.GetHeight();
2135ec
+
2135ec
+    //rhbz#1021915. If a menu won't fit in the desired location the default
2135ec
+    //mode is to place it somewhere it will fit.  e.g. above, left, right. For
2135ec
+    //some cases, e.g. menubars, it's desirable to limit the options to
2135ec
+    //above/below and force the menu to scroll if it won't fit
2135ec
+    if (nPopupModeFlags & FLOATWIN_POPUPMODE_NOHORZPLACEMENT)
2135ec
+    {
2135ec
+        Window* pRef = pWin;
2135ec
+        if ( pRef->GetParent() )
2135ec
+            pRef = pRef->GetParent();
2135ec
+
2135ec
+        Rectangle devRect(  pRef->OutputToAbsoluteScreenPixel( aRect.TopLeft() ),
2135ec
+                            pRef->OutputToAbsoluteScreenPixel( aRect.BottomRight() ) );
2135ec
+
2135ec
+        long nHeightAbove = devRect.Top() - aDesktopRect.Top();
2135ec
+        long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
2135ec
+        nMaxHeight = std::min(nMaxHeight, std::max(nHeightAbove, nHeightBelow));
2135ec
+    }
2135ec
+
2135ec
     if ( pStartedFrom && pStartedFrom->bIsMenuBar )
2135ec
         nMaxHeight -= pW->GetSizePixel().Height();
2135ec
     sal_Int32 nLeft, nTop, nRight, nBottom;
2135ec
@@ -5345,7 +5367,7 @@
2135ec
             // #99071# do not grab the focus, otherwise it will be restored to the menubar
2135ec
             // when the frame is reactivated later
2135ec
             //GrabFocus();
2135ec
-            pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN, pMenu, bPreSelectFirst );
2135ec
+            pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_NOHORZPLACEMENT, pMenu, bPreSelectFirst );
2135ec
             if ( pActivePopup )
2135ec
             {
2135ec
                 // does not have a window, if aborted before or if there are no entries