diff options
author | Liang Qi <liang.qi@qt.io> | 2021-10-27 12:01:41 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-26 23:38:16 +0000 |
commit | ca6dfb19a04a22285ba6b2c92b97f403884936d4 (patch) | |
tree | 877d90f24d3f8e7474fcbe75d71df88c5e24eff9 | |
parent | 9b59929217dd06e983873a0c8a544fffe16a6cff (diff) |
xcb: stablilize xkb state when keymap updated
QXcbKeyboard only deals with core_device_id. With the reporter's test
case: using xdotool to send a string, the deviceID is not changed,
then we assume xkb_state_new() is more stable(or correct) than
xkb_x11_state_new_from_device() in this case.
See also https://www.x.org/releases/current/doc/man/man3/xcb_xkb_new_keyboard_notify_event_t.3.xhtml .
Fixes: QTBUG-95933
Change-Id: Ic595e1f1424fbc6814871a85ac159907f1aeb12a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Zhang Hao <zhanghao@uniontech.com>
Reviewed-by: Liang Qi <liang.qi@qt.io>
(cherry picked from commit 27c25fc909c19ddc4750f36d26b7c500db9eb0ab)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 24 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.h | 1 |
3 files changed, 22 insertions, 5 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index c667de0f78..8f22a4db13 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -750,7 +750,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) case XCB_XKB_NEW_KEYBOARD_NOTIFY: { xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify; if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES) - m_keyboard->updateKeymap(); + m_keyboard->updateKeymap(ev); break; } default: diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index b2ce353ae9..e0537fc068 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -365,6 +365,17 @@ void QXcbKeyboard::updateKeymap(xcb_mapping_notify_event_t *event) updateKeymap(); } +void QXcbKeyboard::updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event) +{ + if (!event) + return; + + if (event->deviceID != event->oldDeviceID) + m_config = false; + + updateKeymap(); +} + void QXcbKeyboard::updateKeymap() { KeysymModifierMap keysymMods; @@ -372,8 +383,6 @@ void QXcbKeyboard::updateKeymap() keysymMods = keysymsToModifiers(); updateModifiers(keysymMods); - m_config = true; - if (!m_xkbContext) { m_xkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES)); if (!m_xkbContext) { @@ -389,8 +398,13 @@ void QXcbKeyboard::updateKeymap() if (connection()->hasXKB()) { m_xkbKeymap.reset(xkb_x11_keymap_new_from_device(m_xkbContext.get(), xcb_connection(), core_device_id, XKB_KEYMAP_COMPILE_NO_FLAGS)); - if (m_xkbKeymap) - m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id)); + if (m_xkbKeymap) { + if (m_config) + m_xkbState.reset(xkb_state_new(m_xkbKeymap.get())); + else + m_xkbState.reset(xkb_x11_state_new_from_device(m_xkbKeymap.get(), xcb_connection(), core_device_id)); + + } } else { m_xkbKeymap.reset(keymapFromCore(keysymMods)); if (m_xkbKeymap) @@ -411,6 +425,8 @@ void QXcbKeyboard::updateKeymap() updateXKBMods(); QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get()); + + m_config = true; } QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 1252512e13..470f690d50 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -69,6 +69,7 @@ public: Qt::KeyboardModifiers translateModifiers(int s) const; void updateKeymap(xcb_mapping_notify_event_t *event); + void updateKeymap(xcb_xkb_new_keyboard_notify_event_t *event); void updateKeymap(); QList<int> possibleKeys(const QKeyEvent *event) const; |