diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 37 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 2 |
5 files changed, 31 insertions, 20 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2834ff3224..915c29edcc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -417,7 +417,7 @@ void QXcbConnection::initializeScreens() qWarning("failed to get the current screen resources"); free(error); } else { - xcb_timestamp_t timestamp; + xcb_timestamp_t timestamp = 0; xcb_randr_output_t *outputs = Q_NULLPTR; int outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources_current.data()); if (outputCount) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 3754890796..19c076e888 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -517,6 +517,7 @@ public: #ifdef XCB_USE_XINPUT22 bool xi2MouseEvents() const; + bool isTouchScreen(int id) const; #endif protected: diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 0ace79a4f5..d91cbfe82d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -1025,6 +1025,14 @@ Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) return Qt::NoButton; } +bool QXcbConnection::isTouchScreen(int id) const +{ + auto device = m_touchDevices.value(id); + return device && device->qtTouchDevice + && device->qtTouchDevice->type() == QTouchDevice::TouchScreen; +} + +#if QT_CONFIG(tabletevent) static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { // keep in sync with wacom_intuos_inout() in Linux kernel driver wacom_wac.c switch (toolId) { @@ -1058,7 +1066,6 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { return QTabletEvent::Stylus; // Safe default assumption if nonzero } -#ifndef QT_NO_TABLETEVENT bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData) { bool handled = true; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0275cf5630..2d52f5dd46 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -315,6 +315,7 @@ static const char *wm_window_role_property_id = "_q_xcb_wm_window_role"; QXcbWindow::QXcbWindow(QWindow *window) : QPlatformWindow(window) , m_window(0) + , m_cmap(0) , m_syncCounter(0) , m_gravity(XCB_GRAVITY_STATIC) , m_mapped(false) @@ -443,7 +444,6 @@ void QXcbWindow::create() m_visualId = visual->visual_id; m_depth = platformScreen->depthOfVisual(m_visualId); m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap); - xcb_colormap_t colormap = 0; quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL @@ -455,10 +455,10 @@ void QXcbWindow::create() static const bool haveOpenGL = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL); if ((window()->supportsOpenGL() && haveOpenGL) || m_format.hasAlpha()) { - colormap = xcb_generate_id(xcb_connection()); + m_cmap = xcb_generate_id(xcb_connection()); Q_XCB_CALL(xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, - colormap, + m_cmap, xcb_parent_id, m_visualId)); @@ -472,7 +472,7 @@ void QXcbWindow::create() type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint), type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, defaultEventMask, - colormap + m_cmap }; m_window = xcb_generate_id(xcb_connection()); @@ -638,6 +638,9 @@ void QXcbWindow::destroy() Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window)); m_window = 0; } + if (m_cmap) { + xcb_free_colormap(xcb_connection(), m_cmap); + } m_mapped = false; if (m_pendingSyncRequest) @@ -2420,22 +2423,27 @@ static inline int fixed1616ToInt(FP1616 val) return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } -void QXcbWindow::handleXIMouseButtonState(const xcb_ge_event_t *event) +// 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) { QXcbConnection *conn = connection(); - const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event); + xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); + if (ev->buttons_len > 0) { unsigned char *buttonMask = (unsigned char *) &ev[1]; + // There is a bug in the evdev driver which leads to receiving mouse events without + // XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188 + // Filter them out by other attributes: when their source device is a touch screen + // and the LMB is pressed. + if (XIMaskIsSet(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) { + if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) + qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid); + return; + } 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) -{ - QXcbConnection *conn = connection(); - xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); const int event_x = fixed1616ToInt(ev->event_x); const int event_y = fixed1616ToInt(ev->event_y); @@ -2455,23 +2463,18 @@ 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 41befbf66f..680629c040 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -139,7 +139,6 @@ public: void handleFocusOutEvent(const xcb_focus_out_event_t *event) override; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override; #ifdef XCB_USE_XINPUT22 - void handleXIMouseButtonState(const xcb_ge_event_t *); void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override; void handleXIEnterLeave(xcb_ge_event_t *) override; #endif @@ -235,6 +234,7 @@ protected: quint8 mode, quint8 detail, xcb_timestamp_t timestamp); xcb_window_t m_window; + xcb_colormap_t m_cmap; uint m_depth; QImage::Format m_imageFormat; |