Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.10.1
-
None
-
Qt (Base, Wayland) 5.10.1 on Arch Linux.
-
23453c30084d09d7325e113bbc3d0637c51cb3e7 (qt/qtwayland/dev)
Description
Steps to reproduce
- Run Wayland compositor (sway in my case)
- Run simple program with QTextEdit field (attached test.cpp should be enough)
- Type in some text
- Ctrl+A should select all text (as expected)
- Switch to non-US keyboard layout (Russian in my case)
- Ctrl+A will do nothing
Investigation
Attached test_2.cpp contains another simple program that shows received key events (QKeyEvent).
Ctrl+A press on X11 with US layout:
| Keys involved: 1 | Key code: 65 | Text: "\u0001" | Native scan code: 38 | Native virtual key: 97 > Modifiers: | Shift: false | Ctrl: true | Alt: false | Meta: false > Matches sequences: | Unknown key: false | Cancel: false | Select all: true
Ctrl+A press on X11 with RU layout:
| Keys involved: 1 | Key code: 65 | Text: "\u0001" | Native scan code: 38 | Native virtual key: 1734 > Modifiers: | Shift: false | Ctrl: true | Alt: false | Meta: false > Matches sequences: | Unknown key: false | Cancel: false | Select all: true
Ctrl+A press on Wayland with US layout:
| Keys involved: 1 | Key code: 65 | Text: "\u0001" | Native scan code: 38 | Native virtual key: 97 > Modifiers: | Shift: false | Ctrl: true | Alt: false | Meta: false > Matches sequences: | Unknown key: false | Cancel: false | Select all: true
And finally... Ctrl+A press on Wayland with RU layout:
| Keys involved: 1 | Key code: 1060 | Text: "ф" | Native scan code: 38 | Native virtual key: 1734 > Modifiers: | Shift: false | Ctrl: true | Alt: false | Meta: false > Matches sequences: | Unknown key: false | Cancel: false | Select all: false
Note key code (event->key()) value.
On Wayland QWaylandXkb::keysymToQtKey is responsive for Keysym-QtKey mapping. It's called from following places:
- qt5-wayland-git/src/qt5-wayland/src/client/qwaylandinputcontext.cpp:340
- qt5-wayland-git/src/qt5-wayland/src/client/qwaylandinputdevice.cpp:755
On X11 QXcbKeyboard::keysymToQtKey is responsive for same task. It's called from following place:
// Have a temporary keyboard state filled in from state // this way we allow for synthetic events to have different state // from the current state i.e. you can have Alt+Ctrl pressed // and receive a synthetic key event that has neither Alt nor Ctrl pressed struct xkb_state *kb_state = xkb_state_new(xkb_keymap); if (!kb_state) return; updateXKBStateFromState(kb_state, state); xcb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code); QString string = lookupString(kb_state, code); // Ιf control modifier is set we should prefer latin character, this is // used for standard shortcuts in checks like "key == QKeySequence::Copy", // users can still see the actual X11 keysym with QKeyEvent::nativeVirtualKey Qt::KeyboardModifiers modifiers = translateModifiers(state); xcb_keysym_t translatedSym = XKB_KEY_NoSymbol; if (modifiers & Qt::ControlModifier && !isLatin(sym)) translatedSym = lookupLatinKeysym(code); if (translatedSym == XKB_KEY_NoSymbol) translatedSym = sym; int qtcode = keysymToQtKey(translatedSym, modifiers, string);
lookupLatinKeysym converts 'ф' into latin 'a' so Ctrl+A will always be reported as Ctrl+A, not Ctrl+Ф. There is no corresponding conversion done in Wayland-related code:
void QWaylandTextInput::zwp_text_input_v2_keysym(uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) { // ... QString text; int qtkey; std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, qtModifiers); // ... QWindowSystemInterface::handleKeyEvent(QGuiApplication::focusWindow(), time, type, qtkey, qtModifiers, text);
Attachments
Issue Links
- relates to
-
QTBUG-65503 Unify key handling code on linux
- Closed