diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index f744b34901..0c8e78491e 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; } +#if QT_CONFIG(textcodec) static const QTextCodec* mapper = QTextCodec::codecForLocale(); int errCode = 0; if (mapper) { @@ -271,6 +274,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) mapper = QTextCodec::codecForName("latin1"); if (!mapper || !mapper->canEncode(s)) return Q_NULLPTR; +#endif static QByteArray qcs; qcs = s.toLatin1(); tp.value = (uchar*)qcs.data(); @@ -278,7 +282,9 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) tp.format = 8; tp.nitems = qcs.length(); free_prop = false; +#if QT_CONFIG(textcodec) } +#endif return &tp; } #endif // XCB_USE_XLIB @@ -2417,6 +2423,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) { @@ -2432,12 +2449,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); @@ -2447,18 +2458,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); @@ -2856,9 +2872,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, |