diff options
author | Simon Long <simon@raspberrypi.org> | 2015-07-08 18:02:50 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-07-09 15:07:24 +0000 |
commit | 74407aef94b6d8dfdd69891c4a6e578587ef3e71 (patch) | |
tree | cc8c8f9cde981f90760cb7fdaa02688713989f83 | |
parent | 40ade8d04380083e383d6a6e50e5c254fcde2b2f (diff) |
tdf#92630 Enable auto-accelerator behaviour for gtk
Change-Id: I671177dd1f9e535c28a29bcbd6b74f1c789371ea
Reviewed-on: https://gerrit.libreoffice.org/16883
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/vcl/ctrl.hxx | 3 | ||||
-rw-r--r-- | include/vcl/dialog.hxx | 1 | ||||
-rw-r--r-- | include/vcl/layout.hxx | 1 | ||||
-rw-r--r-- | include/vcl/menu.hxx | 2 | ||||
-rw-r--r-- | include/vcl/outdev.hxx | 41 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 2 | ||||
-rw-r--r-- | vcl/source/app/svdata.cxx | 2 | ||||
-rw-r--r-- | vcl/source/control/button.cxx | 5 | ||||
-rw-r--r-- | vcl/source/control/ctrl.cxx | 29 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 9 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 30 | ||||
-rw-r--r-- | vcl/source/window/menu.cxx | 41 | ||||
-rw-r--r-- | vcl/source/window/menubarwindow.cxx | 36 | ||||
-rw-r--r-- | vcl/source/window/menubarwindow.hxx | 6 | ||||
-rw-r--r-- | vcl/source/window/menufloatingwindow.cxx | 10 | ||||
-rw-r--r-- | vcl/source/window/syswin.cxx | 13 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 11 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 21 | ||||
-rw-r--r-- | vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 9 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalframe.cxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx | 2 |
21 files changed, 224 insertions, 52 deletions
diff --git a/include/vcl/ctrl.hxx b/include/vcl/ctrl.hxx index 69a3569a0b5e..b85f561ce254 100644 --- a/include/vcl/ctrl.hxx +++ b/include/vcl/ctrl.hxx @@ -43,6 +43,7 @@ private: bool mbHasControlFocus; bool mbFont; bool mbForeground; + bool mbShowAccelerator; Link<> maGetFocusHdl; Link<> maLoseFocusHdl; @@ -184,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 8afe77480082..aae1dccbbda1 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 fc9eb56faa6a..7d67230ba363 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 2a4abcf3052a..479849f608bc 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 3e73b313c530..8f39b2febe13 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 214066bb9e87..4be003e2848c 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -280,6 +280,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 8b1a2a60e380..9c2cde1c31b1 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -84,6 +84,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 0c330d6d88ea..ca27059e68b1 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 21056db4c58f..59d3389bc47a 100644 --- a/vcl/source/control/ctrl.cxx +++ b/vcl/source/control/ctrl.cxx @@ -38,6 +38,7 @@ void Control::ImplInitControlData() mbHasControlFocus = false; mbFont = false; mbForeground = false; + mbShowAccelerator = false; mpControlData = new ImplControlData; } @@ -379,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 ) @@ -442,15 +453,27 @@ void Control::ImplInitSettings(const bool _bFont, const bool _bForeground) 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 69e957ecb6eb..51ca684bba20 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -2230,6 +2230,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; @@ -2266,7 +2269,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 ); @@ -2278,7 +2282,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 b6679d10189b..5f3acda65a3c 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(InvalidateFlags::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 cb836371d077..543f259f6cd9 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(InvalidateFlags::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 e6fe6461c023..602366f70d63 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(InvalidateFlags::Update); ChangeHighlightItem( nEntry, true ); bDone = true; } diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx index 23d87415a37f..579e03b687f1 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 065b9dcec388..4dbd276a8303 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 c08a60168a93..2ec48b30bc85 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 199888a1141a..fc35c6f48457 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -1919,6 +1919,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 c1b31962b6a5..280db2325733 100644 --- a/vcl/source/window/winproc.cxx +++ b/vcl/source/window/winproc.cxx @@ -2165,17 +2165,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 89c0f62c9d11..77cac74cef88 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -563,6 +563,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 9a33d777f50e..5496bf6e6f37 100644 --- a/vcl/unx/gtk/window/gtksalframe.cxx +++ b/vcl/unx/gtk/window/gtksalframe.cxx @@ -3935,7 +3935,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; @@ -3996,6 +3995,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 9fa1f7e6c2c8..f66d731455c0 100644 --- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx @@ -1933,6 +1933,8 @@ void GtkData::initNWF() pSVData->maNWFData.mbCanDrawWidgetAnySize = true; pSVData->maNWFData.mbDDListBoxNoTextArea = true; pSVData->maNWFData.mbNoFocusRects = true; + pSVData->maNWFData.mbAutoAccel = true; + pSVData->maNWFData.mbEnableAccel = true; } void GtkData::deInitNWF() |