[Libreoffice-commits] core.git: vcl/inc vcl/qt5

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Tue Jul 20 13:20:50 UTC 2021


 vcl/inc/qt5/Qt5Frame.hxx |    1 
 vcl/qt5/Qt5Frame.cxx     |    3 +
 vcl/qt5/Qt5Widget.cxx    |   81 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+)

New commits:
commit 862fdb98ca271b60a831cd5420fd16d5f9c1c747
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Mon Jul 19 15:17:53 2021 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Tue Jul 20 15:20:14 2021 +0200

    tdf#143298 Qt5 send SalEvent::KeyModChange events
    
    I originally omitted this in the Qt implementation, as I couldn't
    find any non-working use case.
    
    The implementation got a bit hacky, because Qt doesn't have a non-
    native way to identify different L/R modifier keys, so we must
    process the X11/xkb keycode ourself, which obviously won't work on
    Wayland... but most times this is not relevant, so the default
    modifier notification may be good enough.
    
    P.S. it's basically the same code then X11 and Gtk...
    
    Change-Id: I37fbfde4a33a966b6017f3e0c280e2c7ea91e4db
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119235
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index f90936528399..ed82c2a7a8fb 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -102,6 +102,7 @@ class VCLPLUG_QT5_PUBLIC Qt5Frame : public QObject, public SalFrame
 
 #if QT5_USING_X11
     ScreenSaverInhibitor m_ScreenSaverInhibitor;
+    ModKeyFlags m_nKeyModifiers;
 #endif
 
     LanguageType m_nInputLanguage;
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 6dc54d9408e3..322f293828cd 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -113,6 +113,9 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
     , m_bDefaultPos(true)
     , m_bFullScreen(false)
     , m_bFullScreenSpanAll(false)
+#if QT5_USING_X11
+    , m_nKeyModifiers(ModKeyFlags::NONE)
+#endif
     , m_nInputLanguage(LANGUAGE_DONTKNOW)
 {
     Qt5Instance* pInst = static_cast<Qt5Instance*>(GetSalData()->m_pInstance);
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index a2bf8fe6472d..2e97132f5e75 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -52,6 +52,11 @@
 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
 
+#if QT5_USING_X11
+#define XK_MISCELLANY
+#include <X11/keysymdef.h>
+#endif
+
 using namespace com::sun::star;
 
 void Qt5Widget::paintEvent(QPaintEvent* pEvent)
@@ -444,6 +449,82 @@ bool Qt5Widget::handleKeyEvent(Qt5Frame& rFrame, const QWidget& rWidget, QKeyEve
         return true;
     }
 
+    if (nCode == 0)
+    {
+        sal_uInt16 nModCode = GetKeyModCode(pEvent->modifiers());
+        SalKeyModEvent aModEvt;
+        aModEvt.mbDown = eState == ButtonKeyState::Pressed;
+        aModEvt.mnModKeyCode = ModKeyFlags::NONE;
+
+#if QT5_USING_X11
+        if (QGuiApplication::platformName() == "xcb")
+        {
+            // pressing just the ctrl key leads to a keysym of XK_Control but
+            // the event state does not contain ControlMask. In the release
+            // event it's the other way round: it does contain the Control mask.
+            // The modifier mode therefore has to be adapted manually.
+            ModKeyFlags nExtModMask = ModKeyFlags::NONE;
+            sal_uInt16 nModMask = 0;
+            switch (pEvent->nativeVirtualKey())
+            {
+                case XK_Control_L:
+                    nExtModMask = ModKeyFlags::LeftMod1;
+                    nModMask = KEY_MOD1;
+                    break;
+                case XK_Control_R:
+                    nExtModMask = ModKeyFlags::RightMod1;
+                    nModMask = KEY_MOD1;
+                    break;
+                case XK_Alt_L:
+                    nExtModMask = ModKeyFlags::LeftMod2;
+                    nModMask = KEY_MOD2;
+                    break;
+                case XK_Alt_R:
+                    nExtModMask = ModKeyFlags::RightMod2;
+                    nModMask = KEY_MOD2;
+                    break;
+                case XK_Shift_L:
+                    nExtModMask = ModKeyFlags::LeftShift;
+                    nModMask = KEY_SHIFT;
+                    break;
+                case XK_Shift_R:
+                    nExtModMask = ModKeyFlags::RightShift;
+                    nModMask = KEY_SHIFT;
+                    break;
+                // Map Meta/Super keys to MOD3 modifier on all Unix systems
+                // except macOS
+                case XK_Meta_L:
+                case XK_Super_L:
+                    nExtModMask = ModKeyFlags::LeftMod3;
+                    nModMask = KEY_MOD3;
+                    break;
+                case XK_Meta_R:
+                case XK_Super_R:
+                    nExtModMask = ModKeyFlags::RightMod3;
+                    nModMask = KEY_MOD3;
+                    break;
+            }
+
+            if (eState == ButtonKeyState::Released)
+            {
+                aModEvt.mnModKeyCode = rFrame.m_nKeyModifiers;
+                nModCode &= ~nModMask;
+                rFrame.m_nKeyModifiers &= ~nExtModMask;
+            }
+            else
+            {
+                nModCode |= nModMask;
+                rFrame.m_nKeyModifiers |= nExtModMask;
+                aModEvt.mnModKeyCode = rFrame.m_nKeyModifiers;
+            }
+        }
+#endif
+        aModEvt.mnCode = nModCode;
+
+        rFrame.CallCallback(SalEvent::KeyModChange, &aModEvt);
+        return false;
+    }
+
     SalKeyEvent aEvent;
     aEvent.mnCharCode = (pEvent->text().isEmpty() ? 0 : pEvent->text().at(0).unicode());
     aEvent.mnRepeat = 0;


More information about the Libreoffice-commits mailing list