11#include <QWaylandClientExtension>
12#include <qwayland-wayland.h>
14#include <config-qt-wayland-patches-present.h>
15#include <QtGui/private/qxkbcommon_p.h>
21#if KRITA_QT_HAS_XKB_CONTEXT_IN_NATIVE_INTERFACE
23#include <QGuiApplication>
24#include <QtWaylandClient/private/qwaylandintegration_p.h>
28#include <QtGui/private/qguiapplication_p.h>
29#include <QtWaylandClient/private/qwaylandintegration_p.h>
30#include <QtWaylandClient/private/qwaylanddisplay_p.h>
35#if KRITA_QT_HAS_XKB_CONTEXT_IN_NATIVE_INTERFACE
36 auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>();
37 return waylandApp ? waylandApp->xkbContext() :
nullptr;
43 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
44 auto waylandIntegration =
dynamic_cast<QtWaylandClient::QWaylandIntegration *
>(platformIntegration);
45 return waylandIntegration ? waylandIntegration->display()->xkbContext() :
nullptr;
57 : wl_keyboard(keyboard)
74 xkb_keysym_t sym = xkb_state_key_get_one_sym(
mXkbState.get(), code);
77 Qt::Key qtKey =
static_cast<Qt::Key
>(QXkbCommon::keysymToQtKey(sym,
modifiers,
mXkbState.get(), code));
79 if (qtKey != Qt::Key_unknown)
94 Qt::KeyboardModifiers ret = Qt::NoModifier;
97 ret = QXkbCommon::modifiers(
mXkbState.get());
106 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
107 qDebug() <<
"unknown keymap format:" << format;
112 char *map_str =
static_cast<char *
>(mmap(
nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0));
113 if (map_str == MAP_FAILED) {
120 mXkbKeymap.reset(xkb_keymap_new_from_string(xkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS));
121 QXkbCommon::verifyHasLatinLayout(
mXkbKeymap.get());
124 munmap(map_str, size);
133 void keyboard_key([[maybe_unused]] uint32_t serial, [[maybe_unused]] uint32_t time, uint32_t key, uint32_t state)
override
135 const bool isDown = state != WL_KEYBOARD_KEY_STATE_RELEASED;
139 qWarning().nospace() <<
"WARNING: got a key-down for a key (" << Qt::hex << Qt::showbase << key <<
") which is reported to be pressed already!";
146 qWarning().nospace() <<
"WARNING: got a key-up for a key (" << Qt::hex << Qt::showbase << key <<
") which is NOT reported to be pressed!";
152 void keyboard_modifiers([[maybe_unused]] uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
override
155 xkb_state_update_mask(
mXkbState.get(), mods_depressed, mods_latched, mods_locked, 0, 0, group);
159 void keyboard_enter([[maybe_unused]] uint32_t serial, [[maybe_unused]] wl_surface *surface, [[maybe_unused]] wl_array *keys)
override
162 mNativeKeys.reserve(keys->size /
sizeof(uint32_t));
164 for (
const uint32_t *keyPtr =
static_cast<const uint32_t *
>(keys->data);
165 reinterpret_cast<const char *
>(keyPtr) <
static_cast<const char *
>(keys->data) + keys->size;
172 void keyboard_leave([[maybe_unused]] uint32_t serial, [[maybe_unused]] wl_surface *surface)
override
195 :
public QWaylandClientExtensionTemplate<KisWaylandKeyboardWatcher::Seat>
196 ,
public QtWayland::wl_seat
212 std::unique_ptr<KisWaylandKeyboardWatcher::Keyboard>
m_keyboard;
216 : QWaylandClientExtensionTemplate(5)
229 const bool hasKeyboard = capabilities & capability_keyboard;
230 if (hasKeyboard && !m_keyboard) {
231 m_keyboard = std::make_unique<KisWaylandKeyboardWatcher::Keyboard>(get_keyboard());
232 }
else if (!hasKeyboard && m_keyboard) {
238 return m_keyboard && m_keyboard->hasKeyboardFocus();
244 return m_keyboard->pressedKeys();
252 return Qt::NoModifier;
254 return m_keyboard->modifiers();
273 return m_seat->hasKeyboardFocus();
278 return m_seat->pressedKeys();
283 return m_seat->modifiers();
286#include "KisWaylandKeyboardWatcher.moc"
static struct xkb_context * getGlobalXkbContextFromQt()
Qt::KeyboardModifiers modifiers() const
QList< Qt::Key > pressedKeys() const
void keyboard_modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) override
uint32_t mNativeModifiers
void keyboard_enter(uint32_t serial, wl_surface *surface, wl_array *keys) override
QXkbCommon::ScopedXKBKeymap mXkbKeymap
bool hasKeyboardFocus() const
QList< uint32_t > mNativeKeys
QXkbCommon::ScopedXKBState mXkbState
Keyboard(::wl_keyboard *keyboard)
void keyboard_leave(uint32_t serial, wl_surface *surface) override
void keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) override
void keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) override
Qt::KeyboardModifiers modifiers() const
QList< Qt::Key > pressedKeys() const
bool hasKeyboardFocus() const
std::unique_ptr< KisWaylandKeyboardWatcher::Keyboard > m_keyboard
void seat_capabilities(uint32_t capabilities) override
QList< Qt::Key > pressedKeys() const
~KisWaylandKeyboardWatcher()
bool hasKeyboardFocus() const
std::unique_ptr< Seat > m_seat
Qt::KeyboardModifiers modifiers() const
KisWaylandKeyboardWatcher()