From 6ad458bc93162753e448eea28499e778e2946d2c Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 31 Mar 2014 17:13:20 +0200 Subject: [PATCH] Fix regression in key handling. libxkbcommon 0.4.1 added two new functions, xkb_state_key_get_utf{8,32}(). They combine the operations of xkb_state_key_get_syms() and xkb_keysym_to_utf{8,32}(). The xkb_state_key_get_utf{8,32}() functions now apply Control transformation: when the Control modifier is active, the string is converted to an appropriate control character. This matches the behavior of libX11's XLookupString(3), and is required by the XKB specification: http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier Task-number: QTBUG-36281 Change-Id: Ib45f45d801291c171640600384107a35d7d56b9b Reviewed-by: Ran Benita Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 19 ++++++++----------- src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 73cfb76bfc..4ee1cb4305 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -853,7 +853,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const return QList(); QList result; - int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym)); + int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode())); result += (baseQtKey + modifiers); // The base key is _always_ valid, of course xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift"); @@ -900,7 +900,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const continue; Qt::KeyboardModifiers mods = modifiers & ~neededMods; - qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym)); + qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode())); if (qtKey == baseQtKey) continue; @@ -1316,7 +1316,8 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } Qt::KeyboardModifiers modifiers = translateModifiers(state); - QString string = keysymToUnicode(sym); + + QString string = lookupString(xkb_state, code); int count = string.size(); string.truncate(count); @@ -1379,16 +1380,12 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod } } -QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const +QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const { QByteArray chars; - int bytes; - chars.resize(7); - bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size()); - if (bytes == -1) - qWarning("QXcbKeyboard::handleKeyEvent - buffer too small"); - chars.resize(bytes-1); - + chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0)); + // equivalent of XLookupString + xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); return QString::fromUtf8(chars); } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 1acd466aeb..ce27785ae1 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -86,7 +86,7 @@ protected: void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time); void resolveMaskConflicts(); - QString keysymToUnicode(xcb_keysym_t sym) const; + QString lookupString(struct xkb_state *state, xcb_keycode_t code) const; int keysymToQtKey(xcb_keysym_t keysym) const; int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const; void printKeymapError(const char *error) const;