diff options
Diffstat (limited to 'src/client/qwaylandinputdevice.cpp')
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 142 |
1 files changed, 85 insertions, 57 deletions
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 4def0de8f..b34504a1f 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -70,19 +70,16 @@ #include <QtGui/QGuiApplication> +#if QT_CONFIG(xkbcommon_evdev) +#include <xkbcommon/xkbcommon-compose.h> +#endif + QT_BEGIN_NAMESPACE namespace QtWaylandClient { QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) -#if QT_CONFIG(xkbcommon_evdev) - , mXkbContext(0) - , mXkbMap(0) - , mXkbState(0) -#endif - , mNativeModifiers(0) { connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey())); } @@ -113,6 +110,7 @@ bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() qWarning() << "xkb_map_new_from_names failed, no key input"; return false; } + createComposeState(); return true; } @@ -125,15 +123,45 @@ void QWaylandInputDevice::Keyboard::releaseKeyMap() if (mXkbContext) xkb_context_unref(mXkbContext); } + +void QWaylandInputDevice::Keyboard::createComposeState() +{ + static const char *locale = nullptr; + if (!locale) { + locale = getenv("LC_ALL"); + if (!locale) + locale = getenv("LC_CTYPE"); + if (!locale) + locale = getenv("LANG"); + if (!locale) + locale = "C"; + } + + mXkbComposeTable = xkb_compose_table_new_from_locale(mXkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (mXkbComposeTable) + mXkbComposeState = xkb_compose_state_new(mXkbComposeTable, XKB_COMPOSE_STATE_NO_FLAGS); +} + +void QWaylandInputDevice::Keyboard::releaseComposeState() +{ + if (mXkbComposeState) + xkb_compose_state_unref(mXkbComposeState); + if (mXkbComposeTable) + xkb_compose_table_unref(mXkbComposeTable); + mXkbComposeState = nullptr; + mXkbComposeTable = nullptr; +} + #endif QWaylandInputDevice::Keyboard::~Keyboard() { #if QT_CONFIG(xkbcommon_evdev) + releaseComposeState(); releaseKeyMap(); #endif if (mFocus) - QWindowSystemInterface::handleWindowActivated(0); + QWindowSystemInterface::handleWindowActivated(nullptr); if (mParent->mVersion >= 3) wl_keyboard_release(object()); else @@ -147,16 +175,6 @@ void QWaylandInputDevice::Keyboard::stopRepeat() QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) - , mEnterSerial(0) -#if QT_CONFIG(cursor) - , mCursorSerial(0) -#endif - , mButtons(0) -#if QT_CONFIG(cursor) - , mCursorBuffer(nullptr) - , mCursorShape(Qt::BitmapCursor) -#endif { } @@ -170,7 +188,6 @@ QWaylandInputDevice::Pointer::~Pointer() QWaylandInputDevice::Touch::Touch(QWaylandInputDevice *p) : mParent(p) - , mFocus(0) { } @@ -188,17 +205,6 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, , mQDisplay(display) , mDisplay(display->wl_display()) , mVersion(qMin(version, 4)) - , mCaps(0) -#if QT_CONFIG(wayland_datadevice) - , mDataDevice(0) -#endif - , mKeyboard(0) - , mPointer(0) - , mTouch(0) - , mTextInput(0) - , mTime(0) - , mSerial(0) - , mTouchDevice(0) { #if QT_CONFIG(wayland_datadevice) if (mQDisplay->dndSelectionHandler()) { @@ -227,7 +233,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) mKeyboard->init(get_keyboard()); } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && mKeyboard) { delete mKeyboard; - mKeyboard = 0; + mKeyboard = nullptr; } if (caps & WL_SEAT_CAPABILITY_POINTER && !mPointer) { @@ -236,7 +242,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) pointerSurface = mQDisplay->createSurface(this); } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && mPointer) { delete mPointer; - mPointer = 0; + mPointer = nullptr; } if (caps & WL_SEAT_CAPABILITY_TOUCH && !mTouch) { @@ -251,7 +257,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps) } } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && mTouch) { delete mTouch; - mTouch = 0; + mTouch = nullptr; } } @@ -272,14 +278,8 @@ QWaylandInputDevice::Touch *QWaylandInputDevice::createTouch(QWaylandInputDevice void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) { - if (mPointer && window == mPointer->mFocus) - mPointer->mFocus = 0; - if (mKeyboard && window == mKeyboard->mFocus) { - mKeyboard->mFocus = 0; + if (mKeyboard && window == mKeyboard->mFocus) mKeyboard->stopRepeat(); - } - if (mTouch && window == mTouch->mFocus) - mTouch->mFocus = 0; } void QWaylandInputDevice::handleEndDrag() @@ -321,17 +321,17 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) QWaylandWindow *QWaylandInputDevice::pointerFocus() const { - return mPointer ? mPointer->mFocus : 0; + return mPointer ? mPointer->mFocus : nullptr; } QWaylandWindow *QWaylandInputDevice::keyboardFocus() const { - return mKeyboard ? mKeyboard->mFocus : 0; + return mKeyboard ? mKeyboard->mFocus : nullptr; } QWaylandWindow *QWaylandInputDevice::touchFocus() const { - return mTouch ? mTouch->mFocus : 0; + return mTouch ? mTouch->mFocus : nullptr; } Qt::KeyboardModifiers QWaylandInputDevice::modifiers() const @@ -411,7 +411,7 @@ void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, const QPoint &hotS /* Hide cursor */ if (!buffer) { - mPointer->set_cursor(mPointer->mEnterSerial, NULL, 0, 0); + mPointer->set_cursor(mPointer->mEnterSerial, nullptr, 0, 0); return; } @@ -434,7 +434,7 @@ class EnterEvent : public QWaylandPointerEvent { public: EnterEvent(const QPointF &l, const QPointF &g) - : QWaylandPointerEvent(QWaylandPointerEvent::Enter, 0, l, g, 0, Qt::NoModifier) + : QWaylandPointerEvent(QWaylandPointerEvent::Enter, 0, l, g, nullptr, Qt::NoModifier) {} }; @@ -474,7 +474,7 @@ void QWaylandInputDevice::Pointer::pointer_leave(uint32_t time, struct wl_surfac QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseLeave(mParent); } - mFocus = 0; + mFocus = nullptr; mButtons = Qt::NoButton; mParent->mTime = time; @@ -493,7 +493,7 @@ void QWaylandInputDevice::Pointer::pointer_motion(uint32_t time, wl_fixed_t surf { QWaylandWindow *window = mFocus; - if (window == NULL) { + if (!window) { // We destroyed the pointer focus surface, but the server // didn't get the message yet. return; @@ -595,7 +595,7 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in QPoint pixelDelta; QPoint angleDelta; - if (window == NULL) { + if (!window) { // We destroyed the pointer focus surface, but the server // didn't get the message yet. return; @@ -624,7 +624,7 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, return; } - char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + char *map_str = static_cast<char *>(mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0)); if (map_str == MAP_FAILED) { close(fd); return; @@ -632,14 +632,17 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, // Release the old keymap resources in the case they were already created in // the key event or when the compositor issues a new map + releaseComposeState(); releaseKeyMap(); - mXkbContext = xkb_context_new(xkb_context_flags(0)); - mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + 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); munmap(map_str, size); close(fd); mXkbState = xkb_state_new(mXkbMap); + createComposeState(); + #else Q_UNUSED(format); Q_UNUSED(fd); @@ -672,7 +675,7 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf window->unfocus(); } - mFocus = NULL; + mFocus = nullptr; mParent->mQDisplay->handleKeyboardFocusChanged(mParent); @@ -703,7 +706,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, { QWaylandWindow *window = mFocus; uint32_t code = key + 8; - bool isDown = state != 0; + bool isDown = state != WL_KEYBOARD_KEY_STATE_RELEASED; QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; QString text; int qtkey = key + 8; // qt-compositor substracts 8 for some reason @@ -723,12 +726,37 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, return; } - const xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); + QString composedText; + xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code); + if (mXkbComposeState) { + if (isDown) + xkb_compose_state_feed(mXkbComposeState, sym); + xkb_compose_status status = xkb_compose_state_get_status(mXkbComposeState); + + switch (status) { + case XKB_COMPOSE_COMPOSED: { + int size = xkb_compose_state_get_utf8(mXkbComposeState, nullptr, 0); + QVarLengthArray<char, 32> buffer(size + 1); + xkb_compose_state_get_utf8(mXkbComposeState, buffer.data(), buffer.size()); + composedText = QString::fromUtf8(buffer.constData()); + sym = xkb_compose_state_get_one_sym(mXkbComposeState); + xkb_compose_state_reset(mXkbComposeState); + } break; + case XKB_COMPOSE_COMPOSING: + case XKB_COMPOSE_CANCELLED: + return; + case XKB_COMPOSE_NOTHING: + break; + } + } Qt::KeyboardModifiers modifiers = mParent->modifiers(); std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers); + if (!composedText.isNull()) + text = composedText; + sendKey(window->window(), time, type, qtkey, modifiers, code, sym, mNativeModifiers, text); #else // Generic fallback for single hard keys: Assume 'key' is a Qt key code. @@ -817,7 +845,7 @@ void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_ { Q_UNUSED(serial); Q_UNUSED(time); - mFocus = 0; + mFocus = nullptr; mParent->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); // As of Weston 1.5.90 there is no touch_frame after the last touch_up @@ -843,7 +871,7 @@ void QWaylandInputDevice::Touch::touch_cancel() if (touchExt) touchExt->touchCanceled(); - QWindowSystemInterface::handleTouchCancelEvent(0, mParent->mTouchDevice); + QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); } void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) @@ -928,7 +956,7 @@ void QWaylandInputDevice::Touch::touch_frame() return; } - QWindow *window = mFocus ? mFocus->window() : 0; + QWindow *window = mFocus ? mFocus->window() : nullptr; if (mFocus) { const QWindowSystemInterface::TouchPoint &tp = mTouchPoints.last(); |