1
0
forked from pool/libqt5-qtbase
libqt5-qtbase/0015-Use-the-state-of-the-key-event-to-process-it.patch

150 lines
6.3 KiB
Diff
Raw Normal View History

From d7be69c973623e76deff3fa00354927946b21c66 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Thu, 21 Apr 2016 01:39:27 +0200
Subject: [PATCH 15/16] Use the state of the key event to process it
Use the state of the key event instead of the global state.
UpdateXKBStateFromState uses xkbModMask, which needs updateXKBMods
to be called beforehand.
Task-number: QTBUG-48795
Change-Id: Ic2c545718adb68df41730e5a3bf25adb374ffce3
---
src/plugins/platforms/xcb/qxcbkeyboard.cpp | 72 ++++++++++++++++++------------
src/plugins/platforms/xcb/qxcbkeyboard.h | 2 +
2 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 631dd17908f458533f413409773b6c078b743d98..baba7ec812c16025893bf5267fba545e8b4378bf 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -742,8 +742,7 @@ void QXcbKeyboard::updateKeymap()
// update xkb state object
xkb_state_unref(xkb_state);
xkb_state = new_state;
- if (!connection()->hasXKB())
- updateXKBMods();
+ updateXKBMods();
checkForLatinLayout();
}
@@ -768,32 +767,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);
}
}
@@ -1445,7 +1449,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;
@@ -1464,11 +1477,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",
@@ -1537,6 +1552,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
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 457a27affb166e2a3e54c78761361ff3713a4d18..dc27511b56e98bfc0f642e03c0b3aa8b2f4778e9 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -98,6 +98,8 @@ protected:
void checkForLatinLayout();
private:
+ void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
+
bool m_config;
xcb_keycode_t m_autorepeat_code;
--
2.6.6