summaryrefslogtreecommitdiffstats
path: root/src/client/qwaylandinputdevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/qwaylandinputdevice.cpp')
-rw-r--r--src/client/qwaylandinputdevice.cpp142
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();