diff options
author | Liang Qi <liang.qi@qt.io> | 2016-09-22 07:28:34 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-09-22 07:28:34 +0200 |
commit | 50908f023d83257dbc0b6d17bfe29e2f101615af (patch) | |
tree | de68e2d9587db1fb59d75505981b6ff033e12992 /src/plugins/platforms/xcb/qxcbkeyboard.cpp | |
parent | 7555a925816e3244073803f0adc4d44640f5ac1d (diff) | |
parent | d10e4c193b0152350e884adcc1060aabd1a974f7 (diff) |
Merge remote-tracking branch 'origin/5.7' into 5.8
Conflicts:
src/plugins/platforms/ios/qiosviewcontroller.mm
Change-Id: I2dda31867cbc79ea7fe965f52afb518aefa4ad20
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbkeyboard.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 4c908359f3..a5aff7f11f 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -748,8 +748,7 @@ void QXcbKeyboard::updateKeymap() // update xkb state object xkb_state_unref(xkb_state); xkb_state = new_state; - if (!connection()->hasXKB()) - updateXKBMods(); + updateXKBMods(); checkForLatinLayout(); } @@ -774,32 +773,37 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) } #endif +void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state) +{ + const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED); + const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED); + const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED); + const quint32 xkbMask = xkbModMask(state); + + const quint32 latched = modsLatched & xkbMask; + const quint32 locked = modsLocked & xkbMask; + quint32 depressed = modsDepressed & xkbMask; + // set modifiers in depressed if they don't appear in any of the final masks + depressed |= ~(depressed | latched | locked) & xkbMask; + + const xkb_state_component newState + = xkb_state_update_mask(kb_state, + depressed, + latched, + locked, + 0, + 0, + (state >> 13) & 3); // bits 13 and 14 report the state keyboard group + + if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } +} + void QXcbKeyboard::updateXKBStateFromCore(quint16 state) { if (m_config && !connection()->hasXKB()) { - const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); - const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); - const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); - const quint32 xkbMask = xkbModMask(state); - - const quint32 latched = modsLatched & xkbMask; - const quint32 locked = modsLocked & xkbMask; - quint32 depressed = modsDepressed & xkbMask; - // set modifiers in depressed if they don't appear in any of the final masks - depressed |= ~(depressed | latched | locked) & xkbMask; - - const xkb_state_component newState - = xkb_state_update_mask(xkb_state, - depressed, - latched, - locked, - 0, - 0, - (state >> 13) & 3); // bits 13 and 14 report the state keyboard group - - if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { - //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); - } + updateXKBStateFromState(xkb_state, state); } } @@ -1463,7 +1467,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, if (type == QEvent::KeyPress) targetWindow->updateNetWmUserTime(time); - xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); + // 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); QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); QMetaMethod method; @@ -1482,11 +1495,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, Q_ARG(uint, code), Q_ARG(uint, state), Q_ARG(bool, type == QEvent::KeyPress)); - if (retval) + if (retval) { + xkb_state_unref(kb_state); return; + } } - QString string = lookupString(xkb_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", @@ -1557,6 +1572,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, code, sym, state, string, isAutoRepeat); } + xkb_state_unref(kb_state); } QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const |