mirror of
https://github.com/danog/patches.git
synced 2024-11-30 04:19:34 +01:00
2317 lines
108 KiB
Diff
2317 lines
108 KiB
Diff
diff --git a/src/platformsupport/input/input-support.pro b/src/platformsupport/input/input-support.pro
|
|
new file mode 100644
|
|
index 0000000000..3d39210b9e
|
|
--- /dev/null
|
|
+++ b/src/platformsupport/input/input-support.pro
|
|
@@ -0,0 +1,35 @@
|
|
+TARGET = QtInputSupport
|
|
+MODULE = input_support
|
|
+
|
|
+QT = core-private gui-private devicediscovery_support-private
|
|
+CONFIG += static internal_module
|
|
+
|
|
+DEFINES += QT_NO_CAST_FROM_ASCII
|
|
+PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h
|
|
+
|
|
+qtConfig(evdev) {
|
|
+ include($$PWD/evdevmouse/evdevmouse.pri)
|
|
+ include($$PWD/evdevkeyboard/evdevkeyboard.pri)
|
|
+ include($$PWD/evdevtouch/evdevtouch.pri)
|
|
+ qtConfig(tabletevent) {
|
|
+ include($$PWD/evdevtablet/evdevtablet.pri)
|
|
+ }
|
|
+}
|
|
+
|
|
+qtConfig(tslib) {
|
|
+ include($$PWD/tslib/tslib.pri)
|
|
+}
|
|
+
|
|
+qtConfig(libinput) {
|
|
+ include($$PWD/libinput/libinput.pri)
|
|
+}
|
|
+
|
|
+qtConfig(evdev)|qtConfig(libinput) {
|
|
+ include($$PWD/shared/shared.pri)
|
|
+}
|
|
+
|
|
+qtConfig(integrityhid) {
|
|
+ include($$PWD/integrityhid/integrityhid.pri)
|
|
+}
|
|
+
|
|
+load(qt_module)
|
|
diff --git a/src/platformsupport/input/input.pro b/src/platformsupport/input/input.pro
|
|
index 3d39210b9e..138c04dea3 100644
|
|
--- a/src/platformsupport/input/input.pro
|
|
+++ b/src/platformsupport/input/input.pro
|
|
@@ -1,35 +1,8 @@
|
|
-TARGET = QtInputSupport
|
|
-MODULE = input_support
|
|
+TEMPLATE = subdirs
|
|
+QT_FOR_CONFIG += gui-private
|
|
|
|
-QT = core-private gui-private devicediscovery_support-private
|
|
-CONFIG += static internal_module
|
|
+qtConfig(xkbcommon): SUBDIRS += xkbcommon
|
|
|
|
-DEFINES += QT_NO_CAST_FROM_ASCII
|
|
-PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h
|
|
+SUBDIRS += input-support.pro ### FIXME - QTBUG-52657
|
|
|
|
-qtConfig(evdev) {
|
|
- include($$PWD/evdevmouse/evdevmouse.pri)
|
|
- include($$PWD/evdevkeyboard/evdevkeyboard.pri)
|
|
- include($$PWD/evdevtouch/evdevtouch.pri)
|
|
- qtConfig(tabletevent) {
|
|
- include($$PWD/evdevtablet/evdevtablet.pri)
|
|
- }
|
|
-}
|
|
-
|
|
-qtConfig(tslib) {
|
|
- include($$PWD/tslib/tslib.pri)
|
|
-}
|
|
-
|
|
-qtConfig(libinput) {
|
|
- include($$PWD/libinput/libinput.pri)
|
|
-}
|
|
-
|
|
-qtConfig(evdev)|qtConfig(libinput) {
|
|
- include($$PWD/shared/shared.pri)
|
|
-}
|
|
-
|
|
-qtConfig(integrityhid) {
|
|
- include($$PWD/integrityhid/integrityhid.pri)
|
|
-}
|
|
-
|
|
-load(qt_module)
|
|
+CONFIG += ordered
|
|
diff --git a/src/platformsupport/input/libinput/libinput.pri b/src/platformsupport/input/libinput/libinput.pri
|
|
index 476f20c1b8..f80b5f41d9 100644
|
|
--- a/src/platformsupport/input/libinput/libinput.pri
|
|
+++ b/src/platformsupport/input/libinput/libinput.pri
|
|
@@ -14,4 +14,7 @@ QMAKE_USE_PRIVATE += libudev libinput
|
|
|
|
INCLUDEPATH += $$PWD/../shared
|
|
|
|
-qtConfig(xkbcommon): QMAKE_USE_PRIVATE += xkbcommon
|
|
+qtConfig(xkbcommon): {
|
|
+ QMAKE_USE_PRIVATE += xkbcommon
|
|
+ QT += xkbcommon_support-private
|
|
+}
|
|
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
|
|
index baef769bc9..6586b084f1 100644
|
|
--- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
|
|
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
|
|
@@ -47,6 +47,7 @@
|
|
#if QT_CONFIG(xkbcommon)
|
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
|
#include <xkbcommon/xkbcommon-names.h>
|
|
+#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
|
|
#endif
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
@@ -56,88 +57,7 @@ Q_DECLARE_LOGGING_CATEGORY(qLcLibInput)
|
|
const int REPEAT_DELAY = 500;
|
|
const int REPEAT_RATE = 100;
|
|
|
|
-#if QT_CONFIG(xkbcommon)
|
|
-struct KeyTabEntry {
|
|
- int xkbkey;
|
|
- int qtkey;
|
|
-};
|
|
-
|
|
-static inline bool operator==(const KeyTabEntry &a, const KeyTabEntry &b)
|
|
-{
|
|
- return a.xkbkey == b.xkbkey;
|
|
-}
|
|
-
|
|
-static const KeyTabEntry keyTab[] = {
|
|
- { XKB_KEY_Escape, Qt::Key_Escape },
|
|
- { XKB_KEY_Tab, Qt::Key_Tab },
|
|
- { XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab },
|
|
- { XKB_KEY_BackSpace, Qt::Key_Backspace },
|
|
- { XKB_KEY_Return, Qt::Key_Return },
|
|
- { XKB_KEY_Insert, Qt::Key_Insert },
|
|
- { XKB_KEY_Delete, Qt::Key_Delete },
|
|
- { XKB_KEY_Clear, Qt::Key_Delete },
|
|
- { XKB_KEY_Pause, Qt::Key_Pause },
|
|
- { XKB_KEY_Print, Qt::Key_Print },
|
|
-
|
|
- { XKB_KEY_Home, Qt::Key_Home },
|
|
- { XKB_KEY_End, Qt::Key_End },
|
|
- { XKB_KEY_Left, Qt::Key_Left },
|
|
- { XKB_KEY_Up, Qt::Key_Up },
|
|
- { XKB_KEY_Right, Qt::Key_Right },
|
|
- { XKB_KEY_Down, Qt::Key_Down },
|
|
- { XKB_KEY_Prior, Qt::Key_PageUp },
|
|
- { XKB_KEY_Next, Qt::Key_PageDown },
|
|
-
|
|
- { XKB_KEY_Shift_L, Qt::Key_Shift },
|
|
- { XKB_KEY_Shift_R, Qt::Key_Shift },
|
|
- { XKB_KEY_Shift_Lock, Qt::Key_Shift },
|
|
- { XKB_KEY_Control_L, Qt::Key_Control },
|
|
- { XKB_KEY_Control_R, Qt::Key_Control },
|
|
- { XKB_KEY_Meta_L, Qt::Key_Meta },
|
|
- { XKB_KEY_Meta_R, Qt::Key_Meta },
|
|
- { XKB_KEY_Alt_L, Qt::Key_Alt },
|
|
- { XKB_KEY_Alt_R, Qt::Key_Alt },
|
|
- { XKB_KEY_Caps_Lock, Qt::Key_CapsLock },
|
|
- { XKB_KEY_Num_Lock, Qt::Key_NumLock },
|
|
- { XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock },
|
|
- { XKB_KEY_Super_L, Qt::Key_Super_L },
|
|
- { XKB_KEY_Super_R, Qt::Key_Super_R },
|
|
- { XKB_KEY_Menu, Qt::Key_Menu },
|
|
- { XKB_KEY_Hyper_L, Qt::Key_Hyper_L },
|
|
- { XKB_KEY_Hyper_R, Qt::Key_Hyper_R },
|
|
- { XKB_KEY_Help, Qt::Key_Help },
|
|
-
|
|
- { XKB_KEY_KP_Space, Qt::Key_Space },
|
|
- { XKB_KEY_KP_Tab, Qt::Key_Tab },
|
|
- { XKB_KEY_KP_Enter, Qt::Key_Enter },
|
|
- { XKB_KEY_KP_Home, Qt::Key_Home },
|
|
- { XKB_KEY_KP_Left, Qt::Key_Left },
|
|
- { XKB_KEY_KP_Up, Qt::Key_Up },
|
|
- { XKB_KEY_KP_Right, Qt::Key_Right },
|
|
- { XKB_KEY_KP_Down, Qt::Key_Down },
|
|
- { XKB_KEY_KP_Prior, Qt::Key_PageUp },
|
|
- { XKB_KEY_KP_Next, Qt::Key_PageDown },
|
|
- { XKB_KEY_KP_End, Qt::Key_End },
|
|
- { XKB_KEY_KP_Begin, Qt::Key_Clear },
|
|
- { XKB_KEY_KP_Insert, Qt::Key_Insert },
|
|
- { XKB_KEY_KP_Delete, Qt::Key_Delete },
|
|
- { XKB_KEY_KP_Equal, Qt::Key_Equal },
|
|
- { XKB_KEY_KP_Multiply, Qt::Key_Asterisk },
|
|
- { XKB_KEY_KP_Add, Qt::Key_Plus },
|
|
- { XKB_KEY_KP_Separator, Qt::Key_Comma },
|
|
- { XKB_KEY_KP_Subtract, Qt::Key_Minus },
|
|
- { XKB_KEY_KP_Decimal, Qt::Key_Period },
|
|
- { XKB_KEY_KP_Divide, Qt::Key_Slash },
|
|
-};
|
|
-#endif
|
|
-
|
|
QLibInputKeyboard::QLibInputKeyboard()
|
|
-#if QT_CONFIG(xkbcommon)
|
|
- : m_ctx(0),
|
|
- m_keymap(0),
|
|
- m_state(0),
|
|
- m_mods(Qt::NoModifier)
|
|
-#endif
|
|
{
|
|
#if QT_CONFIG(xkbcommon)
|
|
qCDebug(qLcLibInput) << "Using xkbcommon for key mapping";
|
|
@@ -148,18 +68,14 @@ QLibInputKeyboard::QLibInputKeyboard()
|
|
}
|
|
m_keymap = xkb_keymap_new_from_names(m_ctx, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
if (!m_keymap) {
|
|
- qWarning("Failed to compile keymap");
|
|
+ qCWarning(qLcLibInput, "Failed to compile keymap");
|
|
return;
|
|
}
|
|
m_state = xkb_state_new(m_keymap);
|
|
if (!m_state) {
|
|
- qWarning("Failed to create xkb state");
|
|
+ qCWarning(qLcLibInput, "Failed to create xkb state");
|
|
return;
|
|
}
|
|
- m_modindex[0] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL);
|
|
- m_modindex[1] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT);
|
|
- m_modindex[2] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT);
|
|
- m_modindex[3] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO);
|
|
|
|
m_repeatTimer.setSingleShot(true);
|
|
connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat);
|
|
@@ -186,52 +102,33 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
|
|
if (!m_ctx || !m_keymap || !m_state)
|
|
return;
|
|
|
|
- const uint32_t k = libinput_event_keyboard_get_key(e) + 8;
|
|
+ const uint32_t keycode = libinput_event_keyboard_get_key(e) + 8;
|
|
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, keycode);
|
|
const bool pressed = libinput_event_keyboard_get_key_state(e) == LIBINPUT_KEY_STATE_PRESSED;
|
|
|
|
- QVarLengthArray<char, 32> chars(32);
|
|
- const int size = xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
|
|
- if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
|
|
- chars.resize(size + 1);
|
|
- xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
|
|
- }
|
|
- const QString text = QString::fromUtf8(chars.constData(), size);
|
|
-
|
|
- const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k);
|
|
+ // Modifiers here is the modifier state before the event, i.e. not
|
|
+ // including the current key in case it is a modifier. See the XOR
|
|
+ // logic in QKeyEvent::modifiers(). ### QTBUG-73826
|
|
+ Qt::KeyboardModifiers modifiers = QXkbCommon::modifiers(m_state);
|
|
|
|
- // mods here is the modifier state before the event, i.e. not
|
|
- // including the current key in case it is a modifier.
|
|
- Qt::KeyboardModifiers mods = Qt::NoModifier;
|
|
- const int qtkey = keysymToQtKey(sym, &mods, text);
|
|
+ const QString text = QXkbCommon::lookupString(m_state, keycode);
|
|
+ const int qtkey = QXkbCommon::keysymToQtKey(sym, modifiers, m_state, keycode);
|
|
|
|
- if (qtkey == Qt::Key_Control)
|
|
- mods |= Qt::ControlModifier;
|
|
- if (qtkey == Qt::Key_Alt)
|
|
- mods |= Qt::AltModifier;
|
|
- if (qtkey == Qt::Key_Shift)
|
|
- mods |= Qt::ShiftModifier;
|
|
- if (qtkey == Qt::Key_Meta)
|
|
- mods |= Qt::MetaModifier;
|
|
- xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
|
+ xkb_state_update_key(m_state, keycode, pressed ? XKB_KEY_DOWN : XKB_KEY_UP);
|
|
|
|
- if (mods != Qt::NoModifier) {
|
|
- if (pressed)
|
|
- m_mods |= mods;
|
|
- else
|
|
- m_mods &= ~mods;
|
|
+ Qt::KeyboardModifiers modifiersAfterStateChange = QXkbCommon::modifiers(m_state);
|
|
+ QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiersAfterStateChange);
|
|
|
|
- QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(m_mods);
|
|
- }
|
|
QWindowSystemInterface::handleExtendedKeyEvent(nullptr,
|
|
pressed ? QEvent::KeyPress : QEvent::KeyRelease,
|
|
- qtkey, m_mods, k, sym, m_mods, text);
|
|
+ qtkey, modifiers, keycode, sym, modifiers, text);
|
|
|
|
- if (pressed && xkb_keymap_key_repeats(m_keymap, k)) {
|
|
+ if (pressed && xkb_keymap_key_repeats(m_keymap, keycode)) {
|
|
m_repeatData.qtkey = qtkey;
|
|
- m_repeatData.mods = mods;
|
|
- m_repeatData.nativeScanCode = k;
|
|
+ m_repeatData.mods = modifiers;
|
|
+ m_repeatData.nativeScanCode = keycode;
|
|
m_repeatData.virtualKey = sym;
|
|
- m_repeatData.nativeMods = mods;
|
|
+ m_repeatData.nativeMods = modifiers;
|
|
m_repeatData.unicodeText = text;
|
|
m_repeatData.repeatCount = 1;
|
|
m_repeatTimer.setInterval(REPEAT_DELAY);
|
|
@@ -256,50 +153,6 @@ void QLibInputKeyboard::handleRepeat()
|
|
m_repeatTimer.setInterval(REPEAT_RATE);
|
|
m_repeatTimer.start();
|
|
}
|
|
-
|
|
-int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t key) const
|
|
-{
|
|
- const size_t elemCount = sizeof(keyTab) / sizeof(KeyTabEntry);
|
|
- KeyTabEntry e;
|
|
- e.xkbkey = key;
|
|
- const KeyTabEntry *result = std::find(keyTab, keyTab + elemCount, e);
|
|
- return result != keyTab + elemCount ? result->qtkey : 0;
|
|
-}
|
|
-
|
|
-int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const
|
|
-{
|
|
- int code = 0;
|
|
-#if QT_CONFIG(textcodec)
|
|
- QTextCodec *systemCodec = QTextCodec::codecForLocale();
|
|
-#endif
|
|
- if (keysym < 128 || (keysym < 256
|
|
-#if QT_CONFIG(textcodec)
|
|
- && systemCodec->mibEnum() == 4
|
|
-#endif
|
|
- )) {
|
|
- // upper-case key, if known
|
|
- code = isprint((int)keysym) ? toupper((int)keysym) : 0;
|
|
- } else if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
|
|
- // function keys
|
|
- code = Qt::Key_F1 + ((int)keysym - XKB_KEY_F1);
|
|
- } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
|
|
- if (keysym >= XKB_KEY_KP_0) {
|
|
- // numeric keypad keys
|
|
- code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
|
|
- } else {
|
|
- code = keysymToQtKey(keysym);
|
|
- }
|
|
- *modifiers |= Qt::KeypadModifier;
|
|
- } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
|
|
- && text.unicode()->unicode() != 0x7f
|
|
- && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_longsolidusoverlay)) {
|
|
- code = text.unicode()->toUpper().unicode();
|
|
- } else {
|
|
- // any other keys
|
|
- code = keysymToQtKey(keysym);
|
|
- }
|
|
- return code;
|
|
-}
|
|
#endif
|
|
|
|
QT_END_NAMESPACE
|
|
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
|
|
index 14ae71b545..7521902e02 100644
|
|
--- a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
|
|
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h
|
|
@@ -79,10 +79,9 @@ private:
|
|
int keysymToQtKey(xkb_keysym_t key) const;
|
|
int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const;
|
|
|
|
- xkb_context *m_ctx;
|
|
- xkb_keymap *m_keymap;
|
|
- xkb_state *m_state;
|
|
- xkb_mod_index_t m_modindex[4];
|
|
+ xkb_context *m_ctx = nullptr;
|
|
+ xkb_keymap *m_keymap = nullptr;
|
|
+ xkb_state *m_state = nullptr;
|
|
|
|
QTimer m_repeatTimer;
|
|
|
|
@@ -95,7 +94,6 @@ private:
|
|
QString unicodeText;
|
|
int repeatCount;
|
|
} m_repeatData;
|
|
- Qt::KeyboardModifiers m_mods;
|
|
#endif
|
|
};
|
|
|
|
diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
|
|
new file mode 100644
|
|
index 0000000000..4bee868fa9
|
|
--- /dev/null
|
|
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
|
|
@@ -0,0 +1,797 @@
|
|
+/****************************************************************************
|
|
+**
|
|
+** Copyright (C) 2019 The Qt Company Ltd.
|
|
+** Contact: https://www.qt.io/licensing/
|
|
+**
|
|
+** This file is part of the QtGui module of the Qt Toolkit.
|
|
+**
|
|
+** $QT_BEGIN_LICENSE:LGPL$
|
|
+** Commercial License Usage
|
|
+** Licensees holding valid commercial Qt licenses may use this file in
|
|
+** accordance with the commercial license agreement provided with the
|
|
+** Software or, alternatively, in accordance with the terms contained in
|
|
+** a written agreement between you and The Qt Company. For licensing terms
|
|
+** and conditions see https://www.qt.io/terms-conditions. For further
|
|
+** information use the contact form at https://www.qt.io/contact-us.
|
|
+**
|
|
+** GNU Lesser General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
+** General Public License version 3 as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
+** packaging of this file. Please review the following information to
|
|
+** ensure the GNU Lesser General Public License version 3 requirements
|
|
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
|
+**
|
|
+** GNU General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU
|
|
+** General Public License version 2.0 or (at your option) the GNU General
|
|
+** Public license version 3 or any later version approved by the KDE Free
|
|
+** Qt Foundation. The licenses are as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
+** included in the packaging of this file. Please review the following
|
|
+** information to ensure the GNU General Public License requirements will
|
|
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
+** https://www.gnu.org/licenses/gpl-3.0.html.
|
|
+**
|
|
+** $QT_END_LICENSE$
|
|
+**
|
|
+****************************************************************************/
|
|
+
|
|
+#include "qxkbcommon_p.h"
|
|
+
|
|
+#include <private/qmakearray_p.h>
|
|
+
|
|
+#include <QtGui/QKeyEvent>
|
|
+
|
|
+QT_BEGIN_NAMESPACE
|
|
+
|
|
+Q_LOGGING_CATEGORY(lcXkbcommon, "qt.xkbcommon")
|
|
+
|
|
+static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
+ xkb_state *state, xkb_keycode_t code,
|
|
+ bool superAsMeta, bool hyperAsMeta);
|
|
+
|
|
+typedef struct xkb2qt
|
|
+{
|
|
+ unsigned int xkb;
|
|
+ unsigned int qt;
|
|
+
|
|
+ constexpr bool operator <=(const xkb2qt &that) const noexcept
|
|
+ {
|
|
+ return xkb <= that.xkb;
|
|
+ }
|
|
+
|
|
+ constexpr bool operator <(const xkb2qt &that) const noexcept
|
|
+ {
|
|
+ return xkb < that.xkb;
|
|
+ }
|
|
+} xkb2qt_t;
|
|
+
|
|
+template<std::size_t Xkb, std::size_t Qt>
|
|
+struct Xkb2Qt
|
|
+{
|
|
+ using Type = xkb2qt_t;
|
|
+ static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
|
|
+};
|
|
+
|
|
+static constexpr const auto KeyTbl = qMakeArray(
|
|
+ QSortedData<
|
|
+ // misc keys
|
|
+
|
|
+ Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
|
|
+ Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
|
|
+ Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
|
|
+ Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
|
|
+ Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
|
|
+ Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
|
|
+ Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
|
|
+ Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
|
|
+ Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
|
|
+ Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
|
|
+ Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
|
|
+ Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
|
|
+
|
|
+ // cursor movement
|
|
+
|
|
+ Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
|
|
+ Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
|
|
+ Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
|
|
+ Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
|
|
+ Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
|
|
+ Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
|
|
+ Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
|
|
+ Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
|
|
+
|
|
+ // modifiers
|
|
+
|
|
+ Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
|
|
+ Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
|
|
+ Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
|
|
+ Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
|
|
+ Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
|
|
+ Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
|
|
+ Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
|
|
+ Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
|
|
+ Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
|
|
+ Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
|
|
+ Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
|
|
+ Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
|
|
+ Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
|
|
+ Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
|
|
+ Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
|
|
+ Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
|
|
+ Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
|
|
+ Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
|
|
+ Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
|
|
+ Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
|
|
+ Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
|
|
+
|
|
+ // numeric and function keypad keys
|
|
+
|
|
+ Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
|
|
+ Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
|
|
+ Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
|
|
+
|
|
+ // special non-XF86 function keys
|
|
+
|
|
+ Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
|
|
+ Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
|
|
+ Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
|
|
+ Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
|
|
+
|
|
+ // International input method support keys
|
|
+
|
|
+ // International & multi-key character composition
|
|
+ Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
|
|
+ Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
|
|
+ Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
|
|
+ Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
|
|
+
|
|
+ // Misc Functions
|
|
+ Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
|
|
+ Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
|
|
+
|
|
+ // Japanese keyboard support
|
|
+ Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
|
|
+ Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
|
|
+ //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
|
|
+ Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
|
|
+ Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
|
|
+ Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
|
|
+ Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
|
|
+ Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
|
|
+ Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
|
|
+ Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
|
|
+ Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
|
|
+ Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
|
|
+ Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
|
|
+ Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
|
|
+ Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
|
|
+ Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
|
|
+ Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
|
|
+ Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
|
|
+ //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
|
|
+ //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
|
|
+ //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
|
|
+ Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
|
|
+ Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
|
|
+
|
|
+ // Korean keyboard support
|
|
+ Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
|
|
+ //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
|
|
+ //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
|
|
+ //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
|
|
+ //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
|
|
+ //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
|
|
+ Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
|
|
+
|
|
+ // dead keys
|
|
+ Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
|
|
+ Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
|
|
+ Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
|
|
+ Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
|
|
+ Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
|
|
+ Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
|
|
+ Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
|
|
+ Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
|
|
+ Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
|
|
+ Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
|
|
+ Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
|
|
+ Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
|
|
+ Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
|
|
+ Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
|
|
+ Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
|
|
+ Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
|
|
+ Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
|
|
+ Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
|
|
+ Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
|
|
+ Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
|
|
+ Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
|
|
+ Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
|
|
+ Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
|
|
+ Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
|
|
+ Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
|
|
+ Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
|
|
+ Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
|
|
+ Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
|
|
+ Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
|
|
+ Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
|
|
+ Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
|
|
+ Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
|
|
+ Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
|
|
+ Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
|
|
+ Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
|
|
+ Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
|
|
+ Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
|
|
+ Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
|
|
+ Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
|
|
+ Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
|
|
+ Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
|
|
+
|
|
+ // Special keys from X.org - This include multimedia keys,
|
|
+ // wireless/bluetooth/uwb keys, special launcher keys, etc.
|
|
+ Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
|
|
+ Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
|
|
+ Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_Launch0>, // ### Qt 6: remap properly
|
|
+ Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Launch1>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
|
|
+ Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
|
|
+ Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
|
|
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
|
|
+ Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
|
|
+ Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
|
|
+ Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
|
|
+ Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
|
|
+ Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
|
|
+ Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
|
|
+ Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
|
|
+ Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
|
|
+ Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
|
|
+ Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
|
|
+ Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
|
|
+ Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
|
|
+ Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
|
|
+ Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
|
|
+ Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
|
|
+ Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
|
|
+ Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
|
|
+ Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
|
|
+ Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
|
|
+ Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
|
|
+ Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
|
|
+ Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
|
|
+ Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
|
|
+ Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
|
|
+ Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
|
|
+ Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
|
|
+ Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
|
|
+ Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
|
|
+ Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch2>, // ### Qt 6: remap properly
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch3>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch4>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch5>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch6>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch7>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch8>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch9>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_LaunchA>,
|
|
+ Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_LaunchB>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchC>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchD>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchE>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchF>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchG>,
|
|
+ Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchH>
|
|
+ >::Data{}
|
|
+);
|
|
+
|
|
+xkb_keysym_t QXkbCommon::qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks)
|
|
+{
|
|
+ xkb_keysym_t lower, upper;
|
|
+
|
|
+ xkbcommon_XConvertCase(ks, &lower, &upper);
|
|
+
|
|
+ return upper;
|
|
+}
|
|
+
|
|
+QString QXkbCommon::lookupString(struct xkb_state *state, xkb_keycode_t code)
|
|
+{
|
|
+ QVarLengthArray<char, 32> chars(32);
|
|
+ const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
|
|
+ if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
|
|
+ chars.resize(size + 1);
|
|
+ xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
|
|
+ }
|
|
+ return QString::fromUtf8(chars.constData(), size);
|
|
+}
|
|
+
|
|
+QString QXkbCommon::lookupStringNoKeysymTransformations(xkb_keysym_t keysym)
|
|
+{
|
|
+ QVarLengthArray<char, 32> chars(32);
|
|
+ const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
|
|
+ if (size == 0)
|
|
+ return QString(); // the keysym does not have a Unicode representation
|
|
+
|
|
+ if (Q_UNLIKELY(size > chars.size())) {
|
|
+ chars.resize(size);
|
|
+ xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
|
|
+ }
|
|
+ return QString::fromUtf8(chars.constData(), size - 1);
|
|
+}
|
|
+
|
|
+QVector<xkb_keysym_t> QXkbCommon::toKeysym(QKeyEvent *event)
|
|
+{
|
|
+ QVector<xkb_keysym_t> keysyms;
|
|
+ int qtKey = event->key();
|
|
+
|
|
+ if (qtKey >= Qt::Key_F1 && qtKey <= Qt::Key_F35) {
|
|
+ keysyms.append(XKB_KEY_F1 + (qtKey - Qt::Key_F1));
|
|
+ } else if (event->modifiers() & Qt::KeypadModifier) {
|
|
+ if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9)
|
|
+ keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0));
|
|
+ } else if (isLatin(qtKey) && event->text().isUpper()) {
|
|
+ keysyms.append(qtKey);
|
|
+ }
|
|
+
|
|
+ if (!keysyms.isEmpty())
|
|
+ return keysyms;
|
|
+
|
|
+ // check if we have a direct mapping
|
|
+ auto it = std::find_if(KeyTbl.cbegin(), KeyTbl.cend(), [&qtKey](xkb2qt_t elem) {
|
|
+ return elem.qt == static_cast<uint>(qtKey);
|
|
+ });
|
|
+ if (it != KeyTbl.end()) {
|
|
+ keysyms.append(it->xkb);
|
|
+ return keysyms;
|
|
+ }
|
|
+
|
|
+ QVector<uint> ucs4;
|
|
+ if (event->text().isEmpty())
|
|
+ ucs4.append(qtKey);
|
|
+ else
|
|
+ ucs4 = event->text().toUcs4();
|
|
+
|
|
+ // From libxkbcommon keysym-utf.c:
|
|
+ // "We allow to represent any UCS character in the range U-00000000 to
|
|
+ // U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff."
|
|
+ for (uint utf32 : qAsConst(ucs4))
|
|
+ keysyms.append(utf32 | 0x01000000);
|
|
+
|
|
+ return keysyms;
|
|
+}
|
|
+
|
|
+int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers)
|
|
+{
|
|
+ return keysymToQtKey(keysym, modifiers, nullptr, 0);
|
|
+}
|
|
+
|
|
+int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
+ xkb_state *state, xkb_keycode_t code,
|
|
+ bool superAsMeta, bool hyperAsMeta)
|
|
+{
|
|
+ // Note 1: All standard key sequences on linux (as defined in platform theme)
|
|
+ // that use a latin character also contain a control modifier, which is why
|
|
+ // checking for Qt::ControlModifier is sufficient here. It is possible to
|
|
+ // override QPlatformTheme::keyBindings() and provide custom sequences for
|
|
+ // QKeySequence::StandardKey. Custom sequences probably should respect this
|
|
+ // convention (alternatively, we could test against other modifiers here).
|
|
+ // Note 2: The possibleKeys() shorcut mechanism is not affected by this value
|
|
+ // adjustment and does its own thing.
|
|
+ if (modifiers & Qt::ControlModifier) {
|
|
+ // With standard shortcuts we should prefer a latin character, this is
|
|
+ // for checks like "some qkeyevent == QKeySequence::Copy" to work even
|
|
+ // when using for example 'russian' keyboard layout.
|
|
+ if (!QXkbCommon::isLatin(keysym)) {
|
|
+ xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code);
|
|
+ if (latinKeysym != XKB_KEY_NoSymbol)
|
|
+ keysym = latinKeysym;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return keysymToQtKey_internal(keysym, modifiers, state, code, superAsMeta, hyperAsMeta);
|
|
+}
|
|
+
|
|
+static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
+ xkb_state *state, xkb_keycode_t code,
|
|
+ bool superAsMeta, bool hyperAsMeta)
|
|
+{
|
|
+ int qtKey = 0;
|
|
+
|
|
+ // lookup from direct mapping
|
|
+ if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
|
|
+ // function keys
|
|
+ qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1);
|
|
+ } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
|
|
+ // numeric keypad keys
|
|
+ qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
|
|
+ } else if (QXkbCommon::isLatin(keysym)) {
|
|
+ qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym);
|
|
+ } else {
|
|
+ // check if we have a direct mapping
|
|
+ xkb2qt_t searchKey{keysym, 0};
|
|
+ auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
|
|
+ if (it != KeyTbl.end() && !(searchKey < *it))
|
|
+ qtKey = it->qt;
|
|
+ }
|
|
+
|
|
+ if (qtKey)
|
|
+ return qtKey;
|
|
+
|
|
+ // lookup from unicode
|
|
+ QString text;
|
|
+ if (!state || modifiers & Qt::ControlModifier) {
|
|
+ // Control modifier changes the text to ASCII control character, therefore we
|
|
+ // can't use this text to map keysym to a qt key. We can use the same keysym
|
|
+ // (it is not affectd by transformation) to obtain untransformed text. For details
|
|
+ // see "Appendix A. Default Symbol Transformations" in the XKB specification.
|
|
+ text = QXkbCommon::lookupStringNoKeysymTransformations(keysym);
|
|
+ } else {
|
|
+ text = QXkbCommon::lookupString(state, code);
|
|
+ }
|
|
+ if (!text.isEmpty()) {
|
|
+ if (text.unicode()->isDigit()) {
|
|
+ // Ensures that also non-latin digits are mapped to corresponding qt keys,
|
|
+ // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2.
|
|
+ qtKey = Qt::Key_0 + text.unicode()->digitValue();
|
|
+ } else {
|
|
+ qtKey = text.unicode()->toUpper().unicode();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
|
|
+ if (superAsMeta && (qtKey == Qt::Key_Super_L || qtKey == Qt::Key_Super_R))
|
|
+ qtKey = Qt::Key_Meta;
|
|
+ if (hyperAsMeta && (qtKey == Qt::Key_Hyper_L || qtKey == Qt::Key_Hyper_R))
|
|
+ qtKey = Qt::Key_Meta;
|
|
+
|
|
+ return qtKey;
|
|
+}
|
|
+
|
|
+Qt::KeyboardModifiers QXkbCommon::modifiers(struct xkb_state *state)
|
|
+{
|
|
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
|
|
+
|
|
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0)
|
|
+ modifiers |= Qt::ControlModifier;
|
|
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0)
|
|
+ modifiers |= Qt::AltModifier;
|
|
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0)
|
|
+ modifiers |= Qt::ShiftModifier;
|
|
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0)
|
|
+ modifiers |= Qt::MetaModifier;
|
|
+
|
|
+ return modifiers;
|
|
+}
|
|
+
|
|
+// Possible modifier states.
|
|
+static const Qt::KeyboardModifiers ModsTbl[] = {
|
|
+ Qt::NoModifier, // 0
|
|
+ Qt::ShiftModifier, // 1
|
|
+ Qt::ControlModifier, // 2
|
|
+ Qt::ControlModifier | Qt::ShiftModifier, // 3
|
|
+ Qt::AltModifier, // 4
|
|
+ Qt::AltModifier | Qt::ShiftModifier, // 5
|
|
+ Qt::AltModifier | Qt::ControlModifier, // 6
|
|
+ Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
|
|
+ Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
|
|
+};
|
|
+
|
|
+QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
|
|
+ bool superAsMeta, bool hyperAsMeta)
|
|
+{
|
|
+ QList<int> result;
|
|
+ quint32 keycode = event->nativeScanCode();
|
|
+ Qt::KeyboardModifiers modifiers = event->modifiers();
|
|
+ xkb_keymap *keymap = xkb_state_get_keymap(state);
|
|
+ // turn off the modifier bits which doesn't participate in shortcuts
|
|
+ Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier;
|
|
+ modifiers &= ~notNeeded;
|
|
+ // create a fresh kb state and test against the relevant modifier combinations
|
|
+ ScopedXKBState scopedXkbQueryState(xkb_state_new(keymap));
|
|
+ xkb_state *queryState = scopedXkbQueryState.get();
|
|
+ if (!queryState) {
|
|
+ qCWarning(lcXkbcommon) << Q_FUNC_INFO << "failed to compile xkb keymap";
|
|
+ return result;
|
|
+ }
|
|
+ // get kb state from the master state and update the temporary state
|
|
+ xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_LOCKED);
|
|
+ xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
|
|
+ xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
|
|
+ xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED);
|
|
+ xkb_state_update_mask(queryState, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
+ // handle shortcuts for level three and above
|
|
+ xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(queryState, keycode);
|
|
+ xkb_level_index_t levelIndex = 0;
|
|
+ if (layoutIndex != XKB_LAYOUT_INVALID) {
|
|
+ levelIndex = xkb_state_key_get_level(queryState, keycode, layoutIndex);
|
|
+ if (levelIndex == XKB_LEVEL_INVALID)
|
|
+ levelIndex = 0;
|
|
+ }
|
|
+ if (levelIndex <= 1)
|
|
+ xkb_state_update_mask(queryState, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
+
|
|
+ xkb_keysym_t sym = xkb_state_key_get_one_sym(queryState, keycode);
|
|
+ if (sym == XKB_KEY_NoSymbol)
|
|
+ return result;
|
|
+
|
|
+ int baseQtKey = keysymToQtKey_internal(sym, modifiers, queryState, keycode, superAsMeta, hyperAsMeta);
|
|
+ if (baseQtKey)
|
|
+ result += (baseQtKey + modifiers);
|
|
+
|
|
+ xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(keymap, "Shift");
|
|
+ xkb_mod_index_t altMod = xkb_keymap_mod_get_index(keymap, "Alt");
|
|
+ xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(keymap, "Control");
|
|
+ xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(keymap, "Meta");
|
|
+
|
|
+ Q_ASSERT(shiftMod < 32);
|
|
+ Q_ASSERT(altMod < 32);
|
|
+ Q_ASSERT(controlMod < 32);
|
|
+
|
|
+ xkb_mod_mask_t depressed;
|
|
+ int qtKey = 0;
|
|
+ // obtain a list of possible shortcuts for the given key event
|
|
+ for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
|
|
+ Qt::KeyboardModifiers neededMods = ModsTbl[i];
|
|
+ if ((modifiers & neededMods) == neededMods) {
|
|
+ if (i == 8) {
|
|
+ if (isLatin(baseQtKey))
|
|
+ continue;
|
|
+ // add a latin key as a fall back key
|
|
+ sym = lookupLatinKeysym(state, keycode);
|
|
+ } else {
|
|
+ depressed = 0;
|
|
+ if (neededMods & Qt::AltModifier)
|
|
+ depressed |= (1 << altMod);
|
|
+ if (neededMods & Qt::ShiftModifier)
|
|
+ depressed |= (1 << shiftMod);
|
|
+ if (neededMods & Qt::ControlModifier)
|
|
+ depressed |= (1 << controlMod);
|
|
+ if (metaMod < 32 && neededMods & Qt::MetaModifier)
|
|
+ depressed |= (1 << metaMod);
|
|
+ xkb_state_update_mask(queryState, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
+ sym = xkb_state_key_get_one_sym(queryState, keycode);
|
|
+ }
|
|
+ if (sym == XKB_KEY_NoSymbol)
|
|
+ continue;
|
|
+
|
|
+ Qt::KeyboardModifiers mods = modifiers & ~neededMods;
|
|
+ qtKey = keysymToQtKey_internal(sym, mods, queryState, keycode, superAsMeta, hyperAsMeta);
|
|
+ if (!qtKey || qtKey == baseQtKey)
|
|
+ continue;
|
|
+
|
|
+ // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
|
|
+ // but Ctrl++ is more specific than +, so we should skip the last one
|
|
+ bool ambiguous = false;
|
|
+ for (int shortcut : qAsConst(result)) {
|
|
+ if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) {
|
|
+ ambiguous = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (ambiguous)
|
|
+ continue;
|
|
+
|
|
+ result += (qtKey + mods);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return result;
|
|
+}
|
|
+
|
|
+void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
|
|
+{
|
|
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(keymap);
|
|
+ const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
|
|
+ const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
|
|
+
|
|
+ const xkb_keysym_t *keysyms = nullptr;
|
|
+ int nrLatinKeys = 0;
|
|
+ for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
|
|
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
|
|
+ xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms);
|
|
+ if (keysyms && isLatin(keysyms[0]))
|
|
+ nrLatinKeys++;
|
|
+ if (nrLatinKeys > 10) // arbitrarily chosen threshold
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ // This means that lookupLatinKeysym() will not find anything and latin
|
|
+ // key shortcuts might not work. This is a bug in the affected desktop
|
|
+ // environment. Usually can be solved via system settings by adding e.g. 'us'
|
|
+ // layout to the list of seleced layouts, or by using command line, "setxkbmap
|
|
+ // -layout rus,en". The position of latin key based layout in the list of the
|
|
+ // selected layouts is irrelevant. Properly functioning desktop environments
|
|
+ // handle this behind the scenes, even if no latin key based layout has been
|
|
+ // explicitly listed in the selected layouts.
|
|
+ qCDebug(lcXkbcommon, "no keyboard layouts with latin keys present");
|
|
+}
|
|
+
|
|
+xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode)
|
|
+{
|
|
+ xkb_layout_index_t layout;
|
|
+ xkb_keysym_t sym = XKB_KEY_NoSymbol;
|
|
+ xkb_keymap *keymap = xkb_state_get_keymap(state);
|
|
+ const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(keymap, keycode);
|
|
+ const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(state, keycode);
|
|
+ // Look at user layouts in the order in which they are defined in system
|
|
+ // settings to find a latin keysym.
|
|
+ for (layout = 0; layout < layoutCount; ++layout) {
|
|
+ if (layout == currentLayout)
|
|
+ continue;
|
|
+ const xkb_keysym_t *syms = nullptr;
|
|
+ xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout);
|
|
+ if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1)
|
|
+ continue;
|
|
+ if (isLatin(syms[0])) {
|
|
+ sym = syms[0];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (sym == XKB_KEY_NoSymbol)
|
|
+ return sym;
|
|
+
|
|
+ xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED);
|
|
+ xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED);
|
|
+
|
|
+ // Check for uniqueness, consider the following setup:
|
|
+ // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
|
|
+ // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
|
|
+ // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
|
|
+ // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
|
|
+ // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
|
|
+ // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
|
|
+ // generate the same shortcut event in this case.
|
|
+ const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap);
|
|
+ const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap);
|
|
+ ScopedXKBState queryState(xkb_state_new(keymap));
|
|
+ for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
|
|
+ xkb_state_update_mask(queryState.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout);
|
|
+ for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
|
|
+ xkb_keysym_t prevSym = xkb_state_key_get_one_sym(queryState.get(), code);
|
|
+ if (prevSym == sym) {
|
|
+ sym = XKB_KEY_NoSymbol;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return sym;
|
|
+}
|
|
+
|
|
+QT_END_NAMESPACE
|
|
diff --git a/src/plugins/platforms/xcb/qxcbxkbcommon.h b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp
|
|
similarity index 94%
|
|
rename from src/plugins/platforms/xcb/qxcbxkbcommon.h
|
|
rename to src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp
|
|
index 422c0c0f12..08f43b3b72 100644
|
|
--- a/src/plugins/platforms/xcb/qxcbxkbcommon.h
|
|
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp
|
|
@@ -1,9 +1,9 @@
|
|
/****************************************************************************
|
|
**
|
|
-** Copyright (C) 2018 The Qt Company Ltd.
|
|
+** Copyright (C) 2019 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
-** This file is part of the plugins of the Qt Toolkit.
|
|
+** This file is part of the QtGui module of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:LGPL$
|
|
** Commercial License Usage
|
|
@@ -37,10 +37,7 @@
|
|
**
|
|
****************************************************************************/
|
|
|
|
-/* XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c,
|
|
- which contains the following license information:
|
|
-
|
|
- Copyright 1985, 1987, 1990, 1998 The Open Group
|
|
+/* Copyright 1985, 1987, 1990, 1998 The Open Group
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
copy of this software and associated documentation files (the "Software"),
|
|
@@ -89,6 +86,7 @@
|
|
*/
|
|
|
|
/*
|
|
+ XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c
|
|
The following code modifications were applied:
|
|
|
|
XConvertCase() was renamed to xkbcommon_XConvertCase(), to not confuse it
|
|
@@ -99,10 +97,9 @@
|
|
results instead of using the less complete version from keysym.c
|
|
*/
|
|
|
|
-#include <xkbcommon/xkbcommon.h>
|
|
-#include <QtCore/QChar>
|
|
+#include "qxkbcommon_p.h"
|
|
|
|
-QT_BEGIN_NAMESPACE
|
|
+#include <QtCore/QChar>
|
|
|
|
static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
|
{
|
|
@@ -110,7 +107,7 @@ static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *
|
|
*upper = QChar::toUpper(code);
|
|
}
|
|
|
|
-void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
|
+void QXkbCommon::xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper)
|
|
{
|
|
/* Latin 1 keysym */
|
|
if (sym < 0x100) {
|
|
@@ -220,14 +217,3 @@ void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t
|
|
break;
|
|
}
|
|
}
|
|
-
|
|
-xkb_keysym_t xkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks)
|
|
-{
|
|
- xkb_keysym_t lower, upper;
|
|
-
|
|
- xkbcommon_XConvertCase(ks, &lower, &upper);
|
|
-
|
|
- return upper;
|
|
-}
|
|
-
|
|
-QT_END_NAMESPACE
|
|
diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
|
|
new file mode 100644
|
|
index 0000000000..475c51ad91
|
|
--- /dev/null
|
|
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h
|
|
@@ -0,0 +1,118 @@
|
|
+/****************************************************************************
|
|
+**
|
|
+** Copyright (C) 2018 The Qt Company Ltd.
|
|
+** Contact: https://www.qt.io/licensing/
|
|
+**
|
|
+** This file is part of the QtGui module of the Qt Toolkit.
|
|
+**
|
|
+** $QT_BEGIN_LICENSE:LGPL$
|
|
+** Commercial License Usage
|
|
+** Licensees holding valid commercial Qt licenses may use this file in
|
|
+** accordance with the commercial license agreement provided with the
|
|
+** Software or, alternatively, in accordance with the terms contained in
|
|
+** a written agreement between you and The Qt Company. For licensing terms
|
|
+** and conditions see https://www.qt.io/terms-conditions. For further
|
|
+** information use the contact form at https://www.qt.io/contact-us.
|
|
+**
|
|
+** GNU Lesser General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
+** General Public License version 3 as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
+** packaging of this file. Please review the following information to
|
|
+** ensure the GNU Lesser General Public License version 3 requirements
|
|
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
|
+**
|
|
+** GNU General Public License Usage
|
|
+** Alternatively, this file may be used under the terms of the GNU
|
|
+** General Public License version 2.0 or (at your option) the GNU General
|
|
+** Public license version 3 or any later version approved by the KDE Free
|
|
+** Qt Foundation. The licenses are as published by the Free Software
|
|
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
+** included in the packaging of this file. Please review the following
|
|
+** information to ensure the GNU General Public License requirements will
|
|
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
+** https://www.gnu.org/licenses/gpl-3.0.html.
|
|
+**
|
|
+** $QT_END_LICENSE$
|
|
+**
|
|
+****************************************************************************/
|
|
+
|
|
+#ifndef QXKBCOMMON_P_H
|
|
+#define QXKBCOMMON_P_H
|
|
+
|
|
+//
|
|
+// W A R N I N G
|
|
+// -------------
|
|
+//
|
|
+// This file is not part of the Qt API. It exists purely as an
|
|
+// implementation detail. This header file may change from version to
|
|
+// version without notice, or even be removed.
|
|
+//
|
|
+// We mean it.
|
|
+//
|
|
+
|
|
+#include <QtCore/QString>
|
|
+#include <QtCore/QVector>
|
|
+#include <QtCore/QLoggingCategory>
|
|
+#include <QtCore/QList>
|
|
+
|
|
+#include <xkbcommon/xkbcommon.h>
|
|
+
|
|
+#include <memory>
|
|
+
|
|
+QT_BEGIN_NAMESPACE
|
|
+
|
|
+Q_DECLARE_LOGGING_CATEGORY(lcXkbcommon)
|
|
+
|
|
+class QKeyEvent;
|
|
+
|
|
+class QXkbCommon
|
|
+{
|
|
+public:
|
|
+ static QString lookupString(struct xkb_state *state, xkb_keycode_t code);
|
|
+ static QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym);
|
|
+
|
|
+ static QVector<xkb_keysym_t> toKeysym(QKeyEvent *event);
|
|
+
|
|
+ static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers);
|
|
+ static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
+ xkb_state *state, xkb_keycode_t code,
|
|
+ bool superAsMeta = false, bool hyperAsMeta = false);
|
|
+
|
|
+ // xkbcommon_* API is part of libxkbcommon internals, with modifications as
|
|
+ // desribed in the header of the implementation file.
|
|
+ static void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper);
|
|
+ static xkb_keysym_t qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks);
|
|
+
|
|
+ static Qt::KeyboardModifiers modifiers(struct xkb_state *state);
|
|
+
|
|
+ static QList<int> possibleKeys(xkb_state *state, const QKeyEvent *event,
|
|
+ bool superAsMeta = false, bool hyperAsMeta = false);
|
|
+
|
|
+ static void verifyHasLatinLayout(xkb_keymap *keymap);
|
|
+ static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);
|
|
+
|
|
+ static bool isLatin(xkb_keysym_t sym) {
|
|
+ return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
|
|
+ }
|
|
+ static bool isKeypad(xkb_keysym_t sym) {
|
|
+ return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9;
|
|
+ }
|
|
+
|
|
+ struct XKBStateDeleter {
|
|
+ void operator()(struct xkb_state *state) const { return xkb_state_unref(state); }
|
|
+ };
|
|
+ struct XKBKeymapDeleter {
|
|
+ void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); }
|
|
+ };
|
|
+ struct XKBContextDeleter {
|
|
+ void operator()(struct xkb_context *context) const { return xkb_context_unref(context); }
|
|
+ };
|
|
+ using ScopedXKBState = std::unique_ptr<struct xkb_state, XKBStateDeleter>;
|
|
+ using ScopedXKBKeymap = std::unique_ptr<struct xkb_keymap, XKBKeymapDeleter>;
|
|
+ using ScopedXKBContext = std::unique_ptr<struct xkb_context, XKBContextDeleter>;
|
|
+};
|
|
+
|
|
+QT_END_NAMESPACE
|
|
+
|
|
+#endif // QXKBCOMMON_P_H
|
|
diff --git a/src/platformsupport/input/xkbcommon/xkbcommon.pro b/src/platformsupport/input/xkbcommon/xkbcommon.pro
|
|
new file mode 100644
|
|
index 0000000000..2f5d132b5c
|
|
--- /dev/null
|
|
+++ b/src/platformsupport/input/xkbcommon/xkbcommon.pro
|
|
@@ -0,0 +1,23 @@
|
|
+TARGET = QtXkbCommonSupport
|
|
+MODULE = xkbcommon_support
|
|
+
|
|
+QT = core-private gui-private
|
|
+CONFIG += static internal_module
|
|
+
|
|
+DEFINES += QT_NO_CAST_FROM_ASCII
|
|
+PRECOMPILED_HEADER = ../../../corelib/global/qt_pch.h
|
|
+
|
|
+QMAKE_USE_PRIVATE += xkbcommon
|
|
+
|
|
+HEADERS += \
|
|
+ qxkbcommon_p.h
|
|
+
|
|
+SOURCES += \
|
|
+ qxkbcommon.cpp \
|
|
+ qxkbcommon_3rdparty.cpp
|
|
+
|
|
+# qxkbcommon.cpp::KeyTbl has more than 256 levels of expansion and older
|
|
+# Clang uses that as a limit (it's 1024 in current versions).
|
|
+clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024
|
|
+
|
|
+load(qt_module)
|
|
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
|
index c5dc7b21ad..6eb31d67bd 100644
|
|
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
|
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
|
|
@@ -39,7 +39,6 @@
|
|
#include "qxcbkeyboard.h"
|
|
#include "qxcbwindow.h"
|
|
#include "qxcbscreen.h"
|
|
-#include "qxcbxkbcommon.h"
|
|
|
|
#include <qpa/qwindowsysteminterface.h>
|
|
#include <qpa/qplatforminputcontext.h>
|
|
@@ -49,404 +48,20 @@
|
|
#include <QtCore/QMetaEnum>
|
|
|
|
#include <private/qguiapplication_p.h>
|
|
-#include <private/qmakearray_p.h>
|
|
|
|
-#include <xkbcommon/xkbcommon-keysyms.h>
|
|
+#if QT_CONFIG(xkb)
|
|
+#include <xkbcommon/xkbcommon-x11.h>
|
|
+#endif
|
|
|
|
#if QT_CONFIG(xcb_xinput)
|
|
#include <xcb/xinput.h>
|
|
#endif
|
|
-QT_BEGIN_NAMESPACE
|
|
-
|
|
-typedef struct xkb2qt
|
|
-{
|
|
- unsigned int xkb;
|
|
- unsigned int qt;
|
|
-
|
|
- constexpr bool operator <=(const xkb2qt &that) const noexcept
|
|
- {
|
|
- return xkb <= that.xkb;
|
|
- }
|
|
-
|
|
- constexpr bool operator <(const xkb2qt &that) const noexcept
|
|
- {
|
|
- return xkb < that.xkb;
|
|
- }
|
|
-} xkb2qt_t;
|
|
|
|
-template<std::size_t Xkb, std::size_t Qt>
|
|
-struct Xkb2Qt
|
|
-{
|
|
- using Type = xkb2qt_t;
|
|
- static constexpr Type data() noexcept { return Type{Xkb, Qt}; }
|
|
-};
|
|
-
|
|
-static constexpr const auto KeyTbl = qMakeArray(
|
|
- QSortedData<
|
|
- // misc keys
|
|
-
|
|
- Xkb2Qt<XKB_KEY_Escape, Qt::Key_Escape>,
|
|
- Xkb2Qt<XKB_KEY_Tab, Qt::Key_Tab>,
|
|
- Xkb2Qt<XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab>,
|
|
- Xkb2Qt<XKB_KEY_BackSpace, Qt::Key_Backspace>,
|
|
- Xkb2Qt<XKB_KEY_Return, Qt::Key_Return>,
|
|
- Xkb2Qt<XKB_KEY_Insert, Qt::Key_Insert>,
|
|
- Xkb2Qt<XKB_KEY_Delete, Qt::Key_Delete>,
|
|
- Xkb2Qt<XKB_KEY_Clear, Qt::Key_Delete>,
|
|
- Xkb2Qt<XKB_KEY_Pause, Qt::Key_Pause>,
|
|
- Xkb2Qt<XKB_KEY_Print, Qt::Key_Print>,
|
|
- Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq
|
|
- Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq
|
|
-
|
|
- // cursor movement
|
|
-
|
|
- Xkb2Qt<XKB_KEY_Home, Qt::Key_Home>,
|
|
- Xkb2Qt<XKB_KEY_End, Qt::Key_End>,
|
|
- Xkb2Qt<XKB_KEY_Left, Qt::Key_Left>,
|
|
- Xkb2Qt<XKB_KEY_Up, Qt::Key_Up>,
|
|
- Xkb2Qt<XKB_KEY_Right, Qt::Key_Right>,
|
|
- Xkb2Qt<XKB_KEY_Down, Qt::Key_Down>,
|
|
- Xkb2Qt<XKB_KEY_Prior, Qt::Key_PageUp>,
|
|
- Xkb2Qt<XKB_KEY_Next, Qt::Key_PageDown>,
|
|
-
|
|
- // modifiers
|
|
-
|
|
- Xkb2Qt<XKB_KEY_Shift_L, Qt::Key_Shift>,
|
|
- Xkb2Qt<XKB_KEY_Shift_R, Qt::Key_Shift>,
|
|
- Xkb2Qt<XKB_KEY_Shift_Lock, Qt::Key_Shift>,
|
|
- Xkb2Qt<XKB_KEY_Control_L, Qt::Key_Control>,
|
|
- Xkb2Qt<XKB_KEY_Control_R, Qt::Key_Control>,
|
|
- Xkb2Qt<XKB_KEY_Meta_L, Qt::Key_Meta>,
|
|
- Xkb2Qt<XKB_KEY_Meta_R, Qt::Key_Meta>,
|
|
- Xkb2Qt<XKB_KEY_Alt_L, Qt::Key_Alt>,
|
|
- Xkb2Qt<XKB_KEY_Alt_R, Qt::Key_Alt>,
|
|
- Xkb2Qt<XKB_KEY_Caps_Lock, Qt::Key_CapsLock>,
|
|
- Xkb2Qt<XKB_KEY_Num_Lock, Qt::Key_NumLock>,
|
|
- Xkb2Qt<XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock>,
|
|
- Xkb2Qt<XKB_KEY_Super_L, Qt::Key_Super_L>,
|
|
- Xkb2Qt<XKB_KEY_Super_R, Qt::Key_Super_R>,
|
|
- Xkb2Qt<XKB_KEY_Menu, Qt::Key_Menu>,
|
|
- Xkb2Qt<XKB_KEY_Hyper_L, Qt::Key_Hyper_L>,
|
|
- Xkb2Qt<XKB_KEY_Hyper_R, Qt::Key_Hyper_R>,
|
|
- Xkb2Qt<XKB_KEY_Help, Qt::Key_Help>,
|
|
- Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab
|
|
- Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11)
|
|
- Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12)
|
|
-
|
|
- // numeric and function keypad keys
|
|
-
|
|
- Xkb2Qt<XKB_KEY_KP_Space, Qt::Key_Space>,
|
|
- Xkb2Qt<XKB_KEY_KP_Tab, Qt::Key_Tab>,
|
|
- Xkb2Qt<XKB_KEY_KP_Enter, Qt::Key_Enter>,
|
|
- //Xkb2Qt<XKB_KEY_KP_F1, Qt::Key_F1>,
|
|
- //Xkb2Qt<XKB_KEY_KP_F2, Qt::Key_F2>,
|
|
- //Xkb2Qt<XKB_KEY_KP_F3, Qt::Key_F3>,
|
|
- //Xkb2Qt<XKB_KEY_KP_F4, Qt::Key_F4>,
|
|
- Xkb2Qt<XKB_KEY_KP_Home, Qt::Key_Home>,
|
|
- Xkb2Qt<XKB_KEY_KP_Left, Qt::Key_Left>,
|
|
- Xkb2Qt<XKB_KEY_KP_Up, Qt::Key_Up>,
|
|
- Xkb2Qt<XKB_KEY_KP_Right, Qt::Key_Right>,
|
|
- Xkb2Qt<XKB_KEY_KP_Down, Qt::Key_Down>,
|
|
- Xkb2Qt<XKB_KEY_KP_Prior, Qt::Key_PageUp>,
|
|
- Xkb2Qt<XKB_KEY_KP_Next, Qt::Key_PageDown>,
|
|
- Xkb2Qt<XKB_KEY_KP_End, Qt::Key_End>,
|
|
- Xkb2Qt<XKB_KEY_KP_Begin, Qt::Key_Clear>,
|
|
- Xkb2Qt<XKB_KEY_KP_Insert, Qt::Key_Insert>,
|
|
- Xkb2Qt<XKB_KEY_KP_Delete, Qt::Key_Delete>,
|
|
- Xkb2Qt<XKB_KEY_KP_Equal, Qt::Key_Equal>,
|
|
- Xkb2Qt<XKB_KEY_KP_Multiply, Qt::Key_Asterisk>,
|
|
- Xkb2Qt<XKB_KEY_KP_Add, Qt::Key_Plus>,
|
|
- Xkb2Qt<XKB_KEY_KP_Separator, Qt::Key_Comma>,
|
|
- Xkb2Qt<XKB_KEY_KP_Subtract, Qt::Key_Minus>,
|
|
- Xkb2Qt<XKB_KEY_KP_Decimal, Qt::Key_Period>,
|
|
- Xkb2Qt<XKB_KEY_KP_Divide, Qt::Key_Slash>,
|
|
-
|
|
- // special non-XF86 function keys
|
|
-
|
|
- Xkb2Qt<XKB_KEY_Undo, Qt::Key_Undo>,
|
|
- Xkb2Qt<XKB_KEY_Redo, Qt::Key_Redo>,
|
|
- Xkb2Qt<XKB_KEY_Find, Qt::Key_Find>,
|
|
- Xkb2Qt<XKB_KEY_Cancel, Qt::Key_Cancel>,
|
|
-
|
|
- // International input method support keys
|
|
-
|
|
- // International & multi-key character composition
|
|
- Xkb2Qt<XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr>,
|
|
- Xkb2Qt<XKB_KEY_Multi_key, Qt::Key_Multi_key>,
|
|
- Xkb2Qt<XKB_KEY_Codeinput, Qt::Key_Codeinput>,
|
|
- Xkb2Qt<XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate>,
|
|
- Xkb2Qt<XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate>,
|
|
- Xkb2Qt<XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate>,
|
|
-
|
|
- // Misc Functions
|
|
- Xkb2Qt<XKB_KEY_Mode_switch, Qt::Key_Mode_switch>,
|
|
- Xkb2Qt<XKB_KEY_script_switch, Qt::Key_Mode_switch>,
|
|
-
|
|
- // Japanese keyboard support
|
|
- Xkb2Qt<XKB_KEY_Kanji, Qt::Key_Kanji>,
|
|
- Xkb2Qt<XKB_KEY_Muhenkan, Qt::Key_Muhenkan>,
|
|
- //Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan_Mode>,
|
|
- Xkb2Qt<XKB_KEY_Henkan_Mode, Qt::Key_Henkan>,
|
|
- Xkb2Qt<XKB_KEY_Henkan, Qt::Key_Henkan>,
|
|
- Xkb2Qt<XKB_KEY_Romaji, Qt::Key_Romaji>,
|
|
- Xkb2Qt<XKB_KEY_Hiragana, Qt::Key_Hiragana>,
|
|
- Xkb2Qt<XKB_KEY_Katakana, Qt::Key_Katakana>,
|
|
- Xkb2Qt<XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana>,
|
|
- Xkb2Qt<XKB_KEY_Zenkaku, Qt::Key_Zenkaku>,
|
|
- Xkb2Qt<XKB_KEY_Hankaku, Qt::Key_Hankaku>,
|
|
- Xkb2Qt<XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku>,
|
|
- Xkb2Qt<XKB_KEY_Touroku, Qt::Key_Touroku>,
|
|
- Xkb2Qt<XKB_KEY_Massyo, Qt::Key_Massyo>,
|
|
- Xkb2Qt<XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock>,
|
|
- Xkb2Qt<XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift>,
|
|
- Xkb2Qt<XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift>,
|
|
- Xkb2Qt<XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle>,
|
|
- //Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Kanji_Bangou>,
|
|
- //Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_Zen_Koho>,
|
|
- //Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_Mae_Koho>,
|
|
- Xkb2Qt<XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput>,
|
|
- Xkb2Qt<XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate>,
|
|
- Xkb2Qt<XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate>,
|
|
-
|
|
- // Korean keyboard support
|
|
- Xkb2Qt<XKB_KEY_Hangul, Qt::Key_Hangul>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_End, Qt::Key_Hangul_End>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja>,
|
|
- //Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Hangul_Codeinput>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja>,
|
|
- //Xkb2Qt<XKB_KEY_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate>,
|
|
- //Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate>,
|
|
- //Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special>,
|
|
- //Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Hangul_switch>,
|
|
- Xkb2Qt<XKB_KEY_Hangul_switch, Qt::Key_Mode_switch>,
|
|
-
|
|
- // dead keys
|
|
- Xkb2Qt<XKB_KEY_dead_grave, Qt::Key_Dead_Grave>,
|
|
- Xkb2Qt<XKB_KEY_dead_acute, Qt::Key_Dead_Acute>,
|
|
- Xkb2Qt<XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex>,
|
|
- Xkb2Qt<XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde>,
|
|
- Xkb2Qt<XKB_KEY_dead_macron, Qt::Key_Dead_Macron>,
|
|
- Xkb2Qt<XKB_KEY_dead_breve, Qt::Key_Dead_Breve>,
|
|
- Xkb2Qt<XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot>,
|
|
- Xkb2Qt<XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis>,
|
|
- Xkb2Qt<XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering>,
|
|
- Xkb2Qt<XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute>,
|
|
- Xkb2Qt<XKB_KEY_dead_caron, Qt::Key_Dead_Caron>,
|
|
- Xkb2Qt<XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla>,
|
|
- Xkb2Qt<XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek>,
|
|
- Xkb2Qt<XKB_KEY_dead_iota, Qt::Key_Dead_Iota>,
|
|
- Xkb2Qt<XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound>,
|
|
- Xkb2Qt<XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot>,
|
|
- Xkb2Qt<XKB_KEY_dead_hook, Qt::Key_Dead_Hook>,
|
|
- Xkb2Qt<XKB_KEY_dead_horn, Qt::Key_Dead_Horn>,
|
|
- Xkb2Qt<XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke>,
|
|
- Xkb2Qt<XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma>,
|
|
- Xkb2Qt<XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma>,
|
|
- Xkb2Qt<XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis>,
|
|
- Xkb2Qt<XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma>,
|
|
- Xkb2Qt<XKB_KEY_dead_currency, Qt::Key_Dead_Currency>,
|
|
- Xkb2Qt<XKB_KEY_dead_a, Qt::Key_Dead_a>,
|
|
- Xkb2Qt<XKB_KEY_dead_A, Qt::Key_Dead_A>,
|
|
- Xkb2Qt<XKB_KEY_dead_e, Qt::Key_Dead_e>,
|
|
- Xkb2Qt<XKB_KEY_dead_E, Qt::Key_Dead_E>,
|
|
- Xkb2Qt<XKB_KEY_dead_i, Qt::Key_Dead_i>,
|
|
- Xkb2Qt<XKB_KEY_dead_I, Qt::Key_Dead_I>,
|
|
- Xkb2Qt<XKB_KEY_dead_o, Qt::Key_Dead_o>,
|
|
- Xkb2Qt<XKB_KEY_dead_O, Qt::Key_Dead_O>,
|
|
- Xkb2Qt<XKB_KEY_dead_u, Qt::Key_Dead_u>,
|
|
- Xkb2Qt<XKB_KEY_dead_U, Qt::Key_Dead_U>,
|
|
- Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
|
|
- Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
|
|
- Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
|
|
- Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
|
|
- Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
|
|
- Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
|
|
- Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
|
|
-
|
|
- // Special keys from X.org - This include multimedia keys,
|
|
- // wireless/bluetooth/uwb keys, special launcher keys, etc.
|
|
- Xkb2Qt<XKB_KEY_XF86Back, Qt::Key_Back>,
|
|
- Xkb2Qt<XKB_KEY_XF86Forward, Qt::Key_Forward>,
|
|
- Xkb2Qt<XKB_KEY_XF86Stop, Qt::Key_Stop>,
|
|
- Xkb2Qt<XKB_KEY_XF86Refresh, Qt::Key_Refresh>,
|
|
- Xkb2Qt<XKB_KEY_XF86Favorites, Qt::Key_Favorites>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia>,
|
|
- Xkb2Qt<XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl>,
|
|
- Xkb2Qt<XKB_KEY_XF86HomePage, Qt::Key_HomePage>,
|
|
- Xkb2Qt<XKB_KEY_XF86Search, Qt::Key_Search>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioStop, Qt::Key_MediaStop>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioNext, Qt::Key_MediaNext>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioPause, Qt::Key_MediaPause>,
|
|
- Xkb2Qt<XKB_KEY_XF86Mail, Qt::Key_LaunchMail>,
|
|
- Xkb2Qt<XKB_KEY_XF86MyComputer, Qt::Key_Launch0>, // ### Qt 6: remap properly
|
|
- Xkb2Qt<XKB_KEY_XF86Calculator, Qt::Key_Launch1>,
|
|
- Xkb2Qt<XKB_KEY_XF86Memo, Qt::Key_Memo>,
|
|
- Xkb2Qt<XKB_KEY_XF86ToDoList, Qt::Key_ToDoList>,
|
|
- Xkb2Qt<XKB_KEY_XF86Calendar, Qt::Key_Calendar>,
|
|
- Xkb2Qt<XKB_KEY_XF86PowerDown, Qt::Key_PowerDown>,
|
|
- Xkb2Qt<XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust>,
|
|
- Xkb2Qt<XKB_KEY_XF86Standby, Qt::Key_Standby>,
|
|
- Xkb2Qt<XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp>,
|
|
- Xkb2Qt<XKB_KEY_XF86MonBrightnessDown, Qt::Key_MonBrightnessDown>,
|
|
- Xkb2Qt<XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff>,
|
|
- Xkb2Qt<XKB_KEY_XF86KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp>,
|
|
- Xkb2Qt<XKB_KEY_XF86KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown>,
|
|
- Xkb2Qt<XKB_KEY_XF86PowerOff, Qt::Key_PowerOff>,
|
|
- Xkb2Qt<XKB_KEY_XF86WakeUp, Qt::Key_WakeUp>,
|
|
- Xkb2Qt<XKB_KEY_XF86Eject, Qt::Key_Eject>,
|
|
- Xkb2Qt<XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver>,
|
|
- Xkb2Qt<XKB_KEY_XF86WWW, Qt::Key_WWW>,
|
|
- Xkb2Qt<XKB_KEY_XF86Sleep, Qt::Key_Sleep>,
|
|
- Xkb2Qt<XKB_KEY_XF86LightBulb, Qt::Key_LightBulb>,
|
|
- Xkb2Qt<XKB_KEY_XF86Shop, Qt::Key_Shop>,
|
|
- Xkb2Qt<XKB_KEY_XF86History, Qt::Key_History>,
|
|
- Xkb2Qt<XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite>,
|
|
- Xkb2Qt<XKB_KEY_XF86HotLinks, Qt::Key_HotLinks>,
|
|
- Xkb2Qt<XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust>,
|
|
- Xkb2Qt<XKB_KEY_XF86Finance, Qt::Key_Finance>,
|
|
- Xkb2Qt<XKB_KEY_XF86Community, Qt::Key_Community>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind>,
|
|
- Xkb2Qt<XKB_KEY_XF86BackForward, Qt::Key_BackForward>,
|
|
- Xkb2Qt<XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft>,
|
|
- Xkb2Qt<XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight>,
|
|
- Xkb2Qt<XKB_KEY_XF86Book, Qt::Key_Book>,
|
|
- Xkb2Qt<XKB_KEY_XF86CD, Qt::Key_CD>,
|
|
- Xkb2Qt<XKB_KEY_XF86Calculater, Qt::Key_Calculator>,
|
|
- Xkb2Qt<XKB_KEY_XF86Clear, Qt::Key_Clear>,
|
|
- Xkb2Qt<XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab>,
|
|
- Xkb2Qt<XKB_KEY_XF86Close, Qt::Key_Close>,
|
|
- Xkb2Qt<XKB_KEY_XF86Copy, Qt::Key_Copy>,
|
|
- Xkb2Qt<XKB_KEY_XF86Cut, Qt::Key_Cut>,
|
|
- Xkb2Qt<XKB_KEY_XF86Display, Qt::Key_Display>,
|
|
- Xkb2Qt<XKB_KEY_XF86DOS, Qt::Key_DOS>,
|
|
- Xkb2Qt<XKB_KEY_XF86Documents, Qt::Key_Documents>,
|
|
- Xkb2Qt<XKB_KEY_XF86Excel, Qt::Key_Excel>,
|
|
- Xkb2Qt<XKB_KEY_XF86Explorer, Qt::Key_Explorer>,
|
|
- Xkb2Qt<XKB_KEY_XF86Game, Qt::Key_Game>,
|
|
- Xkb2Qt<XKB_KEY_XF86Go, Qt::Key_Go>,
|
|
- Xkb2Qt<XKB_KEY_XF86iTouch, Qt::Key_iTouch>,
|
|
- Xkb2Qt<XKB_KEY_XF86LogOff, Qt::Key_LogOff>,
|
|
- Xkb2Qt<XKB_KEY_XF86Market, Qt::Key_Market>,
|
|
- Xkb2Qt<XKB_KEY_XF86Meeting, Qt::Key_Meeting>,
|
|
- Xkb2Qt<XKB_KEY_XF86MenuKB, Qt::Key_MenuKB>,
|
|
- Xkb2Qt<XKB_KEY_XF86MenuPB, Qt::Key_MenuPB>,
|
|
- Xkb2Qt<XKB_KEY_XF86MySites, Qt::Key_MySites>,
|
|
- Xkb2Qt<XKB_KEY_XF86New, Qt::Key_New>,
|
|
- Xkb2Qt<XKB_KEY_XF86News, Qt::Key_News>,
|
|
- Xkb2Qt<XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome>,
|
|
- Xkb2Qt<XKB_KEY_XF86Open, Qt::Key_Open>,
|
|
- Xkb2Qt<XKB_KEY_XF86Option, Qt::Key_Option>,
|
|
- Xkb2Qt<XKB_KEY_XF86Paste, Qt::Key_Paste>,
|
|
- Xkb2Qt<XKB_KEY_XF86Phone, Qt::Key_Phone>,
|
|
- Xkb2Qt<XKB_KEY_XF86Reply, Qt::Key_Reply>,
|
|
- Xkb2Qt<XKB_KEY_XF86Reload, Qt::Key_Reload>,
|
|
- Xkb2Qt<XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows>,
|
|
- Xkb2Qt<XKB_KEY_XF86RotationPB, Qt::Key_RotationPB>,
|
|
- Xkb2Qt<XKB_KEY_XF86RotationKB, Qt::Key_RotationKB>,
|
|
- Xkb2Qt<XKB_KEY_XF86Save, Qt::Key_Save>,
|
|
- Xkb2Qt<XKB_KEY_XF86Send, Qt::Key_Send>,
|
|
- Xkb2Qt<XKB_KEY_XF86Spell, Qt::Key_Spell>,
|
|
- Xkb2Qt<XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen>,
|
|
- Xkb2Qt<XKB_KEY_XF86Support, Qt::Key_Support>,
|
|
- Xkb2Qt<XKB_KEY_XF86TaskPane, Qt::Key_TaskPane>,
|
|
- Xkb2Qt<XKB_KEY_XF86Terminal, Qt::Key_Terminal>,
|
|
- Xkb2Qt<XKB_KEY_XF86Tools, Qt::Key_Tools>,
|
|
- Xkb2Qt<XKB_KEY_XF86Travel, Qt::Key_Travel>,
|
|
- Xkb2Qt<XKB_KEY_XF86Video, Qt::Key_Video>,
|
|
- Xkb2Qt<XKB_KEY_XF86Word, Qt::Key_Word>,
|
|
- Xkb2Qt<XKB_KEY_XF86Xfer, Qt::Key_Xfer>,
|
|
- Xkb2Qt<XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn>,
|
|
- Xkb2Qt<XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut>,
|
|
- Xkb2Qt<XKB_KEY_XF86Away, Qt::Key_Away>,
|
|
- Xkb2Qt<XKB_KEY_XF86Messenger, Qt::Key_Messenger>,
|
|
- Xkb2Qt<XKB_KEY_XF86WebCam, Qt::Key_WebCam>,
|
|
- Xkb2Qt<XKB_KEY_XF86MailForward, Qt::Key_MailForward>,
|
|
- Xkb2Qt<XKB_KEY_XF86Pictures, Qt::Key_Pictures>,
|
|
- Xkb2Qt<XKB_KEY_XF86Music, Qt::Key_Music>,
|
|
- Xkb2Qt<XKB_KEY_XF86Battery, Qt::Key_Battery>,
|
|
- Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
|
|
- Xkb2Qt<XKB_KEY_XF86WLAN, Qt::Key_WLAN>,
|
|
- Xkb2Qt<XKB_KEY_XF86UWB, Qt::Key_UWB>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioForward, Qt::Key_AudioForward>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay>,
|
|
- Xkb2Qt<XKB_KEY_XF86Subtitle, Qt::Key_Subtitle>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack>,
|
|
- Xkb2Qt<XKB_KEY_XF86Time, Qt::Key_Time>,
|
|
- Xkb2Qt<XKB_KEY_XF86Select, Qt::Key_Select>,
|
|
- Xkb2Qt<XKB_KEY_XF86View, Qt::Key_View>,
|
|
- Xkb2Qt<XKB_KEY_XF86TopMenu, Qt::Key_TopMenu>,
|
|
- Xkb2Qt<XKB_KEY_XF86Red, Qt::Key_Red>,
|
|
- Xkb2Qt<XKB_KEY_XF86Green, Qt::Key_Green>,
|
|
- Xkb2Qt<XKB_KEY_XF86Yellow, Qt::Key_Yellow>,
|
|
- Xkb2Qt<XKB_KEY_XF86Blue, Qt::Key_Blue>,
|
|
- Xkb2Qt<XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth>,
|
|
- Xkb2Qt<XKB_KEY_XF86Suspend, Qt::Key_Suspend>,
|
|
- Xkb2Qt<XKB_KEY_XF86Hibernate, Qt::Key_Hibernate>,
|
|
- Xkb2Qt<XKB_KEY_XF86TouchpadToggle, Qt::Key_TouchpadToggle>,
|
|
- Xkb2Qt<XKB_KEY_XF86TouchpadOn, Qt::Key_TouchpadOn>,
|
|
- Xkb2Qt<XKB_KEY_XF86TouchpadOff, Qt::Key_TouchpadOff>,
|
|
- Xkb2Qt<XKB_KEY_XF86AudioMicMute, Qt::Key_MicMute>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch0, Qt::Key_Launch2>, // ### Qt 6: remap properly
|
|
- Xkb2Qt<XKB_KEY_XF86Launch1, Qt::Key_Launch3>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch2, Qt::Key_Launch4>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch3, Qt::Key_Launch5>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch4, Qt::Key_Launch6>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch5, Qt::Key_Launch7>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch6, Qt::Key_Launch8>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch7, Qt::Key_Launch9>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch8, Qt::Key_LaunchA>,
|
|
- Xkb2Qt<XKB_KEY_XF86Launch9, Qt::Key_LaunchB>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchA, Qt::Key_LaunchC>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchB, Qt::Key_LaunchD>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchC, Qt::Key_LaunchE>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchD, Qt::Key_LaunchF>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchE, Qt::Key_LaunchG>,
|
|
- Xkb2Qt<XKB_KEY_XF86LaunchF, Qt::Key_LaunchH>
|
|
- >::Data{}
|
|
-);
|
|
-
|
|
-// Possible modifier states.
|
|
-static const Qt::KeyboardModifiers ModsTbl[] = {
|
|
- Qt::NoModifier, // 0
|
|
- Qt::ShiftModifier, // 1
|
|
- Qt::ControlModifier, // 2
|
|
- Qt::ControlModifier | Qt::ShiftModifier, // 3
|
|
- Qt::AltModifier, // 4
|
|
- Qt::AltModifier | Qt::ShiftModifier, // 5
|
|
- Qt::AltModifier | Qt::ControlModifier, // 6
|
|
- Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7
|
|
- Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
|
|
-};
|
|
+QT_BEGIN_NAMESPACE
|
|
|
|
Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const
|
|
{
|
|
- Qt::KeyboardModifiers ret = 0;
|
|
+ Qt::KeyboardModifiers ret = Qt::NoModifier;
|
|
if (s & XCB_MOD_MASK_SHIFT)
|
|
ret |= Qt::ShiftModifier;
|
|
if (s & XCB_MOD_MASK_CONTROL)
|
|
@@ -473,7 +88,7 @@ static xcb_keysym_t getUnshiftedXKey(xcb_keysym_t unshifted, xcb_keysym_t shifte
|
|
|
|
xcb_keysym_t xlower;
|
|
xcb_keysym_t xupper;
|
|
- xkbcommon_XConvertCase(unshifted, &xlower, &xupper);
|
|
+ QXkbCommon::xkbcommon_XConvertCase(unshifted, &xlower, &xupper);
|
|
|
|
if (xlower != xupper // Check if symbol is cased
|
|
&& unshifted == xupper) { // Unshifted must be upper case
|
|
@@ -805,7 +420,12 @@ void QXcbKeyboard::updateKeymap()
|
|
|
|
updateXKBMods();
|
|
|
|
- checkForLatinLayout();
|
|
+ QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
|
|
+}
|
|
+
|
|
+QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
|
|
+{
|
|
+ return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
|
|
}
|
|
|
|
#if QT_CONFIG(xkb)
|
|
@@ -918,272 +538,6 @@ void QXcbKeyboard::updateXKBMods()
|
|
xkb_mods.mod5 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod5");
|
|
}
|
|
|
|
-static bool isLatin(xkb_keysym_t sym)
|
|
-{
|
|
- return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z'));
|
|
-}
|
|
-
|
|
-void QXcbKeyboard::checkForLatinLayout() const
|
|
-{
|
|
- const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(m_xkbKeymap.get());
|
|
- const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get());
|
|
- const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get());
|
|
-
|
|
- const xkb_keysym_t *keysyms = nullptr;
|
|
- int nrLatinKeys = 0;
|
|
- for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) {
|
|
- for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
|
|
- xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), code, layout, 0, &keysyms);
|
|
- if (keysyms && isLatin(keysyms[0]))
|
|
- nrLatinKeys++;
|
|
- if (nrLatinKeys > 10) // arbitrarily chosen threshold
|
|
- return;
|
|
- }
|
|
- }
|
|
- // This means that lookupLatinKeysym() will not find anything and latin
|
|
- // key shortcuts might not work. This is a bug in the affected desktop
|
|
- // environment. Usually can be solved via system settings by adding e.g. 'us'
|
|
- // layout to the list of seleced layouts, or by using command line, "setxkbmap
|
|
- // -layout rus,en". The position of latin key based layout in the list of the
|
|
- // selected layouts is irrelevant. Properly functioning desktop environments
|
|
- // handle this behind the scenes, even if no latin key based layout has been
|
|
- // explicitly listed in the selected layouts.
|
|
- qCWarning(lcQpaKeyboard, "no keyboard layouts with latin keys present");
|
|
-}
|
|
-
|
|
-xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const
|
|
-{
|
|
- xkb_layout_index_t layout;
|
|
- xkb_keysym_t sym = XKB_KEY_NoSymbol;
|
|
- const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(m_xkbKeymap.get(), keycode);
|
|
- const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(m_xkbState.get(), keycode);
|
|
- // Look at user layouts in the order in which they are defined in system
|
|
- // settings to find a latin keysym.
|
|
- for (layout = 0; layout < layoutCount; ++layout) {
|
|
- if (layout == currentLayout)
|
|
- continue;
|
|
- const xkb_keysym_t *syms;
|
|
- xkb_level_index_t level = xkb_state_key_get_level(m_xkbState.get(), keycode, layout);
|
|
- if (xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), keycode, layout, level, &syms) != 1)
|
|
- continue;
|
|
- if (isLatin(syms[0])) {
|
|
- sym = syms[0];
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- if (sym == XKB_KEY_NoSymbol)
|
|
- return sym;
|
|
-
|
|
- xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED);
|
|
- xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED);
|
|
-
|
|
- // Check for uniqueness, consider the following setup:
|
|
- // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active).
|
|
- // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+<physical x key>,
|
|
- // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained
|
|
- // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired
|
|
- // then the obtained key is not unique. This prevents ctrl+<physical q key> from generating a ctrl+q
|
|
- // shortcut in the above described setup. We don't want ctrl+<physical x key> and ctrl+<physical q key> to
|
|
- // generate the same shortcut event in this case.
|
|
- const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get());
|
|
- const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get());
|
|
- ScopedXKBState state(xkb_state_new(m_xkbKeymap.get()));
|
|
- for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) {
|
|
- xkb_state_update_mask(state.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout);
|
|
- for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) {
|
|
- xkb_keysym_t prevSym = xkb_state_key_get_one_sym(state.get(), code);
|
|
- if (prevSym == sym) {
|
|
- sym = XKB_KEY_NoSymbol;
|
|
- break;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- return sym;
|
|
-}
|
|
-
|
|
-static const char *qtKeyName(int qtKey)
|
|
-{
|
|
- int keyEnumIndex = qt_getQtMetaObject()->indexOfEnumerator("Key");
|
|
- QMetaEnum keyEnum = qt_getQtMetaObject()->enumerator(keyEnumIndex);
|
|
- return keyEnum.valueToKey(qtKey);
|
|
-}
|
|
-
|
|
-QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
|
|
-{
|
|
- // turn off the modifier bits which doesn't participate in shortcuts
|
|
- Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier;
|
|
- Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded;
|
|
- // create a fresh kb state and test against the relevant modifier combinations
|
|
- struct xkb_state *kb_state = xkb_state_new(m_xkbKeymap.get());
|
|
- if (!kb_state) {
|
|
- qWarning("QXcbKeyboard: failed to compile xkb keymap!");
|
|
- return QList<int>();
|
|
- }
|
|
- // get kb state from the master xkb_state and update the temporary kb_state
|
|
- xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(m_xkbState.get(), XKB_STATE_LAYOUT_LOCKED);
|
|
- xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED);
|
|
- xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED);
|
|
- xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_DEPRESSED);
|
|
-
|
|
- xkb_state_update_mask(kb_state, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
- quint32 keycode = event->nativeScanCode();
|
|
- // handle shortcuts for level three and above
|
|
- xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(kb_state, keycode);
|
|
- xkb_level_index_t levelIndex = 0;
|
|
- if (layoutIndex != XKB_LAYOUT_INVALID) {
|
|
- levelIndex = xkb_state_key_get_level(kb_state, keycode, layoutIndex);
|
|
- if (levelIndex == XKB_LEVEL_INVALID)
|
|
- levelIndex = 0;
|
|
- }
|
|
- if (levelIndex <= 1)
|
|
- xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
-
|
|
- xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode);
|
|
- if (sym == XKB_KEY_NoSymbol) {
|
|
- xkb_state_unref(kb_state);
|
|
- return QList<int>();
|
|
- }
|
|
-
|
|
- QList<int> result;
|
|
- int baseQtKey = keysymToQtKey(sym, modifiers, kb_state, keycode);
|
|
- if (baseQtKey)
|
|
- result += (baseQtKey + modifiers);
|
|
-
|
|
- xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Shift");
|
|
- xkb_mod_index_t altMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Alt");
|
|
- xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Control");
|
|
- xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Meta");
|
|
-
|
|
- Q_ASSERT(shiftMod < 32);
|
|
- Q_ASSERT(altMod < 32);
|
|
- Q_ASSERT(controlMod < 32);
|
|
-
|
|
- xkb_mod_mask_t depressed;
|
|
- int qtKey = 0;
|
|
- // obtain a list of possible shortcuts for the given key event
|
|
- for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) {
|
|
- Qt::KeyboardModifiers neededMods = ModsTbl[i];
|
|
- if ((modifiers & neededMods) == neededMods) {
|
|
- if (i == 8) {
|
|
- if (isLatin(baseQtKey))
|
|
- continue;
|
|
- // add a latin key as a fall back key
|
|
- sym = lookupLatinKeysym(keycode);
|
|
- } else {
|
|
- depressed = 0;
|
|
- if (neededMods & Qt::AltModifier)
|
|
- depressed |= (1 << altMod);
|
|
- if (neededMods & Qt::ShiftModifier)
|
|
- depressed |= (1 << shiftMod);
|
|
- if (neededMods & Qt::ControlModifier)
|
|
- depressed |= (1 << controlMod);
|
|
- if (metaMod < 32 && neededMods & Qt::MetaModifier)
|
|
- depressed |= (1 << metaMod);
|
|
- xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout);
|
|
- sym = xkb_state_key_get_one_sym(kb_state, keycode);
|
|
- }
|
|
- if (sym == XKB_KEY_NoSymbol)
|
|
- continue;
|
|
-
|
|
- Qt::KeyboardModifiers mods = modifiers & ~neededMods;
|
|
- qtKey = keysymToQtKey(sym, mods, kb_state, keycode);
|
|
- if (!qtKey || qtKey == baseQtKey)
|
|
- continue;
|
|
-
|
|
- // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
|
|
- // but Ctrl++ is more specific than +, so we should skip the last one
|
|
- bool ambiguous = false;
|
|
- for (int shortcut : qAsConst(result)) {
|
|
- if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) {
|
|
- ambiguous = true;
|
|
- break;
|
|
- }
|
|
- }
|
|
- if (ambiguous)
|
|
- continue;
|
|
-
|
|
- result += (qtKey + mods);
|
|
- }
|
|
- }
|
|
- xkb_state_unref(kb_state);
|
|
- return result;
|
|
-}
|
|
-
|
|
-int QXcbKeyboard::keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
- struct xkb_state *state, xcb_keycode_t code) const
|
|
-{
|
|
- int qtKey = 0;
|
|
-
|
|
- // lookup from direct mapping
|
|
- if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
|
|
- // function keys
|
|
- qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1);
|
|
- } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) {
|
|
- // numeric keypad keys
|
|
- qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0);
|
|
- } else if (isLatin(keysym)) {
|
|
- qtKey = xkbcommon_xkb_keysym_to_upper(keysym);
|
|
- } else {
|
|
- // check if we have a direct mapping
|
|
- xkb2qt_t searchKey{keysym, 0};
|
|
- auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey);
|
|
- if (it != KeyTbl.end() && !(searchKey < *it))
|
|
- qtKey = it->qt;
|
|
- }
|
|
-
|
|
- QString text;
|
|
- bool fromUnicode = qtKey == 0;
|
|
- if (fromUnicode) { // lookup from unicode
|
|
- if (modifiers & Qt::ControlModifier) {
|
|
- // Control modifier changes the text to ASCII control character, therefore we
|
|
- // can't use this text to map keysym to a qt key. We can use the same keysym
|
|
- // (it is not affectd by transformation) to obtain untransformed text. For details
|
|
- // see "Appendix A. Default Symbol Transformations" in the XKB specification.
|
|
- text = lookupStringNoKeysymTransformations(keysym);
|
|
- } else {
|
|
- text = lookupString(state, code);
|
|
- }
|
|
- if (!text.isEmpty()) {
|
|
- if (text.unicode()->isDigit()) {
|
|
- // Ensures that also non-latin digits are mapped to corresponding qt keys,
|
|
- // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2.
|
|
- qtKey = Qt::Key_0 + text.unicode()->digitValue();
|
|
- } else {
|
|
- qtKey = text.unicode()->toUpper().unicode();
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- if (rmod_masks.meta) {
|
|
- // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
|
|
- if (rmod_masks.meta == rmod_masks.super && (qtKey == Qt::Key_Super_L
|
|
- || qtKey == Qt::Key_Super_R)) {
|
|
- qtKey = Qt::Key_Meta;
|
|
- } else if (rmod_masks.meta == rmod_masks.hyper && (qtKey == Qt::Key_Hyper_L
|
|
- || qtKey == Qt::Key_Hyper_R)) {
|
|
- qtKey = Qt::Key_Meta;
|
|
- }
|
|
- }
|
|
-
|
|
- if (Q_UNLIKELY(lcQpaKeyboard().isDebugEnabled())) {
|
|
- char keysymName[64];
|
|
- xkb_keysym_get_name(keysym, keysymName, sizeof(keysymName));
|
|
- QString keysymInHex = QString(QStringLiteral("0x%1")).arg(keysym, 0, 16);
|
|
- if (qtKeyName(qtKey)) {
|
|
- qCDebug(lcQpaKeyboard).nospace() << "keysym: " << keysymName << "("
|
|
- << keysymInHex << ") mapped to Qt::" << qtKeyName(qtKey) << " | text: " << text
|
|
- << " | qt key: " << qtKey << " mapped from unicode number: " << fromUnicode;
|
|
- } else {
|
|
- qCDebug(lcQpaKeyboard).nospace() << "no Qt::Key for keysym: " << keysymName
|
|
- << "(" << keysymInHex << ") | text: " << text << " | qt key: " << qtKey;
|
|
- }
|
|
- }
|
|
-
|
|
- return qtKey;
|
|
-}
|
|
-
|
|
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
|
|
: QXcbObject(connection)
|
|
{
|
|
@@ -1514,6 +868,12 @@ void QXcbKeyboard::resolveMaskConflicts()
|
|
rmod_masks.meta = rmod_masks.hyper;
|
|
}
|
|
}
|
|
+
|
|
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
|
|
+ if (rmod_masks.meta && rmod_masks.meta == rmod_masks.super)
|
|
+ m_superAsMeta = true;
|
|
+ if (rmod_masks.meta && rmod_masks.meta == rmod_masks.hyper)
|
|
+ m_hyperAsMeta = true;
|
|
}
|
|
|
|
void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code,
|
|
@@ -1529,7 +889,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|
if (type == QEvent::KeyPress)
|
|
targetWindow->updateNetWmUserTime(time);
|
|
|
|
- ScopedXKBState sendEventState;
|
|
+ QXkbCommon::ScopedXKBState sendEventState;
|
|
if (fromSendEvent) {
|
|
// Have a temporary keyboard state filled in from state
|
|
// this way we allow for synthetic events to have different state
|
|
@@ -1546,30 +906,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|
struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get();
|
|
|
|
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code);
|
|
- QString text = lookupString(xkbState, code);
|
|
+ QString text = QXkbCommon::lookupString(xkbState, code);
|
|
|
|
Qt::KeyboardModifiers modifiers = translateModifiers(state);
|
|
- if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9)
|
|
+ if (QXkbCommon::isKeypad(sym))
|
|
modifiers |= Qt::KeypadModifier;
|
|
|
|
- // Note 1: All standard key sequences on linux (as defined in platform theme)
|
|
- // that use a latin character also contain a control modifier, which is why
|
|
- // checking for Qt::ControlModifier is sufficient here. It is possible to
|
|
- // override QPlatformTheme::keyBindings() and provide custom sequences for
|
|
- // QKeySequence::StandardKey. Custom sequences probably should respect this
|
|
- // convention (alternatively, we could test against other modifiers here).
|
|
- // Note 2: The possibleKeys() shorcut mechanism is not affected by this value
|
|
- // adjustment and does its own thing.
|
|
- xcb_keysym_t latinKeysym = XKB_KEY_NoSymbol;
|
|
- if (modifiers & Qt::ControlModifier) {
|
|
- // With standard shortcuts we should prefer a latin character, this is
|
|
- // in checks like "event == QKeySequence::Copy".
|
|
- if (!isLatin(sym))
|
|
- latinKeysym = lookupLatinKeysym(code);
|
|
- }
|
|
-
|
|
- int qtcode = keysymToQtKey(latinKeysym != XKB_KEY_NoSymbol ? latinKeysym : sym,
|
|
- modifiers, xkbState, code);
|
|
+ int qtcode = QXkbCommon::keysymToQtKey(sym, modifiers, xkbState, code, m_superAsMeta, m_hyperAsMeta);
|
|
|
|
if (type == QEvent::KeyPress) {
|
|
if (m_isAutoRepeat && m_autoRepeatCode != code)
|
|
@@ -1611,28 +954,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
|
|
}
|
|
}
|
|
|
|
-QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
|
|
-{
|
|
- QVarLengthArray<char, 32> chars(32);
|
|
- const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
|
|
- if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
|
|
- chars.resize(size + 1);
|
|
- xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
|
|
- }
|
|
- return QString::fromUtf8(chars.constData(), size);
|
|
-}
|
|
-
|
|
-QString QXcbKeyboard::lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const
|
|
-{
|
|
- QVarLengthArray<char, 32> chars(32);
|
|
- const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
|
|
- if (Q_UNLIKELY(size > chars.size())) {
|
|
- chars.resize(size);
|
|
- xkb_keysym_to_utf8(keysym, chars.data(), chars.size());
|
|
- }
|
|
- return QString::fromUtf8(chars.constData(), size);
|
|
-}
|
|
-
|
|
static bool fromSendEvent(const void *event)
|
|
{
|
|
// From X11 protocol: Every event contains an 8-bit type code. The most
|
|
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
|
index f8490592b7..75071d045f 100644
|
|
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
|
|
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
|
|
@@ -50,16 +50,12 @@
|
|
#endif
|
|
|
|
#include <xkbcommon/xkbcommon.h>
|
|
-#if QT_CONFIG(xkb)
|
|
-#include <xkbcommon/xkbcommon-x11.h>
|
|
-#endif
|
|
+#include <QtXkbCommonSupport/private/qxkbcommon_p.h>
|
|
|
|
#include <QEvent>
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
-class QWindow;
|
|
-
|
|
class QXcbKeyboard : public QXcbObject
|
|
{
|
|
public:
|
|
@@ -75,7 +71,7 @@ public:
|
|
Qt::KeyboardModifiers translateModifiers(int s) const;
|
|
void updateKeymap(xcb_mapping_notify_event_t *event);
|
|
void updateKeymap();
|
|
- QList<int> possibleKeys(const QKeyEvent *e) const;
|
|
+ QList<int> possibleKeys(const QKeyEvent *event) const;
|
|
|
|
// when XKEYBOARD not present on the X server
|
|
void updateXKBMods();
|
|
@@ -96,10 +92,6 @@ protected:
|
|
quint16 state, xcb_timestamp_t time, bool fromSendEvent);
|
|
|
|
void resolveMaskConflicts();
|
|
- QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
|
|
- QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const;
|
|
- int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
|
|
- struct xkb_state *state, xcb_keycode_t code) const;
|
|
|
|
typedef QMap<xcb_keysym_t, int> KeysymModifierMap;
|
|
struct xkb_keymap *keymapFromCore(const KeysymModifierMap &keysymMods);
|
|
@@ -111,9 +103,6 @@ protected:
|
|
void updateVModMapping();
|
|
void updateVModToRModMapping();
|
|
|
|
- xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const;
|
|
- void checkForLatinLayout() const;
|
|
-
|
|
private:
|
|
bool m_config = false;
|
|
bool m_isAutoRepeat = false;
|
|
@@ -148,22 +137,12 @@ private:
|
|
int core_device_id;
|
|
#endif
|
|
|
|
- struct XKBStateDeleter {
|
|
- void operator()(struct xkb_state *state) const { return xkb_state_unref(state); }
|
|
- };
|
|
- struct XKBKeymapDeleter {
|
|
- void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); }
|
|
- };
|
|
- struct XKBContextDeleter {
|
|
- void operator()(struct xkb_context *context) const { return xkb_context_unref(context); }
|
|
- };
|
|
- using ScopedXKBState = std::unique_ptr<struct xkb_state, XKBStateDeleter>;
|
|
- using ScopedXKBKeymap = std::unique_ptr<struct xkb_keymap, XKBKeymapDeleter>;
|
|
- using ScopedXKBContext = std::unique_ptr<struct xkb_context, XKBContextDeleter>;
|
|
+ QXkbCommon::ScopedXKBState m_xkbState;
|
|
+ QXkbCommon::ScopedXKBKeymap m_xkbKeymap;
|
|
+ QXkbCommon::ScopedXKBContext m_xkbContext;
|
|
|
|
- ScopedXKBState m_xkbState;
|
|
- ScopedXKBKeymap m_xkbKeymap;
|
|
- ScopedXKBContext m_xkbContext;
|
|
+ bool m_superAsMeta = false;
|
|
+ bool m_hyperAsMeta = false;
|
|
};
|
|
|
|
QT_END_NAMESPACE
|
|
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
|
|
index db3d6629b3..34c671c8c7 100644
|
|
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
|
|
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
|
|
@@ -6,7 +6,8 @@ QT += \
|
|
core-private gui-private \
|
|
service_support-private theme_support-private \
|
|
fontdatabase_support-private \
|
|
- edid_support-private
|
|
+ edid_support-private \
|
|
+ xkbcommon_support-private
|
|
|
|
qtHaveModule(linuxaccessibility_support-private): \
|
|
QT += linuxaccessibility_support-private
|
|
@@ -52,7 +53,6 @@ HEADERS = \
|
|
qxcbimage.h \
|
|
qxcbxsettings.h \
|
|
qxcbsystemtraytracker.h \
|
|
- qxcbxkbcommon.h \
|
|
qxcbeventqueue.h \
|
|
qxcbeventdispatcher.h \
|
|
qxcbconnection_basic.h \
|
|
diff --git a/sync.profile b/sync.profile
|
|
index a6d0e2a4a7..e6fc285573 100644
|
|
--- a/sync.profile
|
|
+++ b/sync.profile
|
|
@@ -18,6 +18,7 @@
|
|
"QtEventDispatcherSupport" => "$basedir/src/platformsupport/eventdispatchers",
|
|
"QtFontDatabaseSupport" => "$basedir/src/platformsupport/fontdatabases",
|
|
"QtInputSupport" => "$basedir/src/platformsupport/input",
|
|
+ "QtXkbCommonSupport" => "$basedir/src/platformsupport/input/xkbcommon",
|
|
"QtPlatformCompositorSupport" => "$basedir/src/platformsupport/platformcompositor",
|
|
"QtServiceSupport" => "$basedir/src/platformsupport/services",
|
|
"QtThemeSupport" => "$basedir/src/platformsupport/themes",
|