[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.0' - include/vcl vcl/inc vcl/source vcl/unx

Simon Long simon at raspberrypi.org
Fri Dec 11 13:52:32 PST 2015


 include/vcl/ctrl.hxx                          |    5 +++
 include/vcl/dialog.hxx                        |    1 
 include/vcl/layout.hxx                        |    1 
 include/vcl/menu.hxx                          |    2 +
 include/vcl/outdev.hxx                        |   41 ++++++++++++--------------
 vcl/inc/svdata.hxx                            |    2 +
 vcl/source/app/svdata.cxx                     |    2 +
 vcl/source/control/button.cxx                 |    5 +--
 vcl/source/control/ctrl.cxx                   |   31 +++++++++++++++++--
 vcl/source/outdev/text.cxx                    |    9 ++++-
 vcl/source/window/dialog.cxx                  |   30 +++++++++++++++++++
 vcl/source/window/menu.cxx                    |   41 ++++++++++++++++++++++++++
 vcl/source/window/menubarwindow.cxx           |   36 +++++++++++++++-------
 vcl/source/window/menubarwindow.hxx           |    6 +++
 vcl/source/window/menufloatingwindow.cxx      |   10 +++++-
 vcl/source/window/syswin.cxx                  |   13 ++++++--
 vcl/source/window/window.cxx                  |   11 ++++++
 vcl/source/window/winproc.cxx                 |   21 ++++++++-----
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx      |    9 +++++
 vcl/unx/gtk/window/gtksalframe.cxx            |    2 -
 vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx |    2 +
 21 files changed, 228 insertions(+), 52 deletions(-)

New commits:
commit e982c60bb8ca5d3c3ca66e0810cf459c444aa3aa
Author: Simon Long <simon at raspberrypi.org>
Date:   Wed Jul 8 18:02:50 2015 +0100

    tdf#92630 Enable auto-accelerator behaviour for gtk
    
    Reviewed-on: https://gerrit.libreoffice.org/16883
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    
    Cherry-picked from the
    commit 74407aef94b6d8dfdd69891c4a6e578587ef3e71
    
    Conflicts:
    	include/vcl/ctrl.hxx
    	vcl/source/control/ctrl.cxx
    	vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
    
    Change-Id: I671177dd1f9e535c28a29bcbd6b74f1c789371ea

diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx
index 6741a22..b85f561 100644
--- a/include/vcl/ctrl.hxx
+++ b/include/vcl/ctrl.hxx
@@ -41,6 +41,9 @@ protected:
 
 private:
     bool                    mbHasControlFocus;
+    bool                    mbFont;
+    bool                    mbForeground;
+    bool                    mbShowAccelerator;
     Link<>                  maGetFocusHdl;
     Link<>                  maLoseFocusHdl;
 
@@ -182,6 +185,8 @@ public:
     OutputDevice*   GetReferenceDevice() const;
 
     vcl::Font       GetUnzoomedControlPointFont() const;
+    void            SetShowAccelerator (bool val);
+    bool            GetShowAccelerator (void) const;
 };
 
 #endif // INCLUDED_VCL_CTRL_HXX
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 2dc4cc3..1325231 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -107,6 +107,7 @@ public:
 private:
     bool            ImplStartExecuteModal();
     static void     ImplEndExecuteModal();
+    bool            ImplHandleCmdEvent ( const CommandEvent& rCEvent );
 public:
 
     // Dialog::Execute replacement API
diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 90d0f2d..7e4b6d5 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -786,6 +786,7 @@ inline bool isContainerWindow(const vcl::Window &rWindow)
 {
     WindowType eType = rWindow.GetType();
     return eType == WINDOW_CONTAINER || eType == WINDOW_SCROLLWINDOW ||
+            eType == WINDOW_TABCONTROL || eType == WINDOW_TABPAGE ||
            (eType == WINDOW_DOCKINGWINDOW && ::isLayoutEnabled(&rWindow));
 }
 
diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx
index 2a4abcf..479849f 100644
--- a/include/vcl/menu.hxx
+++ b/include/vcl/menu.hxx
@@ -44,6 +44,7 @@ class HelpEvent;
 class Image;
 class PopupMenu;
 class KeyEvent;
+class CommandEvent;
 class MenuFloatingWindow;
 namespace vcl { class Window; }
 class SalMenu;
@@ -440,6 +441,7 @@ class VCL_DLLPUBLIC MenuBar : public Menu
                                                   MenuBar* pMenu, const css::uno::Reference<css::frame::XFrame> &rFrame);
     SAL_DLLPRIVATE static void ImplDestroy(MenuBar* pMenu, bool bDelete);
     SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent& rKEvent, bool bFromMenu = true);
+    SAL_DLLPRIVATE bool ImplHandleCmdEvent(const CommandEvent& rCEvent);
 
 protected:
 
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index dbd57e6..16723fd 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -160,30 +160,29 @@ typedef std::vector< Rectangle > MetricVector;
 // Flags for DrawText()
 enum class DrawTextFlags
 {
-    NONE                  = 0x0000,
-    Disable               = 0x0001,
-    Mnemonic              = 0x0002,
-    Mono                  = 0x0004,
-    Clip                  = 0x0008,
-    Left                  = 0x0010,
-    Center                = 0x0020,
-    Right                 = 0x0040,
-    Top                   = 0x0080,
-    VCenter               = 0x0100,
-    Bottom                = 0x0200,
-    EndEllipsis           = 0x0400,
-    PathEllipsis          = 0x0800,
-    MultiLine             = 0x1000,
-    WordBreak             = 0x2000,
-    NewsEllipsis          = 0x4000,
-    // in the long run we should make text style flags longer
-    // but at the moment we can get away with this 2 bit field for ellipsis style
-    CenterEllipsis        = EndEllipsis | PathEllipsis,
-    WordBreakHyphenation  = 0x8000 | WordBreak,
+    NONE                  = 0x00000000,
+    Disable               = 0x00000001,
+    Mnemonic              = 0x00000002,
+    Mono                  = 0x00000004,
+    Clip                  = 0x00000008,
+    Left                  = 0x00000010,
+    Center                = 0x00000020,
+    Right                 = 0x00000040,
+    Top                   = 0x00000080,
+    VCenter               = 0x00000100,
+    Bottom                = 0x00000200,
+    EndEllipsis           = 0x00000400,
+    PathEllipsis          = 0x00000800,
+    MultiLine             = 0x00001000,
+    WordBreak             = 0x00002000,
+    NewsEllipsis          = 0x00004000,
+    WordBreakHyphenation  = 0x00008000 | WordBreak,
+    CenterEllipsis        = 0x00010000,
+    HideMnemonic          = 0x00020000,
 };
 namespace o3tl
 {
-    template<> struct typed_flags<DrawTextFlags> : is_typed_flags<DrawTextFlags, 0xffff> {};
+    template<> struct typed_flags<DrawTextFlags> : is_typed_flags<DrawTextFlags, 0x3ffff> {};
 }
 
 // Flags for DrawImage(), these must match the definitions in css::awt::ImageDrawMode
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 5e3282a..46b3f67 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -281,6 +281,8 @@ struct ImplSVNWFData
 
     /// entire drop down listbox resembles a button, no textarea/button parts (as currently on Windows)
     bool                    mbDDListBoxNoTextArea:1;
+    bool                    mbEnableAccel:1;                // whether or not accelerators are shown
+    bool                    mbAutoAccel:1;                  // whether accelerators are only shown when Alt is held down
 };
 
 struct BlendFrameCache
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 71d7628..860c206 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -86,6 +86,8 @@ ImplSVData::ImplSVData()
     memset( this, 0, sizeof( ImplSVData ) );
     maHelpData.mbAutoHelpId = true;
     maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT );
+    maNWFData.mbEnableAccel = 1;
+    maNWFData.mbAutoAccel = 0;
 }
 
 ImplSVGDIData::~ImplSVGDIData()
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index f8820aa..9795aee 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -504,8 +504,9 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
 
     if (bDrawText)
     {
-        ImplSetFocusRect(Rectangle(aTextPos, aTextSize));
-        pDev->DrawText(Rectangle(aTextPos, aTextSize), aText, nTextStyle, pVector, pDisplayText);
+        Rectangle       aTOutRect( aTextPos, aTextSize );
+        ImplSetFocusRect( aTOutRect );
+        DrawControlText( *pDev, aTOutRect, aText, nTextStyle, pVector, pDisplayText );
     }
     else
     {
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index fa7090b..c3c7544 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -36,6 +36,9 @@ using namespace vcl;
 void Control::ImplInitControlData()
 {
     mbHasControlFocus       = false;
+    mbFont                  = false;
+    mbForeground            = false;
+    mbShowAccelerator       = false;
     mpControlData   = new ImplControlData;
 }
 
@@ -377,6 +380,16 @@ void Control::ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect )
     pDev->OutputDevice::SetSettings( aOriginalSettings );
 }
 
+void Control::SetShowAccelerator(bool bVal)
+{
+    mbShowAccelerator = bVal;
+};
+
+bool Control::GetShowAccelerator() const
+{
+    return mbShowAccelerator;
+}
+
 ControlLayoutData::~ControlLayoutData()
 {
     if( m_pParent )
@@ -432,15 +445,27 @@ void Control::ImplInitSettings(const bool, const bool)
 void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const OUString& _rStr,
     DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText ) const
 {
+    OUString rPStr = _rStr;
+    DrawTextFlags nPStyle = _nStyle;
+
+    bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+    bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
+    if (!accel || (autoacc && !mbShowAccelerator))
+    {
+        rPStr = GetNonMnemonicString( _rStr );
+        nPStyle &= ~DrawTextFlags::HideMnemonic;
+    }
+
     if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
     {
-        _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, _rStr, _nStyle );
-        _rTargetDevice.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+        _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, rPStr, nPStyle );
+        _rTargetDevice.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
     }
     else
     {
         ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
-        _io_rRect = aRenderer.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+        _io_rRect = aRenderer.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
     }
 }
 
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 173aa52..17bbb93 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -2242,6 +2242,9 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
         }
     }
 
+    bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+    bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
     if ( nStyle & DrawTextFlags::Disable && ! pVector )
     {
         Color aOldTextColor;
@@ -2278,7 +2281,8 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
             SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
 
         DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText );
-        if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector )
+        if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector
+            && accel && (!autoacc || !(nStyle & DrawTextFlags::HideMnemonic)) )
         {
             if ( nMnemonicPos != -1 )
                 ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
@@ -2290,7 +2294,8 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
     else
     {
         DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText );
-        if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector )
+        if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector
+            && accel && (!autoacc || !(nStyle & DrawTextFlags::HideMnemonic)) )
         {
             if ( nMnemonicPos != -1 )
                 ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 4ce15de..df77652 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -585,6 +585,31 @@ IMPL_LINK_NOARG(Dialog, ImplAsyncCloseHdl)
     return 0;
 }
 
+bool Dialog::ImplHandleCmdEvent( const CommandEvent& rCEvent )
+{
+    if (rCEvent.GetCommand() == CommandEventId::ModKeyChange)
+    {
+        const CommandModKeyData *pCData = rCEvent.GetModKeyData ();
+
+        Window *pGetChild = firstLogicalChildOfParent(this);
+        while (pGetChild)
+        {
+            Control *pControl = dynamic_cast<Control*>(pGetChild->ImplGetWindow());
+            if (pControl && pControl->GetText().indexOf('~') != -1)
+            {
+                if (pCData && pCData->IsMod2())
+                    pControl->SetShowAccelerator(true);
+                else
+                    pControl->SetShowAccelerator(false);
+                pControl->Invalidate(INVALIDATE_UPDATE);
+            }
+            pGetChild = nextLogicalChildOfParent(this, pGetChild);
+        }
+        return true;
+    }
+    return false;
+}
+
 bool Dialog::Notify( NotifyEvent& rNEvt )
 {
     // first call the base class due to Tab control
@@ -628,6 +653,11 @@ bool Dialog::Notify( NotifyEvent& rNEvt )
 
             }
         }
+        else if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
+        {
+            if (ImplHandleCmdEvent( *rNEvt.GetCommandEvent()))
+                return true;
+        }
     }
 
     return nRet;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index cb83637..629b419 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2022,6 +2022,12 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext,
                     aTmpPos.Y() += nTextOffsetY;
                     DrawTextFlags nStyle = nTextStyle | DrawTextFlags::Mnemonic;
 
+                    const Menu *pMenu = this;
+                    while (!pMenu->IsMenuBar() && pMenu->pStartedFrom)
+                        pMenu = pMenu->pStartedFrom;
+                    if (pMenu->IsMenuBar() && (static_cast<MenuBarWindow*>(pMenu->pWindow.get()))->GetMBWHideAccel())
+                        nStyle |= DrawTextFlags::HideMnemonic;
+
                     if (pData->bIsTemporary)
                         nStyle |= DrawTextFlags::Disable;
                     MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
@@ -2602,6 +2608,37 @@ bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
     return bDone;
 }
 
+bool MenuBar::ImplHandleCmdEvent( const CommandEvent& rCEvent )
+{
+    bool bDone = false;
+    const CommandModKeyData* pCData;
+
+    // No keyboard processing when system handles the menu or our menubar is invisible
+    if( !IsDisplayable() ||
+        ( ImplGetSalMenu() && ImplGetSalMenu()->VisibleMenuBar() ) )
+        return bDone;
+
+    // check for enabled, if this method is called from another window...
+    MenuBarWindow* pWin = static_cast<MenuBarWindow*>(ImplGetWindow());
+    if ( pWin && pWin->IsEnabled() && pWin->IsInputEnabled()  && ! pWin->IsInModalMode() )
+    {
+        if (rCEvent.GetCommand() == CommandEventId::ModKeyChange)
+        {
+            pCData = rCEvent.GetModKeyData ();
+            if (pWin->nHighlightedItem == ITEMPOS_INVALID)
+            {
+                if (pCData && pCData->IsMod2())
+                    pWin->SetMBWHideAccel(false);
+                else
+                    pWin->SetMBWHideAccel(true);
+                pWin->Invalidate(INVALIDATE_UPDATE);
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
 void MenuBar::SelectItem(sal_uInt16 nId)
 {
     if (pWindow)
@@ -2886,6 +2923,10 @@ sal_uInt16 PopupMenu::ImplExecute( vcl::Window* pW, const Rectangle& rRect, Floa
     if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) )
         return 0;
 
+    // set the flag to hide or show accelerators in the menu depending on whether the menu was launched by mouse or keyboard shortcut
+    if( pSFrom && pSFrom->IsMenuBar())
+        ((static_cast<MenuBarWindow*>(pSFrom->pWindow.get())))->SetMBWHideAccel(!(static_cast<MenuBarWindow*>(pSFrom->pWindow.get())->GetMBWMenuKey()));
+
     delete mpLayoutData, mpLayoutData = NULL;
 
     ImplSVData* pSVData = ImplGetSVData();
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index fb542a4..99a5adf 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -133,6 +133,7 @@ MenuBarWindow::MenuBarWindow( vcl::Window* pParent ) :
     nSaveFocusId = 0;
     bIgnoreFirstMove = true;
     bStayActive = false;
+    SetMBWHideAccel(true);
 
     ResMgr* pResMgr = ImplGetResMgr();
 
@@ -383,6 +384,7 @@ void MenuBarWindow::PopupClosed( Menu* pPopup )
 void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
 {
     mbAutoPopup = true;
+    SetMBWMenuKey(false);
     sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
     if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup )
     {
@@ -407,7 +409,18 @@ void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
     if ( rMEvt.IsLeaveWindow() )
     {
         if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem )
-            Invalidate(); //HighlightItem( nRolloveredItem, false );
+        {
+            // there is a spurious MouseMove generated after a menu is launched from the keyboard, hence this...
+            if (nHighlightedItem != ITEMPOS_INVALID)
+            {
+                bool hide = GetMBWHideAccel();
+                SetMBWHideAccel(true);
+                Invalidate(); //HighlightItem( nRolloveredItem, false );
+                SetMBWHideAccel(hide);
+            }
+            else
+                Invalidate(); //HighlightItem( nRolloveredItem, false );
+        }
 
         nRolloveredItem = ITEMPOS_INVALID;
         return;
@@ -444,6 +457,9 @@ void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool b
     if( ! pMenu )
         return;
 
+    // always hide accelerators when updating the menu bar...
+    SetMBWHideAccel(true);
+
     // #57934# close active popup if applicable, as TH's background storage works.
     MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
     if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
@@ -824,18 +840,12 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
         {
             if( pActivePopup )
             {
-                // bring focus to menu bar without any open popup
+                // hide the menu and remove the focus...
                 mbAutoPopup = false;
-                sal_uInt16 n = nHighlightedItem;
-                nHighlightedItem = ITEMPOS_INVALID;
-                bStayActive = true;
-                ChangeHighlightItem( n, false );
-                bStayActive = false;
                 KillActivePopup();
-                GrabFocus();
             }
-            else
-                ChangeHighlightItem( ITEMPOS_INVALID, false );
+
+            ChangeHighlightItem( ITEMPOS_INVALID, false );
 
             if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() )
             {
@@ -847,7 +857,8 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
         }
     }
 
-    if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) )
+    bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+    if ( !bDone && ( bFromMenu || (rKEvent.GetKeyCode().IsMod2() && accel) ) )
     {
         sal_Unicode nCharCode = rKEvent.GetCharCode();
         if ( nCharCode )
@@ -857,6 +868,9 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
             if ( pData && (nEntry != ITEMPOS_INVALID) )
             {
                 mbAutoPopup = true;
+                SetMBWMenuKey(true);
+                SetMBWHideAccel(true);
+                Invalidate(INVALIDATE_UPDATE);
                 ChangeHighlightItem( nEntry, true );
                 bDone = true;
             }
diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx
index 0ebb19a..06dbcab 100644
--- a/vcl/source/window/menubarwindow.hxx
+++ b/vcl/source/window/menubarwindow.hxx
@@ -80,6 +80,8 @@ private:
     bool            mbAutoPopup;
     bool            bIgnoreFirstMove;
     bool            bStayActive;
+    bool            mbHideAccel;
+    bool            mbMenuKey;
 
     VclPtr<DecoToolBox>  aCloseBtn;
     VclPtr<PushButton>   aFloatBtn;
@@ -145,6 +147,10 @@ public:
     virtual Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId) SAL_OVERRIDE;
     virtual void RemoveMenuBarButton(sal_uInt16 nId) SAL_OVERRIDE;
     virtual bool HandleMenuButtonEvent(sal_uInt16 i_nButtonId) SAL_OVERRIDE;
+    virtual void SetMBWHideAccel (bool val) { mbHideAccel = val; }
+    virtual bool GetMBWHideAccel (void) const { return mbHideAccel; }
+    virtual void SetMBWMenuKey (bool val) { mbMenuKey = val; }
+    virtual bool GetMBWMenuKey (void) const { return mbMenuKey; }
 };
 
 #endif // INCLUDED_VCL_SOURCE_WINDOW_MENUBARWINDOW_HXX
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx
index 5ff6cc2..edd20a6 100644
--- a/vcl/source/window/menufloatingwindow.cxx
+++ b/vcl/source/window/menufloatingwindow.cxx
@@ -19,6 +19,7 @@
 
 #include "menufloatingwindow.hxx"
 #include "menuitemlist.hxx"
+#include "menubarwindow.hxx"
 
 #include <svdata.hxx>
 #include <vcl/decoview.hxx>
@@ -1108,8 +1109,13 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
             sal_Unicode nCharCode = rKEvent.GetCharCode();
             sal_uInt16 nPos = 0;
             sal_uInt16 nDuplicates = 0;
-            MenuItemData* pData = (nCharCode && pMenu) ? pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem ) : NULL;
-            if ( pData )
+            MenuItemData* pData = (nCharCode && pMenu) ?
+                pMenu->GetItemList()->SearchItem(nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem) : NULL;
+            bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+            Menu *men = pMenu;
+            while (!men->IsMenuBar())
+                men = men->pStartedFrom;
+            if ( pData && (static_cast<MenuBarWindow*>(men->pWindow.get()))->GetMBWMenuKey () && accel )
             {
                 if ( pData->pSubMenu || nDuplicates > 1 )
                 {
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index dcb455d..4c6a6c5 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -126,7 +126,8 @@ void SystemWindow::dispose()
 bool SystemWindow::Notify( NotifyEvent& rNEvt )
 {
     // capture KeyEvents for menu handling
-    if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
+    if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ||
+        rNEvt.GetType() == MouseNotifyEvent::COMMAND)
     {
         MenuBar* pMBar = mpMenuBar;
         if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) )
@@ -135,7 +136,15 @@ bool SystemWindow::Notify( NotifyEvent& rNEvt )
             if( pWin && pWin->IsSystemWindow() )
                 pMBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
         }
-        if ( pMBar && pMBar->ImplHandleKeyEvent( *rNEvt.GetKeyEvent(), false ) )
+        bool bDone(false);
+        if (pMBar)
+        {
+            if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
+                bDone = pMBar->ImplHandleCmdEvent(*rNEvt.GetCommandEvent());
+            else
+                bDone = pMBar->ImplHandleKeyEvent(*rNEvt.GetKeyEvent(), false);
+        }
+        if (bDone)
             return true;
     }
 
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 0a01a14..d8c7846 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1920,6 +1920,17 @@ void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
 
 void Window::KeyInput( const KeyEvent& rKEvt )
 {
+    KeyCode cod = rKEvt.GetKeyCode ();
+    bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+    bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
+    // do not respond to accelerators unless Alt is held */
+    if (cod.GetCode () >= 0x200 && cod.GetCode () <= 0x219)
+    {
+        if (!accel) return;
+        if (autoacc && cod.GetModifier () != 0x4000) return;
+    }
+
     NotifyEvent aNEvt( MouseNotifyEvent::KEYINPUT, this, &rKEvt );
     if ( !CompatNotify( aNEvt ) )
         mpWindowImpl->mbKeyInput = true;
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 304753a..429242f 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -2178,17 +2178,22 @@ static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent* pEvent )
 
     // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
 
-    // find window
-    vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
-    if ( !pChild )
-        return;
+    // find window - first look to see if the system window is available
+    vcl::Window* pChild = pWindow->ImplGetWindowImpl()->mpFirstChild;
 
-    // send modkey events only if useful data is available
-    if( pEvent->mnModKeyCode != 0 )
+    while ( pChild )
     {
-        CommandModKeyData data( pEvent->mnModKeyCode );
-        ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
+        if ( pChild->ImplGetWindowImpl()->mbSysWin )
+            break;
+        pChild = pChild->ImplGetWindowImpl()->mpNext;
     }
+    //...if not, try to find a key input window...
+    if (!pChild) ImplGetKeyInputWindow( pWindow );
+    //...otherwise fail safe...
+    if (!pChild) pChild = pWindow;
+
+    CommandModKeyData data( pEvent->mnModKeyCode );
+    ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
 }
 
 static void ImplHandleInputLanguageChange( vcl::Window* pWindow )
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 1220596..c4913b5 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -565,6 +565,15 @@ void GtkData::initNWF()
     std::fprintf( stderr, "GtkPlugin: using %s NWF\n",
              GtkSalGraphics::bNeedPixmapPaint ? "offscreen" : "direct" );
     #endif
+
+    GtkSettings *gtks = gtk_settings_get_default ();
+    gint val;
+    g_object_get (gtks, "gtk-auto-mnemonics", &val, NULL);
+    if (val) pSVData->maNWFData.mbAutoAccel = true;
+    else pSVData->maNWFData.mbAutoAccel = false;
+    g_object_get (gtks, "gtk-enable-mnemonics", &val, NULL);
+    if (val) pSVData->maNWFData.mbEnableAccel = true;
+    else pSVData->maNWFData.mbEnableAccel = false;
 }
 
 /*********************************************************
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 0e58788..fe41c30 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -4038,7 +4038,6 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
                  pThis->m_bSendModChangeOnRelease )
         {
             aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
-            pThis->m_nKeyModifiers = 0;
         }
 
         sal_uInt16 nExtModMask = 0;
@@ -4099,6 +4098,7 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
 
         aModEvt.mnCode = nModCode;
         aModEvt.mnTime = pEvent->time;
+        aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
 
         pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
 
diff --git a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
index 90d8734..4a71442 100644
--- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx
@@ -1965,6 +1965,8 @@ void GtkData::initNWF()
     pSVData->maNWFData.mbDDListBoxNoTextArea = true;
     pSVData->maNWFData.mbNoFocusRects = true;
     pSVData->maNWFData.mbNoFocusRectsForFlatButtons = true;
+    pSVData->maNWFData.mbAutoAccel = true;
+    pSVData->maNWFData.mbEnableAccel = true;
 }
 
 void GtkData::deInitNWF()


More information about the Libreoffice-commits mailing list