forked from pool/libqt5-qtbase
150 lines
6.3 KiB
Diff
150 lines
6.3 KiB
Diff
|
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
|
|||
|
|