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