Details
-
Bug
-
Resolution: Cannot Reproduce
-
P2: Important
-
None
-
4.4.1
Description
I create a button whose label has a mnemonic, let's say "E&xit". I translate the label into russian, using tr("E&xit"). "E&xit" becomes "&Выход". Now I expect that pressing Alt+В is going to activate the button, but it doesn't.
Debugging has made me understand that QKeySequence for the mnemonic is created using my cyrilic character's unicode. However, QKeyMapper does not map that sequence to the pressed В. The reason is in:
qkeymapper_x11.cpp:1200 (QKeyMapperPrivate::possibleKeysXKB)
It uses XkbLookupKeySym to get KeySym from the native (X11) key code. It receives Latin1 keysym, when we expect russian character. I guess some changes should be made here.
For example, I've made some changes at qkeymapper_x11.cpp:1200, replaced QKeyMapperPrivate::possibleKeysXKB with two methods, which resolved the issue. I'm not quite sure about not having broken something, but at least it is a possible solution.
QList<int> QKeyMapperPrivate::possibleKeysXKBByBaseCode (QKeyEvent *event, KeySym baseKeySym, uint consumedModifiers) { #ifndef QT_NO_XKB const int xkeycode = event->nativeScanCode(); const uint xmodifiers = event->nativeModifiers(); QList<int> result; // translate sym -> code Qt::KeyboardModifiers baseModifiers = 0; int baseCode = -1; QByteArray chars; int count = 0; QString text = translateKeySym(baseKeySym, xmodifiers, baseCode, baseModifiers, chars, count); if (baseCode == -1) { if (text.isEmpty()) return QList<int>(); baseCode = text.at(0).unicode(); } if (baseCode && baseCode < 0xfffe) baseCode = QChar(baseCode).toUpper().unicode(); result += (baseCode | baseModifiers); int pos1Bits[MaxBits]; int num1Bits = 0; for (int i = 0; i < MaxBits; ++i) { if (consumedModifiers & (1 << i)) pos1Bits[num1Bits++] = i; } const int numPerms = (1 << num1Bits); // translate the key again using each permutation of consumedModifiers for (int i = 1; i < numPerms; ++i) { uint val = 0; for (int j = 0; j < num1Bits; ++j) { if (i & (1 << j)) val |= (1 << pos1Bits[j]); } if ((xmodifiers & val) != val) continue; KeySym sym; uint mods; if (!XkbLookupKeySym(X11->display, xkeycode, val, &mods, &sym)) continue; // translate sym -> code Qt::KeyboardModifiers modifiers = 0; int code = -1; chars.clear(); count = 0; // mask out the modifiers needed to translate keycode text = translateKeySym(sym, xmodifiers & ~val, code, modifiers, chars, count); if (code == -1) { if (text.isEmpty()) continue; code = text.at(0).unicode(); } if (code && code < 0xfffe) code = QChar(code).toUpper().unicode(); if (code == baseCode) continue; result += (code | modifiers); } #if 0 qDebug() << "possibleKeysXKB()" << hex << result; #endif return result; #else Q_UNUSED(event); return QList<int>(); #endif // QT_NO_XKB } QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event) { #ifndef QT_NO_XKB const int xkeycode = event->nativeScanCode(); const uint xmodifiers = event->nativeModifiers(); // first, translate key only using lock modifiers (there are no Qt equivalents for these, so we must // always use them when determining the baseKeySym) KeySym baseKeySym; uint consumedModifiers; QList<int> result; if (XkbLookupKeySym(X11->display, xkeycode, (xmodifiers & (LockMask | qt_num_lock_mask)), &consumedModifiers, &baseKeySym)) result += possibleKeysXKBByBaseCode (event, baseKeySym, consumedModifiers); if (event->nativeVirtualKey () != 0) result += possibleKeysXKBByBaseCode (event, event->nativeVirtualKey (), event->nativeModifiers ()); return result.toSet ().toList (); #else Q_UNUSED(event); return QList<int>(); #endif // QT_NO_XKB }
Attachments
Issue Links
- relates to
-
QTBUG-12286 Shortcut key doesn't work with Arabic letters
- Closed