diff options
-rw-r--r-- | src/client/client.pro | 2 | ||||
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 6 | ||||
-rw-r--r-- | src/client/qwaylanddisplay_p.h | 12 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 78 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice_p.h | 21 | ||||
-rw-r--r-- | src/client/qwaylandintegration.cpp | 2 |
6 files changed, 57 insertions, 64 deletions
diff --git a/src/client/client.pro b/src/client/client.pro index 9f7d979d..81152f75 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -16,7 +16,7 @@ CONFIG -= precompile_header CONFIG += link_pkgconfig wayland-scanner qtConfig(xkbcommon) { - QT_PRIVATE += xkbcommon_support-private + QT_FOR_PRIVATE += xkbcommon_support-private } qtHaveModule(linuxaccessibility_support_private): \ diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 22a79124..e96e52fe 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -142,6 +142,12 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); +#if QT_CONFIG(xkbcommon) + mXkbContext.reset(xkb_context_new(XKB_CONTEXT_NO_FLAGS)); + if (!mXkbContext) + qCWarning(lcQpaWayland, "failed to create xkb context"); +#endif + forceRoundTrip(); } diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 836ee0f9..3ced2d9e 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -65,6 +65,10 @@ #include <qpa/qplatforminputcontextfactory_p.h> +#if QT_CONFIG(xkbcommon) +#include <QtXkbCommonSupport/private/qxkbcommon_p.h> +#endif + struct wl_cursor_image; QT_BEGIN_NAMESPACE @@ -111,6 +115,10 @@ public: QWaylandDisplay(QWaylandIntegration *waylandIntegration); ~QWaylandDisplay(void) override; +#if QT_CONFIG(xkbcommon) + struct xkb_context *xkbContext() const { return mXkbContext.get(); } +#endif + QList<QWaylandScreen *> screens() const { return mScreens; } QWaylandScreen *screenForOutput(struct wl_output *output) const; @@ -246,6 +254,10 @@ private: void registry_global(uint32_t id, const QString &interface, uint32_t version) override; void registry_global_remove(uint32_t id) override; +#if QT_CONFIG(xkbcommon) + QXkbCommon::ScopedXKBContext mXkbContext; +#endif + friend class QWaylandIntegration; }; diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index f31ab274..572ce1e5 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -70,10 +70,6 @@ #include <QtGui/QGuiApplication> -#if QT_CONFIG(xkbcommon) -#include <xkbcommon/xkbcommon.h> -#endif - QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -85,51 +81,34 @@ QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p) } #if QT_CONFIG(xkbcommon) -bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() +bool QWaylandInputDevice::Keyboard::createDefaultKeymap() { - if (mXkbContext && mXkbMap && mXkbState) { - return true; - } + struct xkb_context *ctx = mParent->mQDisplay->xkbContext(); + if (!ctx) + return false; - xkb_rule_names names; - names.rules = strdup("evdev"); - names.model = strdup("pc105"); - names.layout = strdup("us"); - names.variant = strdup(""); - names.options = strdup(""); - - mXkbContext = xkb_context_new(xkb_context_flags(0)); - if (mXkbContext) { - mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); - if (mXkbMap) { - mXkbState = xkb_state_new(mXkbMap); - } - } + struct xkb_rule_names names; + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + names.variant = ""; + names.options = ""; - if (!mXkbContext || !mXkbMap || !mXkbState) { - qWarning() << "xkb_map_new_from_names failed, no key input"; + mXkbKeymap.reset(xkb_keymap_new_from_names(ctx, &names, XKB_KEYMAP_COMPILE_NO_FLAGS)); + if (mXkbKeymap) + mXkbState.reset(xkb_state_new(mXkbKeymap.get())); + + if (!mXkbKeymap || !mXkbState) { + qCWarning(lcQpaWayland, "failed to create default keymap"); return false; } return true; } - -void QWaylandInputDevice::Keyboard::releaseKeyMap() -{ - if (mXkbState) - xkb_state_unref(mXkbState); - if (mXkbMap) - xkb_map_unref(mXkbMap); - if (mXkbContext) - xkb_context_unref(mXkbContext); -} #endif QWaylandInputDevice::Keyboard::~Keyboard() { -#if QT_CONFIG(xkbcommon) - releaseKeyMap(); -#endif if (mFocus) QWindowSystemInterface::handleWindowActivated(nullptr); if (mParent->mVersion >= 3) @@ -501,7 +480,7 @@ Qt::KeyboardModifiers QWaylandInputDevice::Keyboard::modifiers() const if (!mXkbState) return ret; - ret = QWaylandXkb::modifiers(mXkbState); + ret = QWaylandXkb::modifiers(mXkbState.get()); #endif return ret; @@ -761,16 +740,16 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, return; } - // Release the old keymap resources in the case they were already created in - // the key event or when the compositor issues a new map - releaseKeyMap(); - - mXkbContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + mXkbKeymap.reset(xkb_keymap_new_from_string(mParent->mQDisplay->xkbContext(), map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + XKB_KEYMAP_COMPILE_NO_FLAGS)); munmap(map_str, size); close(fd); - mXkbState = xkb_state_new(mXkbMap); + if (mXkbKeymap) + mXkbState.reset(xkb_state_new(mXkbKeymap.get())); + else + mXkbState.reset(nullptr); #else Q_UNUSED(format); Q_UNUSED(fd); @@ -860,11 +839,10 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, mParent->mQDisplay->setLastInputDevice(mParent, serial, window); #if QT_CONFIG(xkbcommon) - if (!createDefaultKeyMap()) { + if ((!mXkbKeymap || !mXkbState) && !createDefaultKeymap()) return; - } - xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); + xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState.get(), code); Qt::KeyboardModifiers modifiers = mParent->modifiers(); @@ -878,7 +856,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, if (state == WL_KEYBOARD_KEY_STATE_PRESSED #if QT_CONFIG(xkbcommon) - && xkb_keymap_key_repeats(mXkbMap, code) + && xkb_keymap_key_repeats(mXkbKeymap.get(), code) #endif ) { mRepeatKey = qtkey; @@ -952,7 +930,7 @@ void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial, Q_UNUSED(serial); #if QT_CONFIG(xkbcommon) if (mXkbState) - xkb_state_update_mask(mXkbState, + xkb_state_update_mask(mXkbState.get(), mods_depressed, mods_latched, mods_locked, 0, 0, group); mNativeModifiers = mods_depressed | mods_latched | mods_locked; diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 4149e500..98e60286 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -65,8 +65,7 @@ #include <QtWaylandClient/private/qwayland-wayland.h> #if QT_CONFIG(xkbcommon) -#include <xkbcommon/xkbcommon.h> -#include <xkbcommon/xkbcommon-keysyms.h> +#include <QtXkbCommonSupport/private/qxkbcommon_p.h> #endif #include <QtCore/QDebug> @@ -209,11 +208,7 @@ public: QWaylandInputDevice *mParent = nullptr; ::wl_surface *mFocus = nullptr; -#if QT_CONFIG(xkbcommon) - xkb_context *mXkbContext = nullptr; - xkb_keymap *mXkbMap = nullptr; - xkb_state *mXkbState = nullptr; -#endif + uint32_t mNativeModifiers = 0; int mRepeatKey; @@ -222,9 +217,6 @@ public: int mRepeatRate = 25; int mRepeatDelay = 400; QString mRepeatText; -#if QT_CONFIG(xkbcommon) - xkb_keysym_t mRepeatSym; -#endif QTimer mRepeatTimer; Qt::KeyboardModifiers modifiers() const; @@ -236,12 +228,17 @@ private slots: private: #if QT_CONFIG(xkbcommon) - bool createDefaultKeyMap(); - void releaseKeyMap(); + bool createDefaultKeymap(); #endif void sendKey(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text = QString(), bool autorep = false, ushort count = 1); + +#if QT_CONFIG(xkbcommon) + xkb_keysym_t mRepeatSym = XKB_KEY_NoSymbol; + QXkbCommon::ScopedXKBKeymap mXkbKeymap; + QXkbCommon::ScopedXKBState mXkbState; +#endif }; class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice::Pointer : public QObject, public QtWayland::wl_pointer diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index 8bfe3b6f..3a389d9e 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -479,7 +479,7 @@ void QWaylandIntegration::reconfigureInputContext() mInputContext.reset(QPlatformInputContextFactory::create(defaultInputContext)); #if QT_CONFIG(xkbcommon) - QXkbCommon::setXkbContext(mInputContext.data(), xkb_context_new(XKB_CONTEXT_NO_FLAGS)); + QXkbCommon::setXkbContext(mInputContext.data(), mDisplay->xkbContext()); #endif // Even if compositor-side input context handling has been requested, we fallback to |