From 4d075077393ce7380214871b6ca47132fdee56ed Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Mon, 8 Mar 2021 20:37:00 +0200 Subject: [PATCH] Auto-Type: Support multiple Xkb layouts Completely rewritten XCB Auto-Type keymap system. - supports multiple simultaneous layouts - prefers current layout if it has all keysyms available - removed hardcoded KeySymMap - removed clunky custom KeySym emulation Biggest breaking change is removing KeySym emulation for keys that do not exist in any of the layouts currently in use. It would be possible to make it work but if you are trying to type syms that are not available in any of your layouts you are abusing it. It also adds unnecessary complexity and opens up timing issues when the keymap is modified on-the-fly. Now we are just reading it. This also workarounds a Qt related issue where QX11Info::display() returns a connection to X server that fails to receive updated keymap data when client settings change. We use our own connection now to get it working. --- src/autotype/AutoType.cpp | 1 + src/autotype/AutoTypeAction.cpp | 5 + src/autotype/AutoTypeAction.h | 7 + src/autotype/mac/AutoTypeMac.cpp | 5 + src/autotype/mac/AutoTypeMac.h | 1 + src/autotype/test/AutoTypeTest.cpp | 5 + src/autotype/test/AutoTypeTest.h | 1 + src/autotype/windows/AutoTypeWindows.cpp | 5 + src/autotype/windows/AutoTypeWindows.h | 1 + src/autotype/xcb/AutoTypeXCB.cpp | 204 ++++++++--------------- src/autotype/xcb/AutoTypeXCB.h | 23 +-- src/gui/osutils/nixutils/KeySymMap.h | 171 ------------------- src/gui/osutils/nixutils/NixUtils.cpp | 20 --- src/gui/osutils/nixutils/NixUtils.h | 3 - src/gui/osutils/nixutils/X11Funcs.cpp | 16 +- 15 files changed, 120 insertions(+), 348 deletions(-) delete mode 100644 src/gui/osutils/nixutils/KeySymMap.h diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index 513d8590..f226f59f 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -496,6 +496,7 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin const int maxRepetition = 100; QList> actions; + actions << QSharedPointer::create(); actions << QSharedPointer::create(qMax(0, config()->get(Config::AutoTypeDelay).toInt()), true); // Replace escaped braces with a template for easier regex diff --git a/src/autotype/AutoTypeAction.cpp b/src/autotype/AutoTypeAction.cpp index 46924337..587dee0f 100644 --- a/src/autotype/AutoTypeAction.cpp +++ b/src/autotype/AutoTypeAction.cpp @@ -58,3 +58,8 @@ void AutoTypeClearField::exec(AutoTypeExecutor* executor) const { executor->execClearField(this); } + +void AutoTypeBegin::exec(AutoTypeExecutor* executor) const +{ + executor->execBegin(this); +} diff --git a/src/autotype/AutoTypeAction.h b/src/autotype/AutoTypeAction.h index fdb06873..cf5ce657 100644 --- a/src/autotype/AutoTypeAction.h +++ b/src/autotype/AutoTypeAction.h @@ -61,10 +61,17 @@ public: void exec(AutoTypeExecutor* executor) const override; }; +class KEEPASSXC_EXPORT AutoTypeBegin : public AutoTypeAction +{ +public: + void exec(AutoTypeExecutor* executor) const override; +}; + class KEEPASSXC_EXPORT AutoTypeExecutor { public: virtual ~AutoTypeExecutor() = default; + virtual void execBegin(const AutoTypeBegin* action) = 0; virtual void execType(const AutoTypeKey* action) = 0; virtual void execClearField(const AutoTypeClearField* action) = 0; diff --git a/src/autotype/mac/AutoTypeMac.cpp b/src/autotype/mac/AutoTypeMac.cpp index 1ae8b38d..a8f31f6c 100644 --- a/src/autotype/mac/AutoTypeMac.cpp +++ b/src/autotype/mac/AutoTypeMac.cpp @@ -215,6 +215,11 @@ AutoTypeExecutorMac::AutoTypeExecutorMac(AutoTypePlatformMac* platform) { } +void AutoTypeExecutorMac::execBegin(const AutoTypeBegin* action) +{ + Q_UNUSED(action); +} + void AutoTypeExecutorMac::execType(const AutoTypeKey* action) { if (action->modifiers & Qt::ShiftModifier) { diff --git a/src/autotype/mac/AutoTypeMac.h b/src/autotype/mac/AutoTypeMac.h index f23a7c1d..46e303c9 100644 --- a/src/autotype/mac/AutoTypeMac.h +++ b/src/autotype/mac/AutoTypeMac.h @@ -57,6 +57,7 @@ class AutoTypeExecutorMac : public AutoTypeExecutor public: explicit AutoTypeExecutorMac(AutoTypePlatformMac* platform); + void execBegin(const AutoTypeBegin* action) override; void execType(const AutoTypeKey* action) override; void execClearField(const AutoTypeClearField* action) override; diff --git a/src/autotype/test/AutoTypeTest.cpp b/src/autotype/test/AutoTypeTest.cpp index 906edae3..98fc42e0 100644 --- a/src/autotype/test/AutoTypeTest.cpp +++ b/src/autotype/test/AutoTypeTest.cpp @@ -102,6 +102,11 @@ AutoTypeExecutorTest::AutoTypeExecutorTest(AutoTypePlatformTest* platform) { } +void AutoTypeExecutorTest::execBegin(const AutoTypeBegin* action) +{ + Q_UNUSED(action); +} + void AutoTypeExecutorTest::execType(const AutoTypeKey* action) { m_platform->addAction(action); diff --git a/src/autotype/test/AutoTypeTest.h b/src/autotype/test/AutoTypeTest.h index 9758d281..6ec41c41 100644 --- a/src/autotype/test/AutoTypeTest.h +++ b/src/autotype/test/AutoTypeTest.h @@ -64,6 +64,7 @@ class AutoTypeExecutorTest : public AutoTypeExecutor public: explicit AutoTypeExecutorTest(AutoTypePlatformTest* platform); + void execBegin(const AutoTypeBegin* action) override; void execType(const AutoTypeKey* action) override; void execClearField(const AutoTypeClearField* action) override; diff --git a/src/autotype/windows/AutoTypeWindows.cpp b/src/autotype/windows/AutoTypeWindows.cpp index 6e796e5c..66aaeb4a 100644 --- a/src/autotype/windows/AutoTypeWindows.cpp +++ b/src/autotype/windows/AutoTypeWindows.cpp @@ -226,6 +226,11 @@ AutoTypeExecutorWin::AutoTypeExecutorWin(AutoTypePlatformWin* platform) { } +void AutoTypeExecutorWin::execBegin(const AutoTypeBegin* action) +{ + Q_UNUSED(action); +} + void AutoTypeExecutorWin::execType(const AutoTypeKey* action) { if (action->modifiers & Qt::ShiftModifier) { diff --git a/src/autotype/windows/AutoTypeWindows.h b/src/autotype/windows/AutoTypeWindows.h index fe3ea82e..1c1df10d 100644 --- a/src/autotype/windows/AutoTypeWindows.h +++ b/src/autotype/windows/AutoTypeWindows.h @@ -54,6 +54,7 @@ class AutoTypeExecutorWin : public AutoTypeExecutor public: explicit AutoTypeExecutorWin(AutoTypePlatformWin* platform); + void execBegin(const AutoTypeBegin* action) override; void execType(const AutoTypeKey* action) override; void execClearField(const AutoTypeClearField* action) override; diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp index 21a1a993..88e26cf3 100644 --- a/src/autotype/xcb/AutoTypeXCB.cpp +++ b/src/autotype/xcb/AutoTypeXCB.cpp @@ -21,7 +21,8 @@ AutoTypePlatformX11::AutoTypePlatformX11() { - m_dpy = QX11Info::display(); + // Qt handles XCB slightly differently so we open our own connection + m_dpy = XOpenDisplay(XDisplayString(QX11Info::display())); m_rootWindow = QX11Info::appRootWindow(); m_atomWmState = XInternAtom(m_dpy, "WM_STATE", True); @@ -42,15 +43,9 @@ AutoTypePlatformX11::AutoTypePlatformX11() m_classBlacklist << "xfdesktop" << "xfce4-panel"; // Xfce 4 - m_keysymTable = nullptr; m_xkb = nullptr; - m_remapKeycode = 0; - m_currentRemapKeysym = NoSymbol; m_loaded = true; - - connect(nixUtils(), &NixUtils::keymapChanged, this, [this] { updateKeymap(); }); - updateKeymap(); } bool AutoTypePlatformX11::isAvailable() @@ -65,34 +60,21 @@ bool AutoTypePlatformX11::isAvailable() return false; } - if (!m_xkb) { - XkbDescPtr kbd = getKeyboard(); - - if (!kbd) { - return false; - } - - XkbFreeKeyboard(kbd, XkbAllComponentsMask, True); - } - return true; } void AutoTypePlatformX11::unload() { - // Restore the KeyboardMapping to its original state. - if (m_currentRemapKeysym != NoSymbol) { - AddKeysym(NoSymbol); - } - - if (m_keysymTable) { - XFree(m_keysymTable); - } + m_keymap.clear(); if (m_xkb) { XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); + m_xkb = nullptr; } + XCloseDisplay(m_dpy); + m_dpy = nullptr; + m_loaded = false; } @@ -304,22 +286,30 @@ void AutoTypePlatformX11::updateKeymap() if (m_xkb) { XkbFreeKeyboard(m_xkb, XkbAllComponentsMask, True); } - m_xkb = getKeyboard(); + m_xkb = XkbGetMap(m_dpy, XkbAllClientInfoMask, XkbUseCoreKbd); - XDisplayKeycodes(m_dpy, &m_minKeycode, &m_maxKeycode); - if (m_keysymTable != nullptr) { - XFree(m_keysymTable); - } - m_keysymTable = XGetKeyboardMapping(m_dpy, m_minKeycode, m_maxKeycode - m_minKeycode + 1, &m_keysymPerKeycode); + /* Build updated keymap */ + m_keymap.clear(); - /* determine the keycode to use for remapped keys */ - if (m_remapKeycode == 0 || !isRemapKeycodeValid()) { - for (int keycode = m_minKeycode; keycode <= m_maxKeycode; keycode++) { - int inx = (keycode - m_minKeycode) * m_keysymPerKeycode; - if (m_keysymTable[inx] == NoSymbol) { - m_remapKeycode = keycode; - m_currentRemapKeysym = NoSymbol; - break; + for (int ckeycode = m_xkb->min_key_code; ckeycode < m_xkb->max_key_code; ckeycode++) { + int groups = XkbKeyNumGroups(m_xkb, ckeycode); + + for (int cgroup = 0; cgroup < groups; cgroup++) { + XkbKeyTypePtr type = XkbKeyKeyType(m_xkb, ckeycode, cgroup); + + for (int clevel = 0; clevel < type->num_levels; clevel++) { + KeySym sym = XkbKeycodeToKeysym(m_dpy, ckeycode, cgroup, clevel); + + int mask = 0; + for (int nmap = 0; nmap < type->map_count; nmap++) { + XkbKTMapEntryRec map = type->map[nmap]; + if (map.active && map.level == clevel) { + mask = map.mods.mask; + break; + } + } + + m_keymap.append(AutoTypePlatformX11::KeyDesc{sym, ckeycode, cgroup, mask}); } } } @@ -337,70 +327,12 @@ void AutoTypePlatformX11::updateKeymap() } } XFreeModifiermap(modifiers); - - /* Xlib needs some time until the mapping is distributed to - all clients */ - Tools::sleep(30); -} - -bool AutoTypePlatformX11::isRemapKeycodeValid() -{ - int baseKeycode = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode; - for (int i = 0; i < m_keysymPerKeycode; i++) { - if (m_keysymTable[baseKeycode + i] == m_currentRemapKeysym) { - return true; - } - } - - return false; -} - -XkbDescPtr AutoTypePlatformX11::getKeyboard() -{ - int num_devices; - XID keyboard_id = XkbUseCoreKbd; - XDeviceInfo* devices = XListInputDevices(m_dpy, &num_devices); - if (!devices) { - return nullptr; - } - - for (int i = 0; i < num_devices; i++) { - if (QString(devices[i].name) == "Virtual core XTEST keyboard") { - keyboard_id = devices[i].id; - break; - } - } - - XFreeDeviceList(devices); - - return XkbGetKeyboard(m_dpy, XkbCompatMapMask | XkbGeometryMask, keyboard_id); } // -------------------------------------------------------------------------- // The following code is taken from xvkbd 3.0 and has been slightly modified. // -------------------------------------------------------------------------- -/* - * Insert a specified keysym on the dedicated position in the keymap - * table. - */ -int AutoTypePlatformX11::AddKeysym(KeySym keysym) -{ - if (m_remapKeycode == 0) { - return 0; - } - - int inx = (m_remapKeycode - m_minKeycode) * m_keysymPerKeycode; - m_keysymTable[inx] = keysym; - m_currentRemapKeysym = keysym; - - XChangeKeyboardMapping(m_dpy, m_remapKeycode, m_keysymPerKeycode, &m_keysymTable[inx], 1); - XFlush(m_dpy); - updateKeymap(); - - return m_remapKeycode; -} - /* * Send event to the focused window. * If input focus is specified explicitly, select the window @@ -435,42 +367,26 @@ void AutoTypePlatformX11::SendModifiers(unsigned int mask, bool press) * Determines the keycode and modifier mask for the given * keysym. */ -int AutoTypePlatformX11::GetKeycode(KeySym keysym, unsigned int* mask) +bool AutoTypePlatformX11::GetKeycode(KeySym keysym, int* keycode, int* group, unsigned int* mask) { - int keycode = XKeysymToKeycode(m_dpy, keysym); + const KeyDesc* desc = nullptr; - if (keycode && keysymModifiers(keysym, keycode, mask)) { - return keycode; - } - - /* no modifier matches => resort to remapping */ - keycode = AddKeysym(keysym); - if (keycode && keysymModifiers(keysym, keycode, mask)) { - return keycode; - } - - *mask = 0; - return 0; -} - -bool AutoTypePlatformX11::keysymModifiers(KeySym keysym, int keycode, unsigned int* mask) -{ - int shift, mod; - unsigned int mods_rtrn; - - /* determine whether there is a combination of the modifiers - (Mod1-Mod5) with or without shift which returns keysym */ - for (shift = 0; shift < 2; shift++) { - for (mod = ControlMapIndex; mod <= Mod5MapIndex; mod++) { - KeySym keysym_rtrn; - *mask = (mod == ControlMapIndex) ? shift : shift | (1 << mod); - XkbTranslateKeyCode(m_xkb, keycode, *mask, &mods_rtrn, &keysym_rtrn); - if (keysym_rtrn == keysym) { - return true; + for (const auto& key : m_keymap) { + if (key.sym == keysym) { + // pick this description if we don't have any for this sym or this matches the current group + if (desc == nullptr || key.group == *group) { + desc = &key; } } } + if (desc) { + *keycode = desc->code; + *group = desc->group; + *mask = desc->mask; + return true; + } + return false; } @@ -487,14 +403,24 @@ void AutoTypePlatformX11::sendKey(KeySym keysym, unsigned int modifiers) } int keycode; + int group; + int group_active; unsigned int wanted_mask; - /* determine keycode and mask for the given keysym */ - keycode = GetKeycode(keysym, &wanted_mask); - if (keycode < 8 || keycode > 255) { + /* pull current active layout group */ + XkbStateRec state; + XkbGetState(m_dpy, XkbUseCoreKbd, &state); + group_active = state.group; + + /* tell GeyKeycode we would prefer a key from active group */ + group = group_active; + + /* determine keycode, group and mask for the given keysym */ + if (!GetKeycode(keysym, &keycode, &group, &wanted_mask)) { qWarning("Unable to get valid keycode for key: keysym=0x%lX", keysym); return; } + wanted_mask |= modifiers; Window root, child; @@ -541,6 +467,12 @@ void AutoTypePlatformX11::sendKey(KeySym keysym, unsigned int modifiers) release_mask = release_check_mask; } + /* change layout group if necessary */ + if (group_active != group) { + XkbLockGroup(m_dpy, XkbUseCoreKbd, group); + XFlush(m_dpy); + } + /* set modifiers mask */ if ((release_mask | press_mask) & LockMask) { SendModifiers(LockMask, true); @@ -560,6 +492,12 @@ void AutoTypePlatformX11::sendKey(KeySym keysym, unsigned int modifiers) SendModifiers(LockMask, true); SendModifiers(LockMask, false); } + + /* reset layout group if necessary */ + if (group_active != group) { + XkbLockGroup(m_dpy, XkbUseCoreKbd, group_active); + XFlush(m_dpy); + } } int AutoTypePlatformX11::MyErrorHandler(Display* my_dpy, XErrorEvent* event) @@ -579,6 +517,12 @@ AutoTypeExecutorX11::AutoTypeExecutorX11(AutoTypePlatformX11* platform) { } +void AutoTypeExecutorX11::execBegin(const AutoTypeBegin* action) +{ + Q_UNUSED(action); + m_platform->updateKeymap(); +} + void AutoTypeExecutorX11::execType(const AutoTypeKey* action) { if (action->key != Qt::Key_unknown) { diff --git a/src/autotype/xcb/AutoTypeXCB.h b/src/autotype/xcb/AutoTypeXCB.h index 4e22d417..1a70a3fa 100644 --- a/src/autotype/xcb/AutoTypeXCB.h +++ b/src/autotype/xcb/AutoTypeXCB.h @@ -54,6 +54,7 @@ public: QString activeWindowTitle() override; bool raiseWindow(WId window) override; AutoTypeExecutor* createExecutor() override; + void updateKeymap(); void sendKey(KeySym keysym, unsigned int modifiers = 0); @@ -65,13 +66,10 @@ private: bool isTopLevelWindow(Window window); XkbDescPtr getKeyboard(); - void updateKeymap(); - bool isRemapKeycodeValid(); int AddKeysym(KeySym keysym); void SendKeyEvent(unsigned keycode, bool press); void SendModifiers(unsigned int mask, bool press); - int GetKeycode(KeySym keysym, unsigned int* mask); - bool keysymModifiers(KeySym keysym, int keycode, unsigned int* mask); + bool GetKeycode(KeySym keysym, int* keycode, int* group, unsigned int* mask); static int MyErrorHandler(Display* my_dpy, XErrorEvent* event); @@ -87,14 +85,16 @@ private: Atom m_atomWindow; QSet m_classBlacklist; + typedef struct + { + KeySym sym; + int code; + int group; + int mask; + } KeyDesc; + XkbDescPtr m_xkb; - KeySym* m_keysymTable; - int m_minKeycode; - int m_maxKeycode; - int m_keysymPerKeycode; - /* dedicated keycode for remapped keys */ - unsigned int m_remapKeycode; - KeySym m_currentRemapKeysym; + QList m_keymap; KeyCode m_modifier_keycode[N_MOD_INDICES]; bool m_loaded; }; @@ -104,6 +104,7 @@ class AutoTypeExecutorX11 : public AutoTypeExecutor public: explicit AutoTypeExecutorX11(AutoTypePlatformX11* platform); + void execBegin(const AutoTypeBegin* action) override; void execType(const AutoTypeKey* action) override; void execClearField(const AutoTypeClearField* action) override; diff --git a/src/gui/osutils/nixutils/KeySymMap.h b/src/gui/osutils/nixutils/KeySymMap.h deleted file mode 100644 index efce4df8..00000000 --- a/src/gui/osutils/nixutils/KeySymMap.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Automatically generated by keysymmap.py from parsing keysymdef.h. - */ - -const int unicodeToKeysymLen = 632; - -// clang-format off -const uint unicodeToKeysymKeys[] = { - 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, - 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, 0x010f, - 0x0110, 0x0111, 0x0112, 0x0113, 0x0116, 0x0117, 0x0118, 0x0119, - 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, 0x011f, 0x0120, 0x0121, - 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, 0x0128, 0x0129, - 0x012a, 0x012b, 0x012e, 0x012f, 0x0130, 0x0131, 0x0134, 0x0135, - 0x0136, 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, - 0x013e, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0146, 0x0147, - 0x0148, 0x014a, 0x014b, 0x014c, 0x014d, 0x0150, 0x0151, 0x0152, - 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, - 0x015b, 0x015c, 0x015d, 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, - 0x0163, 0x0164, 0x0165, 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, - 0x016b, 0x016c, 0x016d, 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, - 0x0173, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, 0x017e, - 0x0192, 0x02c7, 0x02d8, 0x02d9, 0x02db, 0x02dd, 0x0385, 0x0386, - 0x0388, 0x0389, 0x038a, 0x038c, 0x038e, 0x038f, 0x0390, 0x0391, - 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, - 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, - 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, - 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03b0, 0x03b1, 0x03b2, - 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, - 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c2, - 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, - 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0401, 0x0402, 0x0403, 0x0404, - 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, - 0x040e, 0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, - 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, - 0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, - 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, - 0x042e, 0x042f, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, - 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, - 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, - 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, - 0x044e, 0x044f, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, - 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f, - 0x0490, 0x0491, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, - 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, - 0x05de, 0x05df, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, - 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x060c, 0x061b, 0x061f, - 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, - 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 0x0630, - 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, - 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, - 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, - 0x064e, 0x064f, 0x0650, 0x0651, 0x0652, 0x0e01, 0x0e02, 0x0e03, - 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, - 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, 0x0e10, 0x0e11, 0x0e12, 0x0e13, - 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, - 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, 0x0e20, 0x0e21, 0x0e22, 0x0e23, - 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, - 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, 0x0e30, 0x0e31, 0x0e32, 0x0e33, - 0x0e34, 0x0e35, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0e3f, - 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, - 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e50, 0x0e51, - 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, - 0x2002, 0x2003, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, 0x200a, - 0x2012, 0x2013, 0x2014, 0x2015, 0x2017, 0x2018, 0x2019, 0x201a, - 0x201c, 0x201d, 0x201e, 0x2020, 0x2021, 0x2025, 0x2026, 0x2030, - 0x2032, 0x2033, 0x2038, 0x203e, 0x20ac, 0x2105, 0x2116, 0x2117, - 0x211e, 0x2122, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, - 0x2159, 0x215a, 0x215b, 0x215c, 0x215d, 0x215e, 0x2190, 0x2191, - 0x2192, 0x2193, 0x21d2, 0x21d4, 0x2202, 0x2207, 0x2218, 0x221a, - 0x221d, 0x221e, 0x2227, 0x2228, 0x2229, 0x222a, 0x222b, 0x2234, - 0x223c, 0x2243, 0x2260, 0x2261, 0x2264, 0x2265, 0x2282, 0x2283, - 0x22a2, 0x22a3, 0x22a4, 0x22a5, 0x2308, 0x230a, 0x2315, 0x2320, - 0x2321, 0x2395, 0x239b, 0x239d, 0x239e, 0x23a0, 0x23a1, 0x23a3, - 0x23a4, 0x23a6, 0x23a8, 0x23ac, 0x23b7, 0x23ba, 0x23bb, 0x23bc, - 0x23bd, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x2424, 0x2500, - 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, 0x252c, - 0x2534, 0x253c, 0x2592, 0x25c6, 0x25cb, 0x260e, 0x2640, 0x2642, - 0x2663, 0x2665, 0x2666, 0x266d, 0x266f, 0x2713, 0x2717, 0x271d, - 0x2720, 0x3001, 0x3002, 0x300c, 0x300d, 0x309b, 0x309c, 0x30a1, - 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, 0x30a9, - 0x30aa, 0x30ab, 0x30ad, 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, - 0x30b9, 0x30bb, 0x30bd, 0x30bf, 0x30c1, 0x30c3, 0x30c4, 0x30c6, - 0x30c8, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d2, - 0x30d5, 0x30d8, 0x30db, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2, - 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, 0x30e9, 0x30ea, - 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f2, 0x30f3, 0x30fb, 0x30fc -}; - -const uint unicodeToKeysymValues[] = { - 0x03c0, 0x03e0, 0x01c3, 0x01e3, 0x01a1, 0x01b1, 0x01c6, 0x01e6, - 0x02c6, 0x02e6, 0x02c5, 0x02e5, 0x01c8, 0x01e8, 0x01cf, 0x01ef, - 0x01d0, 0x01f0, 0x03aa, 0x03ba, 0x03cc, 0x03ec, 0x01ca, 0x01ea, - 0x01cc, 0x01ec, 0x02d8, 0x02f8, 0x02ab, 0x02bb, 0x02d5, 0x02f5, - 0x03ab, 0x03bb, 0x02a6, 0x02b6, 0x02a1, 0x02b1, 0x03a5, 0x03b5, - 0x03cf, 0x03ef, 0x03c7, 0x03e7, 0x02a9, 0x02b9, 0x02ac, 0x02bc, - 0x03d3, 0x03f3, 0x03a2, 0x01c5, 0x01e5, 0x03a6, 0x03b6, 0x01a5, - 0x01b5, 0x01a3, 0x01b3, 0x01d1, 0x01f1, 0x03d1, 0x03f1, 0x01d2, - 0x01f2, 0x03bd, 0x03bf, 0x03d2, 0x03f2, 0x01d5, 0x01f5, 0x13bc, - 0x13bd, 0x01c0, 0x01e0, 0x03a3, 0x03b3, 0x01d8, 0x01f8, 0x01a6, - 0x01b6, 0x02de, 0x02fe, 0x01aa, 0x01ba, 0x01a9, 0x01b9, 0x01de, - 0x01fe, 0x01ab, 0x01bb, 0x03ac, 0x03bc, 0x03dd, 0x03fd, 0x03de, - 0x03fe, 0x02dd, 0x02fd, 0x01d9, 0x01f9, 0x01db, 0x01fb, 0x03d9, - 0x03f9, 0x13be, 0x01ac, 0x01bc, 0x01af, 0x01bf, 0x01ae, 0x01be, - 0x08f6, 0x01b7, 0x01a2, 0x01ff, 0x01b2, 0x01bd, 0x07ae, 0x07a1, - 0x07a2, 0x07a3, 0x07a4, 0x07a7, 0x07a8, 0x07ab, 0x07b6, 0x07c1, - 0x07c2, 0x07c3, 0x07c4, 0x07c5, 0x07c6, 0x07c7, 0x07c8, 0x07c9, - 0x07ca, 0x07cb, 0x07cc, 0x07cd, 0x07ce, 0x07cf, 0x07d0, 0x07d1, - 0x07d2, 0x07d4, 0x07d5, 0x07d6, 0x07d7, 0x07d8, 0x07d9, 0x07a5, - 0x07a9, 0x07b1, 0x07b2, 0x07b3, 0x07b4, 0x07ba, 0x07e1, 0x07e2, - 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8, 0x07e9, 0x07ea, - 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, 0x07f1, 0x07f3, - 0x07f2, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8, 0x07f9, 0x07b5, - 0x07b9, 0x07b7, 0x07b8, 0x07bb, 0x06b3, 0x06b1, 0x06b2, 0x06b4, - 0x06b5, 0x06b6, 0x06b7, 0x06b8, 0x06b9, 0x06ba, 0x06bb, 0x06bc, - 0x06be, 0x06bf, 0x06e1, 0x06e2, 0x06f7, 0x06e7, 0x06e4, 0x06e5, - 0x06f6, 0x06fa, 0x06e9, 0x06ea, 0x06eb, 0x06ec, 0x06ed, 0x06ee, - 0x06ef, 0x06f0, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06e6, 0x06e8, - 0x06e3, 0x06fe, 0x06fb, 0x06fd, 0x06ff, 0x06f9, 0x06f8, 0x06fc, - 0x06e0, 0x06f1, 0x06c1, 0x06c2, 0x06d7, 0x06c7, 0x06c4, 0x06c5, - 0x06d6, 0x06da, 0x06c9, 0x06ca, 0x06cb, 0x06cc, 0x06cd, 0x06ce, - 0x06cf, 0x06d0, 0x06d2, 0x06d3, 0x06d4, 0x06d5, 0x06c6, 0x06c8, - 0x06c3, 0x06de, 0x06db, 0x06dd, 0x06df, 0x06d9, 0x06d8, 0x06dc, - 0x06c0, 0x06d1, 0x06a3, 0x06a1, 0x06a2, 0x06a4, 0x06a5, 0x06a6, - 0x06a7, 0x06a8, 0x06a9, 0x06aa, 0x06ab, 0x06ac, 0x06ae, 0x06af, - 0x06bd, 0x06ad, 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, - 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, - 0x0cee, 0x0cef, 0x0cf0, 0x0cf1, 0x0cf2, 0x0cf3, 0x0cf4, 0x0cf5, - 0x0cf6, 0x0cf7, 0x0cf8, 0x0cf9, 0x0cfa, 0x05ac, 0x05bb, 0x05bf, - 0x05c1, 0x05c2, 0x05c3, 0x05c4, 0x05c5, 0x05c6, 0x05c7, 0x05c8, - 0x05c9, 0x05ca, 0x05cb, 0x05cc, 0x05cd, 0x05ce, 0x05cf, 0x05d0, - 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, - 0x05d9, 0x05da, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, - 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed, - 0x05ee, 0x05ef, 0x05f0, 0x05f1, 0x05f2, 0x0da1, 0x0da2, 0x0da3, - 0x0da4, 0x0da5, 0x0da6, 0x0da7, 0x0da8, 0x0da9, 0x0daa, 0x0dab, - 0x0dac, 0x0dad, 0x0dae, 0x0daf, 0x0db0, 0x0db1, 0x0db2, 0x0db3, - 0x0db4, 0x0db5, 0x0db6, 0x0db7, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, - 0x0dbc, 0x0dbd, 0x0dbe, 0x0dbf, 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, - 0x0dc4, 0x0dc5, 0x0dc6, 0x0dc7, 0x0dc8, 0x0dc9, 0x0dca, 0x0dcb, - 0x0dcc, 0x0dcd, 0x0dce, 0x0dcf, 0x0dd0, 0x0dd1, 0x0dd2, 0x0dd3, - 0x0dd4, 0x0dd5, 0x0dd6, 0x0dd7, 0x0dd8, 0x0dd9, 0x0dda, 0x0ddf, - 0x0de0, 0x0de1, 0x0de2, 0x0de3, 0x0de4, 0x0de5, 0x0de6, 0x0de7, - 0x0de8, 0x0de9, 0x0dea, 0x0deb, 0x0dec, 0x0ded, 0x0df0, 0x0df1, - 0x0df2, 0x0df3, 0x0df4, 0x0df5, 0x0df6, 0x0df7, 0x0df8, 0x0df9, - 0x0aa2, 0x0aa1, 0x0aa3, 0x0aa4, 0x0aa5, 0x0aa6, 0x0aa7, 0x0aa8, - 0x0abb, 0x0aaa, 0x0aa9, 0x07af, 0x0cdf, 0x0ad0, 0x0ad1, 0x0afd, - 0x0ad2, 0x0ad3, 0x0afe, 0x0af1, 0x0af2, 0x0aaf, 0x0aae, 0x0ad5, - 0x0ad6, 0x0ad7, 0x0afc, 0x047e, 0x20ac, 0x0ab8, 0x06b0, 0x0afb, - 0x0ad4, 0x0ac9, 0x0ab0, 0x0ab1, 0x0ab2, 0x0ab3, 0x0ab4, 0x0ab5, - 0x0ab6, 0x0ab7, 0x0ac3, 0x0ac4, 0x0ac5, 0x0ac6, 0x08fb, 0x08fc, - 0x08fd, 0x08fe, 0x08ce, 0x08cd, 0x08ef, 0x08c5, 0x0bca, 0x08d6, - 0x08c1, 0x08c2, 0x08de, 0x08df, 0x08dc, 0x08dd, 0x08bf, 0x08c0, - 0x08c8, 0x08c9, 0x08bd, 0x08cf, 0x08bc, 0x08be, 0x08da, 0x08db, - 0x0bfc, 0x0bdc, 0x0bc2, 0x0bce, 0x0bd3, 0x0bc4, 0x0afa, 0x08a4, - 0x08a5, 0x0bcc, 0x08ab, 0x08ac, 0x08ad, 0x08ae, 0x08a7, 0x08a8, - 0x08a9, 0x08aa, 0x08af, 0x08b0, 0x08a1, 0x09ef, 0x09f0, 0x09f2, - 0x09f3, 0x09e2, 0x09e5, 0x09e9, 0x09e3, 0x09e4, 0x09e8, 0x09f1, - 0x09f8, 0x09ec, 0x09eb, 0x09ed, 0x09ea, 0x09f4, 0x09f5, 0x09f7, - 0x09f6, 0x09ee, 0x09e1, 0x09e0, 0x0bcf, 0x0af9, 0x0af8, 0x0af7, - 0x0aec, 0x0aee, 0x0aed, 0x0af6, 0x0af5, 0x0af3, 0x0af4, 0x0ad9, - 0x0af0, 0x04a4, 0x04a1, 0x04a2, 0x04a3, 0x04de, 0x04df, 0x04a7, - 0x04b1, 0x04a8, 0x04b2, 0x04a9, 0x04b3, 0x04aa, 0x04b4, 0x04ab, - 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, - 0x04bd, 0x04be, 0x04bf, 0x04c0, 0x04c1, 0x04af, 0x04c2, 0x04c3, - 0x04c4, 0x04c5, 0x04c6, 0x04c7, 0x04c8, 0x04c9, 0x04ca, 0x04cb, - 0x04cc, 0x04cd, 0x04ce, 0x04cf, 0x04d0, 0x04d1, 0x04d2, 0x04d3, - 0x04ac, 0x04d4, 0x04ad, 0x04d5, 0x04ae, 0x04d6, 0x04d7, 0x04d8, - 0x04d9, 0x04da, 0x04db, 0x04dc, 0x04a6, 0x04dd, 0x04a5, 0x04b0 -}; -// clang-format on diff --git a/src/gui/osutils/nixutils/NixUtils.cpp b/src/gui/osutils/nixutils/NixUtils.cpp index db39b1ac..8c7756e9 100644 --- a/src/gui/osutils/nixutils/NixUtils.cpp +++ b/src/gui/osutils/nixutils/NixUtils.cpp @@ -16,7 +16,6 @@ */ #include "NixUtils.h" -#include "KeySymMap.h" #include "core/Tools.h" #include @@ -184,25 +183,6 @@ bool NixUtils::nativeEventFilter(const QByteArray& eventType, void* message, lon auto* keyPressEvent = static_cast(message); auto modifierMask = ControlMask | ShiftMask | Mod1Mask | Mod4Mask; return triggerGlobalShortcut(keyPressEvent->detail, keyPressEvent->state & modifierMask); - } else if (type == XCB_MAPPING_NOTIFY) { - auto* mappingNotifyEvent = static_cast(message); - if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD - || mappingNotifyEvent->request == XCB_MAPPING_MODIFIER) { - XMappingEvent xMappingEvent; - memset(&xMappingEvent, 0, sizeof(xMappingEvent)); - xMappingEvent.type = MappingNotify; - xMappingEvent.display = dpy; - if (mappingNotifyEvent->request == XCB_MAPPING_KEYBOARD) { - xMappingEvent.request = MappingKeyboard; - } else { - xMappingEvent.request = MappingModifier; - } - xMappingEvent.first_keycode = mappingNotifyEvent->first_keycode; - xMappingEvent.count = mappingNotifyEvent->count; - XRefreshKeyboardMapping(&xMappingEvent); - // Notify listeners that the keymap has changed - emit keymapChanged(); - } } return false; diff --git a/src/gui/osutils/nixutils/NixUtils.h b/src/gui/osutils/nixutils/NixUtils.h index 92b83fcf..d71b29da 100644 --- a/src/gui/osutils/nixutils/NixUtils.h +++ b/src/gui/osutils/nixutils/NixUtils.h @@ -48,9 +48,6 @@ public: return false; } -signals: - void keymapChanged(); - private: explicit NixUtils(QObject* parent = nullptr); ~NixUtils() override; diff --git a/src/gui/osutils/nixutils/X11Funcs.cpp b/src/gui/osutils/nixutils/X11Funcs.cpp index 5f331303..113177c1 100644 --- a/src/gui/osutils/nixutils/X11Funcs.cpp +++ b/src/gui/osutils/nixutils/X11Funcs.cpp @@ -17,7 +17,6 @@ #include "X11Funcs.h" -#include "KeySymMap.h" #include "core/Tools.h" #include @@ -31,18 +30,9 @@ KeySym qcharToNativeKeyCode(const QChar& ch) return unicode; } - /* mapping table generated from keysymdef.h */ - const uint* match = Tools::binaryFind(unicodeToKeysymKeys, unicodeToKeysymKeys + unicodeToKeysymLen, unicode); - int index = match - unicodeToKeysymKeys; - if (index != unicodeToKeysymLen) { - return unicodeToKeysymValues[index]; - } - - if (unicode >= 0x0100) { - return unicode | 0x01000000; - } - - return NoSymbol; + /* request other characters from X server */ + QString ustr = QString("U%1").arg(unicode, 4, 16, QLatin1Char('0')); + return XStringToKeysym(ustr.toStdString().c_str()); } KeySym qtToNativeKeyCode(Qt::Key key)