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 <ran234@gmail.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Gatis Paeglis 2014-03-31 17:13:20 +02:00 committed by The Qt Project
parent bd40a7cc44
commit 6ad458bc93
2 changed files with 9 additions and 12 deletions

View File

@ -853,7 +853,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
return QList<int>();
QList<int> 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<int> 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);
}

View File

@ -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;