diff options
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 22 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 1 |
2 files changed, 17 insertions, 6 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c81858c408..c703fbef22 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2416,6 +2416,17 @@ static inline int fixed1616ToInt(FP1616 val) return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } +void QXcbWindow::handleXIMouseButtonState(const xcb_ge_event_t *event) +{ + QXcbConnection *conn = connection(); + const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event); + if (ev->buttons_len > 0) { + unsigned char *buttonMask = (unsigned char *) &ev[1]; + for (int i = 1; i <= 15; ++i) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } +} + // With XI 2.2+ press/release/motion comes here instead of the above handlers. void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) { @@ -2431,12 +2442,6 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail); - if (ev->buttons_len > 0) { - unsigned char *buttonMask = (unsigned char *) &ev[1]; - for (int i = 1; i <= 15; ++i) - conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); - } - const char *sourceName = 0; if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) { const QMetaObject *metaObject = qt_getEnumMetaObject(source); @@ -2446,18 +2451,23 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource switch (ev->evtype) { case XI_ButtonPress: + handleXIMouseButtonState(event); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, true); handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_ButtonRelease: + handleXIMouseButtonState(event); if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName); conn->setButton(button, false); handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); break; case XI_Motion: + // Here we do NOT call handleXIMouseButtonState because we don't expect button state change to be bundled with motion. + // When a touchscreen is pressed, an XI_Motion event occurs in which XIMaskIsSet says the left button is pressed, + // but we don't want QGuiApplicationPrivate::processMouseEvent() to react by generating a mouse press event. if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName); handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index f62938ba8a..41dccbe4af 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -139,6 +139,7 @@ public: void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; #ifdef XCB_USE_XINPUT22 + void handleXIMouseButtonState(const xcb_ge_event_t *); void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) Q_DECL_OVERRIDE; void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; #endif |