Commit d518783c authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Fix unbalanced KeyPress/Release on non-latin keyboard on Linux

Key release should come for exactly the same qt-key that was pressed
before to keep them balanced. Even when the modifiers state changes
in the meantime.

CCBUG:454256
parent ebac6865
Pipeline #181017 passed with stage
in 39 minutes and 52 seconds
From 9e4969677dcdc80b19090faa71c722d9c3a43cf9 Mon Sep 17 00:00:00 2001
From: Dmitry Kazakov <dimula73@gmail.com>
Date: Thu, 26 May 2022 11:46:19 +0300
Subject: [PATCH] Fix unbalanced KeyPress/Release on non-latin keyboard on
Linux
Key release should come for exactly the same qt-key that was pressed
before to keep them balanced. Even when the modifiers state changes
in the meantime.
https://bugs.kde.org/show_bug.cgi?id=454256
---
src/plugins/platforms/xcb/qxcbkeyboard.cpp | 49 +++++++++++++++++-----
src/plugins/platforms/xcb/qxcbkeyboard.h | 6 +++
2 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index c5dc7b21..a02f76da 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1577,17 +1577,44 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
m_isAutoRepeat = false;
} else {
m_isAutoRepeat = false;
- // Look at the next event in the queue to see if we are auto-repeating.
- connection()->eventQueue()->peek(QXcbEventQueue::PeekRetainMatch,
- [this, time, code](xcb_generic_event_t *event, int type) {
- if (type == XCB_KEY_PRESS) {
- auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
- m_isAutoRepeat = keyPress->time == time && keyPress->detail == code;
- if (m_isAutoRepeat)
- m_autoRepeatCode = code;
- }
- return true;
- });
+
+ if (m_keyPressRegister.contains(code) && m_keyPressRegister[code].qtCode == qtcode) {
+ // Look at the next event in the queue to see if we are auto-repeating.
+ connection()->eventQueue()->peek(QXcbEventQueue::PeekRetainMatch,
+ [this, time, code](xcb_generic_event_t *event, int type) {
+ if (type == XCB_KEY_PRESS) {
+ auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
+ m_isAutoRepeat = keyPress->time == time && keyPress->detail == code;
+ if (m_isAutoRepeat)
+ m_autoRepeatCode = code;
+ }
+ return true;
+ });
+ }
+ }
+
+ if (type == QEvent::KeyPress) {
+ if (m_keyPressRegister.contains(code)) {
+ qCWarning(lcQpaKeyboard) << "QXcbKeyboard::handleKeyEvent: key pressed, but it is already present in the registry"
+ << "code" << code
+ << "qtcode" << qtcode
+ << "registered qtcode" << m_keyPressRegister[code].qtCode;
+ }
+ m_keyPressRegister[code] = {qtcode, text};
+
+ } else {
+ if (m_keyPressRegister.contains(code)) {
+ if (m_keyPressRegister[code].qtCode != qtcode) {
+ qCDebug(lcQpaKeyboard) << "QXcbKeyboard::handleKeyEvent: replacing qtcode on release" << qtcode << " -> " << m_keyPressRegister[code].qtCode;
+ qtcode = m_keyPressRegister[code].qtCode;
+ text = m_keyPressRegister[code].text;
+ }
+ m_keyPressRegister.remove(code);
+ } else {
+ qCWarning(lcQpaKeyboard) << "QXcbKeyboard::handleKeyEvent: key released, but it has no record in the registry"
+ << "code" << code
+ << "qtcode" << qtcode;
+ }
}
bool filtered = false;
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index f8490592..3a0de5b7 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -119,6 +119,12 @@ private:
bool m_isAutoRepeat = false;
xcb_keycode_t m_autoRepeatCode = 0;
+ struct KeyPressRecord {
+ int qtCode;
+ QString text;
+ };
+ QHash<xcb_keycode_t, KeyPressRecord> m_keyPressRegister;
+
struct _mod_masks {
uint alt;
uint altgr;
--
2.17.1
......@@ -333,7 +333,7 @@ elseif (NOT APPLE)
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/frac_dpi_paint_artifacts/0002-Fix-QPainter-off-by-one-clipping-for-some-non-intege.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/frac_dpi_paint_artifacts/0003-Fix-under-non-integer-scaling-incorrect-update-area.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0001-QMenu-make-less-sensitive-to-mouse-jitter.patch
COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/0001-Fix-unbalanced-KeyPress-Release-on-non-latin-keyboar.patch
CMAKE_ARGS -DOPENSSL_LIBS='-L${EXTPREFIX_qt}/lib -lssl -lcrypto'
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment