summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Long <simon@raspberrypi.org>2015-07-08 18:02:50 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-07-09 15:07:24 +0000
commit74407aef94b6d8dfdd69891c4a6e578587ef3e71 (patch)
treecc8c8f9cde981f90760cb7fdaa02688713989f83
parent40ade8d04380083e383d6a6e50e5c254fcde2b2f (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.hxx3
-rw-r--r--include/vcl/dialog.hxx1
-rw-r--r--include/vcl/layout.hxx1
-rw-r--r--include/vcl/menu.hxx2
-rw-r--r--include/vcl/outdev.hxx41
-rw-r--r--vcl/inc/svdata.hxx2
-rw-r--r--vcl/source/app/svdata.cxx2
-rw-r--r--vcl/source/control/button.cxx5
-rw-r--r--vcl/source/control/ctrl.cxx29
-rw-r--r--vcl/source/outdev/text.cxx9
-rw-r--r--vcl/source/window/dialog.cxx30
-rw-r--r--vcl/source/window/menu.cxx41
-rw-r--r--vcl/source/window/menubarwindow.cxx36
-rw-r--r--vcl/source/window/menubarwindow.hxx6
-rw-r--r--vcl/source/window/menufloatingwindow.cxx10
-rw-r--r--vcl/source/window/syswin.cxx13
-rw-r--r--vcl/source/window/window.cxx11
-rw-r--r--vcl/source/window/winproc.cxx21
-rw-r--r--vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx9
-rw-r--r--vcl/unx/gtk/window/gtksalframe.cxx2
-rw-r--r--vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx2
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()