File indexing completed on 2025-04-27 11:32:59
0001 /* 0002 SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "x11_standalone_effects_keyboard_interception_filter.h" 0008 #include "x11_standalone_effects.h" 0009 #include "x11_standalone_keyboard.h" 0010 0011 #include <QDebug> 0012 #include <QKeyEvent> 0013 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0014 #include <QtXkbCommonSupport/private/qxkbcommon_p.h> 0015 #else 0016 #include <QtGui/private/qxkbcommon_p.h> 0017 #endif 0018 0019 namespace KWin 0020 { 0021 0022 EffectsKeyboardInterceptionX11Filter::EffectsKeyboardInterceptionX11Filter(EffectsHandlerImpl *effects, X11Keyboard *keyboard) 0023 : X11EventFilter(QVector<int>{XCB_KEY_PRESS, XCB_KEY_RELEASE}) 0024 , m_effects(effects) 0025 , m_keyboard(keyboard) 0026 { 0027 } 0028 0029 bool EffectsKeyboardInterceptionX11Filter::event(xcb_generic_event_t *event) 0030 { 0031 switch (event->response_type & ~0x80) { 0032 case XCB_KEY_PRESS: { 0033 const auto keyEvent = reinterpret_cast<xcb_key_press_event_t *>(event); 0034 processKey(true, keyEvent->detail, keyEvent->time); 0035 return true; 0036 } 0037 case XCB_KEY_RELEASE: { 0038 const auto keyEvent = reinterpret_cast<xcb_key_release_event_t *>(event); 0039 processKey(false, keyEvent->detail, keyEvent->time); 0040 return true; 0041 } 0042 default: 0043 return false; 0044 } 0045 } 0046 0047 void EffectsKeyboardInterceptionX11Filter::processKey(bool press, xcb_keycode_t keycode, xcb_timestamp_t timestamp) 0048 { 0049 const xkb_keysym_t keysym = xkb_state_key_get_one_sym(m_keyboard->xkbState(), keycode); 0050 0051 Qt::KeyboardModifiers modifiers = m_keyboard->modifiers(); 0052 if (QXkbCommon::isKeypad(keysym)) { 0053 modifiers |= Qt::KeypadModifier; 0054 } 0055 0056 const int qtKey = QXkbCommon::keysymToQtKey(keysym, modifiers, m_keyboard->xkbState(), keycode); 0057 const QString text = QXkbCommon::lookupString(m_keyboard->xkbState(), keycode); 0058 0059 QKeyEvent keyEvent(press ? QEvent::KeyPress : QEvent::KeyRelease, qtKey, modifiers, text); 0060 keyEvent.setTimestamp(timestamp); 0061 0062 m_effects->grabbedKeyboardEvent(&keyEvent); 0063 } 0064 0065 } // namespace KWin