diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 15616c1cea..d22ea00d8a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -119,6 +119,8 @@ enum { QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE); + #undef FocusIn enum QX11EmbedFocusInDetail { @@ -256,6 +258,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) free_prop = true; } +#ifndef QT_NO_TEXTCODEC static const QTextCodec* mapper = QTextCodec::codecForLocale(); int errCode = 0; if (mapper) { @@ -279,6 +282,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) tp.nitems = qcs.length(); free_prop = false; } +#endif return &tp; } #endif // XCB_USE_XLIB @@ -2416,6 +2420,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 +2446,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 +2455,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); @@ -2855,9 +2869,8 @@ void QXcbWindow::setMask(const QRegion ®ion) XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE); } else { QVector<xcb_rectangle_t> rects; - const QVector<QRect> regionRects = region.rects(); - rects.reserve(regionRects.count()); - foreach (const QRect &r, regionRects) + rects.reserve(region.rectCount()); + for (const QRect &r : region) rects.push_back(qRectToXCBRectangle(r)); xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED, |