diff options
author | Liang Qi <liang.qi@qt.io> | 2021-10-27 12:01:41 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2021-11-26 12:00:06 +0100 |
commit | 27c25fc909c19ddc4750f36d26b7c500db9eb0ab (patch) | |
tree | fa5b9f04af7d8699cb85796289f74661fe4a0e9b /src | |
parent | f92d4ffeade1a95106dc127e3b686cc639a46de4 (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
Pick-to: 6.2 5.15
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>
Diffstat (limited to 'src')
-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 d6257c70b5..191d5af26c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -773,7 +773,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 9ab804ca1b..48abbbf74c 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 cf89acff6d..aaf4577985 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; |