Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlibinputkeyboard.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/QLoggingCategory>
6#include <QtGui/private/qguiapplication_p.h>
7#include <QtGui/private/qinputdevicemanager_p.h>
8#include <qpa/qwindowsysteminterface.h>
9#include <libinput.h>
10#if QT_CONFIG(xkbcommon)
11#include <xkbcommon/xkbcommon-keysyms.h>
12#include <xkbcommon/xkbcommon-names.h>
13#include <QtGui/private/qxkbcommon_p.h>
14#endif
15
17
19
20const int REPEAT_DELAY = 500;
21const int REPEAT_RATE = 100;
22
24{
25#if QT_CONFIG(xkbcommon)
26 qCDebug(qLcLibInput) << "Using xkbcommon for key mapping";
27 m_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
28 if (!m_ctx) {
29 qWarning("Failed to create xkb context");
30 return;
31 }
32 m_keymap = xkb_keymap_new_from_names(m_ctx, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS);
33 if (!m_keymap) {
34 qCWarning(qLcLibInput, "Failed to compile keymap");
35 return;
36 }
37 m_state = xkb_state_new(m_keymap);
38 if (!m_state) {
39 qCWarning(qLcLibInput, "Failed to create xkb state");
40 return;
41 }
42
43 m_repeatTimer.setSingleShot(true);
44 connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat);
45#else
46 qCWarning(qLcLibInput) << "xkbcommon not available, not performing key mapping";
47#endif
48}
49
51{
52#if QT_CONFIG(xkbcommon)
53 if (m_state)
54 xkb_state_unref(m_state);
55 if (m_keymap)
56 xkb_keymap_unref(m_keymap);
57 if (m_ctx)
58 xkb_context_unref(m_ctx);
59#endif
60}
61
62void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
63{
64#if QT_CONFIG(xkbcommon)
65 if (!m_ctx || !m_keymap || !m_state)
66 return;
67
68 const uint32_t keycode = libinput_event_keyboard_get_key(e) + 8;
69 const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, keycode);
70 const bool pressed = libinput_event_keyboard_get_key_state(e) == LIBINPUT_KEY_STATE_PRESSED;
71
72 // Modifiers here is the modifier state before the event, i.e. not
73 // including the current key in case it is a modifier. See the XOR
74 // logic in QKeyEvent::modifiers(). ### QTBUG-73826
75 Qt::KeyboardModifiers modifiers = QXkbCommon::modifiers(m_state);
76
78 const int qtkey = QXkbCommon::keysymToQtKey(sym, modifiers, m_state, keycode);
79
80 xkb_state_update_key(m_state, keycode, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
81
82 Qt::KeyboardModifiers modifiersAfterStateChange = QXkbCommon::modifiers(m_state, sym);
83 QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiersAfterStateChange);
84
87 qtkey, modifiers, keycode, sym, modifiers, text);
88
89 if (pressed && xkb_keymap_key_repeats(m_keymap, keycode)) {
90 m_repeatData.qtkey = qtkey;
91 m_repeatData.mods = modifiers;
92 m_repeatData.nativeScanCode = keycode;
93 m_repeatData.virtualKey = sym;
94 m_repeatData.nativeMods = modifiers;
95 m_repeatData.unicodeText = text;
96 m_repeatData.repeatCount = 1;
97 m_repeatTimer.setInterval(REPEAT_DELAY);
98 m_repeatTimer.start();
99 } else if (m_repeatTimer.isActive()) {
100 m_repeatTimer.stop();
101 }
102
103#else
104 Q_UNUSED(e);
105#endif
106}
107
108#if QT_CONFIG(xkbcommon)
109void QLibInputKeyboard::handleRepeat()
110{
112 m_repeatData.qtkey, m_repeatData.mods,
113 m_repeatData.nativeScanCode, m_repeatData.virtualKey, m_repeatData.nativeMods,
114 m_repeatData.unicodeText, true, m_repeatData.repeatCount);
115 m_repeatData.repeatCount += 1;
116 m_repeatTimer.setInterval(REPEAT_RATE);
117 m_repeatTimer.start();
118}
119#endif
120
@ KeyRelease
Definition qcoreevent.h:65
@ KeyPress
Definition qcoreevent.h:64
static QInputDeviceManager * inputDeviceManager()
void processKey(libinput_event_keyboard *e)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
static bool handleExtendedKeyEvent(QWindow *window, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
static QString lookupString(struct xkb_state *state, xkb_keycode_t code)
static Qt::KeyboardModifiers modifiers(struct xkb_state *state, xkb_keysym_t keysym=XKB_KEY_VoidSymbol)
static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
EGLImageKHR int int EGLuint64KHR * modifiers
QString text
Combined button and popup list for selecting options.
const int REPEAT_RATE
QT_BEGIN_NAMESPACE const int REPEAT_DELAY
#define qWarning
Definition qlogging.h:166
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
#define Q_UNUSED(x)
int keycode
Definition qvnc.cpp:140
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)