summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2017-05-05 01:30:30 +0300
committerMaxim Monastirsky <momonasmon@gmail.com>2017-05-05 11:27:33 +0200
commitfe0451259d2fb93c809c1bfa3baf5abd90019c58 (patch)
treebf9739d56ffbe6e8b291ea5ee399d2cf315faa2b
parente3a44cbb1d01a1fe5e6321b29e215f4a13ddee6a (diff)
tdf#103158 ctrl+shift should work on key up
Under gtk/gtk3 we send CommandEventId::ModKeyChange on key down, to support the auto-accelerator feature. But at least the handler in SwEditWin::Command must get it on key up, in order to not interfere with other ctrl+shift+X shortcuts, which work on key down. To achieve that, we need: - On key up pass the key that was just released, instead of the current state of nothing being pressed. - Have a flag of whether it's a key down or up event, so it can be checked by the application code. Change-Id: If188d6ccdc3b214a2c3ed20aad291d74d46b358f Reviewed-on: https://gerrit.libreoffice.org/37275 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
-rw-r--r--include/vcl/commandevent.hxx4
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx2
-rw-r--r--vcl/inc/salwtype.hxx1
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx1
-rw-r--r--vcl/source/window/commandevent.cxx3
-rw-r--r--vcl/source/window/menu.cxx2
-rw-r--r--vcl/source/window/syswin.cxx2
-rw-r--r--vcl/source/window/winproc.cxx2
-rw-r--r--vcl/unx/generic/window/salframe.cxx1
-rw-r--r--vcl/unx/gtk/gtksalframe.cxx32
-rw-r--r--vcl/unx/gtk3/gtk3gtkframe.cxx32
-rw-r--r--vcl/win/window/salframe.cxx1
12 files changed, 30 insertions, 53 deletions
diff --git a/include/vcl/commandevent.hxx b/include/vcl/commandevent.hxx
index 4113975de118..7b143e402ce4 100644
--- a/include/vcl/commandevent.hxx
+++ b/include/vcl/commandevent.hxx
@@ -188,11 +188,13 @@ public:
class VCL_DLLPUBLIC CommandModKeyData
{
private:
+ bool mbDown;
ModKeyFlags mnCode;
public:
- CommandModKeyData( ModKeyFlags nCode );
+ CommandModKeyData( ModKeyFlags nCode, bool bDown );
+ bool IsDown() const { return mbDown; }
bool IsMod1() const { return bool(mnCode & ModKeyFlags::Mod1Msk); }
bool IsMod2() const { return bool(mnCode & ModKeyFlags::Mod2Msk); }
bool IsLeftShift() const { return bool(mnCode & ModKeyFlags::LeftShift); }
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 6e3ff6ca55ab..4645376d7223 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5480,7 +5480,7 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
case CommandEventId::ModKeyChange :
{
const CommandModKeyData* pCommandData = rCEvt.GetModKeyData();
- if (pCommandData->IsMod1() && !pCommandData->IsMod2())
+ if (!pCommandData->IsDown() && pCommandData->IsMod1() && !pCommandData->IsMod2())
{
sal_uInt16 nSlot = 0;
if(pCommandData->IsLeftShift() && !pCommandData->IsRightShift())
diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx
index 316165f3d44c..168185913880 100644
--- a/vcl/inc/salwtype.hxx
+++ b/vcl/inc/salwtype.hxx
@@ -122,6 +122,7 @@ struct SalMenuEvent
// KEYMODCHANGE
struct SalKeyModEvent
{
+ bool mbDown; // Whether the change occurred on a key down event
sal_uInt64 mnTime; // Time in ms, when event is created
sal_uInt16 mnCode; // SV-Modifiercode (KEY_SHIFT|KEY_MOD1|KEY_MOD2)
ModKeyFlags mnModKeyCode; // extended Modifier (MODKEY_LEFT,MODKEY_RIGHT,MODKEY_PRESS,MODKEY_RELEASE)
diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 5ab7296081b0..00a687422f82 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -195,7 +195,6 @@ class GtkSalFrame : public SalFrame
bool m_bSpanMonitorsWhenFullscreen;
bool m_bDefaultPos;
bool m_bDefaultSize;
- bool m_bSendModChangeOnRelease;
bool m_bWindowIsGtkPlug;
OUString m_aTitle;
OUString m_sWMClass;
diff --git a/vcl/source/window/commandevent.cxx b/vcl/source/window/commandevent.cxx
index bb00c312c86b..b9525ac3a3fb 100644
--- a/vcl/source/window/commandevent.cxx
+++ b/vcl/source/window/commandevent.cxx
@@ -91,8 +91,9 @@ CommandScrollData::CommandScrollData( long nDeltaX, long nDeltaY )
mnDeltaY = nDeltaY;
}
-CommandModKeyData::CommandModKeyData( ModKeyFlags nCode )
+CommandModKeyData::CommandModKeyData( ModKeyFlags nCode, bool bDown )
{
+ mbDown = bDown;
mnCode = nCode;
}
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 538ff1422366..77b48ad3c9d7 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2493,7 +2493,7 @@ bool MenuBar::ImplHandleCmdEvent( const CommandEvent& rCEvent )
const CommandModKeyData* pCData = rCEvent.GetModKeyData ();
if (pWin->nHighlightedItem == ITEMPOS_INVALID)
{
- if (pCData && pCData->IsMod2())
+ if (pCData && pCData->IsMod2() && pCData->IsDown())
pWin->SetMBWHideAccel(false);
else
pWin->SetMBWHideAccel(true);
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index f760e5f9f263..63bf29ba9950 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -162,7 +162,7 @@ bool Accelerator::ToggleMnemonicsOnHierarchy(const CommandEvent& rCEvent, vcl::W
if (rCEvent.GetCommand() == CommandEventId::ModKeyChange && ImplGetSVData()->maNWFData.mbAutoAccel)
{
const CommandModKeyData *pCData = rCEvent.GetModKeyData();
- const bool bShowAccel = pCData && pCData->IsMod2();
+ const bool bShowAccel = pCData && pCData->IsMod2() && pCData->IsDown();
processChildren(pWindow, bShowAccel);
return true;
}
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index a984f1c277ac..cc7798a042a7 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -2094,7 +2094,7 @@ static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent* pEvent )
if ( !pChild )
return;
- CommandModKeyData data( pEvent->mnModKeyCode );
+ CommandModKeyData data( pEvent->mnModKeyCode, pEvent->mbDown );
ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
}
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 4667d4076c7f..9f5c6905ed43 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -3101,6 +3101,7 @@ long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent )
|| nKeySym == XK_Super_L || nKeySym == XK_Super_R )
{
SalKeyModEvent aModEvt;
+ aModEvt.mbDown = false; // auto-accelerator feature not supported here.
aModEvt.mnModKeyCode = ModKeyFlags::NONE;
if( pEvent->type == KeyPress && mnExtKeyMod == ModKeyFlags::NONE )
mbSendExtKeyModChange = true;
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 07d81cd39751..f97a429af72f 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -970,7 +970,6 @@ void GtkSalFrame::InitCommon()
m_bSpanMonitorsWhenFullscreen = false;
m_nState = GDK_WINDOW_STATE_WITHDRAWN;
m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED;
- m_bSendModChangeOnRelease = false;
m_pIMHandler = nullptr;
m_pRegion = nullptr;
m_ePointerStyle = static_cast<PointerStyle>(0xffff);
@@ -2980,10 +2979,7 @@ gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer f
pSalInstance->updatePrinterUpdate();
if( !pEvent->in )
- {
pThis->m_nKeyModifiers = ModKeyFlags::NONE;
- pThis->m_bSendModChangeOnRelease = false;
- }
if( pThis->m_pIMHandler )
pThis->m_pIMHandler->focusChanged( pEvent->in );
@@ -3096,20 +3092,7 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
pEvent->keyval == GDK_KEY_Meta_L || pEvent->keyval == GDK_KEY_Meta_R ||
pEvent->keyval == GDK_KEY_Super_L || pEvent->keyval == GDK_KEY_Super_R )
{
- SalKeyModEvent aModEvt;
-
sal_uInt16 nModCode = GetKeyModCode( pEvent->state );
-
- aModEvt.mnModKeyCode = ModKeyFlags::NONE; // emit no MODKEYCHANGE events
- if( pEvent->type == GDK_KEY_PRESS && pThis->m_nKeyModifiers == ModKeyFlags::NONE )
- pThis->m_bSendModChangeOnRelease = true;
-
- else if( pEvent->type == GDK_KEY_RELEASE &&
- pThis->m_bSendModChangeOnRelease )
- {
- aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
- }
-
ModKeyFlags nExtModMask = ModKeyFlags::NONE;
sal_uInt16 nModMask = 0;
// pressing just the ctrl key leads to a keysym of XK_Control but
@@ -3155,8 +3138,15 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
nModMask = KEY_MOD3;
break;
}
+
+ SalKeyModEvent aModEvt;
+ aModEvt.mbDown = pEvent->type == GDK_KEY_PRESS;
+ aModEvt.mnTime = pEvent->time;
+ aModEvt.mnCode = nModCode;
+
if( pEvent->type == GDK_KEY_RELEASE )
{
+ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
nModCode &= ~nModMask;
pThis->m_nKeyModifiers &= ~nExtModMask;
}
@@ -3164,14 +3154,10 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
{
nModCode |= nModMask;
pThis->m_nKeyModifiers |= nExtModMask;
+ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
}
- aModEvt.mnCode = nModCode;
- aModEvt.mnTime = pEvent->time;
- aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
-
pThis->CallCallback( SalEvent::KeyModChange, &aModEvt );
-
}
else
{
@@ -3184,7 +3170,7 @@ gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame
(pEvent->type == GDK_KEY_PRESS),
false );
if( ! aDel.isDeleted() )
- pThis->m_bSendModChangeOnRelease = false;
+ pThis->m_nKeyModifiers = ModKeyFlags::NONE;
}
if( !aDel.isDeleted() && pThis->m_pIMHandler )
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 4de9d457fe60..5a8b5e89a74c 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -1077,7 +1077,6 @@ void GtkSalFrame::InitCommon()
m_bSpanMonitorsWhenFullscreen = false;
m_nState = GDK_WINDOW_STATE_WITHDRAWN;
m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED;
- m_bSendModChangeOnRelease = false;
m_pIMHandler = nullptr;
m_pRegion = nullptr;
m_pDropTarget = nullptr;
@@ -2982,10 +2981,7 @@ gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer f
pSalInstance->updatePrinterUpdate();
if( !pEvent->in )
- {
pThis->m_nKeyModifiers = ModKeyFlags::NONE;
- pThis->m_bSendModChangeOnRelease = false;
- }
if( pThis->m_pIMHandler )
pThis->m_pIMHandler->focusChanged( pEvent->in );
@@ -3049,20 +3045,7 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
pEvent->keyval == GDK_KEY_Meta_L || pEvent->keyval == GDK_KEY_Meta_R ||
pEvent->keyval == GDK_KEY_Super_L || pEvent->keyval == GDK_KEY_Super_R )
{
- SalKeyModEvent aModEvt;
-
sal_uInt16 nModCode = GetKeyModCode( pEvent->state );
-
- aModEvt.mnModKeyCode = ModKeyFlags::NONE; // emit no MODKEYCHANGE events
- if( pEvent->type == GDK_KEY_PRESS && pThis->m_nKeyModifiers == ModKeyFlags::NONE )
- pThis->m_bSendModChangeOnRelease = true;
-
- else if( pEvent->type == GDK_KEY_RELEASE &&
- pThis->m_bSendModChangeOnRelease )
- {
- aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
- }
-
ModKeyFlags nExtModMask = ModKeyFlags::NONE;
sal_uInt16 nModMask = 0;
// pressing just the ctrl key leads to a keysym of XK_Control but
@@ -3108,8 +3091,15 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
nModMask = KEY_MOD3;
break;
}
+
+ SalKeyModEvent aModEvt;
+ aModEvt.mbDown = pEvent->type == GDK_KEY_PRESS;
+ aModEvt.mnTime = pEvent->time;
+ aModEvt.mnCode = nModCode;
+
if( pEvent->type == GDK_KEY_RELEASE )
{
+ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
nModCode &= ~nModMask;
pThis->m_nKeyModifiers &= ~nExtModMask;
}
@@ -3117,14 +3107,10 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
{
nModCode |= nModMask;
pThis->m_nKeyModifiers |= nExtModMask;
+ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
}
- aModEvt.mnCode = nModCode;
- aModEvt.mnTime = pEvent->time;
- aModEvt.mnModKeyCode = pThis->m_nKeyModifiers;
-
pThis->CallCallbackExc( SalEvent::KeyModChange, &aModEvt );
-
}
else
{
@@ -3137,7 +3123,7 @@ gboolean GtkSalFrame::signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointe
(pEvent->type == GDK_KEY_PRESS),
false );
if( ! aDel.isDeleted() )
- pThis->m_bSendModChangeOnRelease = false;
+ pThis->m_nKeyModifiers = ModKeyFlags::NONE;
}
if( !aDel.isDeleted() && pThis->m_pIMHandler )
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 75cfacde11ac..3fafe257b4fe 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -3475,6 +3475,7 @@ static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg,
if ( (wParam == VK_SHIFT) || (wParam == VK_CONTROL) || (wParam == VK_MENU) )
{
SalKeyModEvent aModEvt;
+ aModEvt.mbDown = false; // auto-accelerator feature not supported here.
aModEvt.mnTime = GetMessageTime();
aModEvt.mnCode = nModCode;
aModEvt.mnModKeyCode = ModKeyFlags::NONE; // no command events will be sent if this member is 0