xcb: Use the state of the key event to process it

Instead of the global state

Task-number: QTBUG-48795
Change-Id: Ic2c545718adb68df41730e5a3bf25adb374ffce3
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
Albert Astals Cid 2016-04-21 01:39:27 +02:00 committed by Shawn Rutledge
parent 6b9c57f8cd
commit 76adb6c29f
2 changed files with 46 additions and 28 deletions

View File

@ -742,7 +742,6 @@ void QXcbKeyboard::updateKeymap()
// update xkb state object // update xkb state object
xkb_state_unref(xkb_state); xkb_state_unref(xkb_state);
xkb_state = new_state; xkb_state = new_state;
if (!connection()->hasXKB())
updateXKBMods(); updateXKBMods();
checkForLatinLayout(); checkForLatinLayout();
@ -768,12 +767,11 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
} }
#endif #endif
void QXcbKeyboard::updateXKBStateFromCore(quint16 state) void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state)
{ {
if (m_config && !connection()->hasXKB()) { const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED);
const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED);
const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED);
const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
const quint32 xkbMask = xkbModMask(state); const quint32 xkbMask = xkbModMask(state);
const quint32 latched = modsLatched & xkbMask; const quint32 latched = modsLatched & xkbMask;
@ -783,7 +781,7 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
depressed |= ~(depressed | latched | locked) & xkbMask; depressed |= ~(depressed | latched | locked) & xkbMask;
const xkb_state_component newState const xkb_state_component newState
= xkb_state_update_mask(xkb_state, = xkb_state_update_mask(kb_state,
depressed, depressed,
latched, latched,
locked, locked,
@ -795,6 +793,12 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
} }
} }
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
{
if (m_config && !connection()->hasXKB()) {
updateXKBStateFromState(xkb_state, state);
}
} }
#ifdef XCB_USE_XINPUT22 #ifdef XCB_USE_XINPUT22
@ -1455,7 +1459,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
if (type == QEvent::KeyPress) if (type == QEvent::KeyPress)
targetWindow->updateNetWmUserTime(time); 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(); QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
QMetaMethod method; QMetaMethod method;
@ -1474,11 +1487,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
Q_ARG(uint, code), Q_ARG(uint, code),
Q_ARG(uint, state), Q_ARG(uint, state),
Q_ARG(bool, type == QEvent::KeyPress)); Q_ARG(bool, type == QEvent::KeyPress));
if (retval) if (retval) {
xkb_state_unref(kb_state);
return; 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 // Ιf control modifier is set we should prefer latin character, this is
// used for standard shortcuts in checks like "key == QKeySequence::Copy", // used for standard shortcuts in checks like "key == QKeySequence::Copy",
@ -1547,6 +1562,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers,
code, sym, state, string, isAutoRepeat); code, sym, state, string, isAutoRepeat);
} }
xkb_state_unref(kb_state);
} }
QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const

View File

@ -98,6 +98,8 @@ protected:
void checkForLatinLayout(); void checkForLatinLayout();
private: private:
void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
bool m_config; bool m_config;
xcb_keycode_t m_autorepeat_code; xcb_keycode_t m_autorepeat_code;