diff options
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 13 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 34 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 201 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbkeyboard.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 23 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 2 |
7 files changed, 165 insertions, 114 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 8c444ce7aa..88d8d86c96 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1023,7 +1023,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); - // press/release/motion is only delivered here when XI 2.2+ is _not_ in use case XCB_BUTTON_PRESS: { xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; m_keyboard->updateXKBStateFromCore(ev->state); @@ -1066,14 +1065,14 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) handleClientMessageEvent((xcb_client_message_event_t *)event); break; case XCB_ENTER_NOTIFY: -#ifdef XCB_USE_XINPUT22 - if (isAtLeastXI22() && xi2MouseEvents()) +#if QT_CONFIG(xinput2) + if (hasXInput2() && !xi2MouseEventsDisabled()) break; #endif HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); case XCB_LEAVE_NOTIFY: -#ifdef XCB_USE_XINPUT22 - if (isAtLeastXI22() && xi2MouseEvents()) +#if QT_CONFIG(xinput2) + if (hasXInput2() && !xi2MouseEventsDisabled()) break; #endif m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); @@ -1138,7 +1137,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) #if QT_CONFIG(xinput2) case XCB_GE_GENERIC: // Here the windowEventListener is invoked from xi2HandleEvent() - if (m_xi2Enabled && isXIEvent(event, m_xiOpCode)) + if (hasXInput2() && isXIEvent(event, m_xiOpCode)) xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event)); break; #endif @@ -1550,7 +1549,7 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, #if QT_CONFIG(xinput2) // compress XI_* events if (responseType == XCB_GE_GENERIC) { - if (!m_xi2Enabled) + if (!hasXInput2()) return false; // compress XI_Motion, but not from tablet devices diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 8ac05574f3..3f030e0a53 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -358,7 +358,7 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {} virtual void handleXIEnterLeave(xcb_ge_event_t *) {} #endif @@ -425,14 +425,6 @@ public: void *xlib_display() const; void *createVisualInfoForDefaultVisualId() const; #endif - -#if QT_CONFIG(xinput2) - void xi2Select(xcb_window_t window); - void xi2SelectStateEvents(); - bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } - bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; } -#endif - void sync(); void handleXcbError(xcb_generic_error_t *error); @@ -461,6 +453,7 @@ public: bool hasInputShape() const { return has_input_shape; } bool hasXKB() const { return has_xkb; } bool hasXRender() const { return has_render_extension; } + bool hasXInput2() const { return m_xi2Enabled; } bool threadedEventHandling() const { return m_reader->isRunning(); } @@ -492,19 +485,23 @@ public: static bool xEmbedSystemTrayAvailable(); static bool xEmbedSystemTrayVisualHasAlphaChannel(); +#if QT_CONFIG(xinput2) + void xi2SelectStateEvents(); + void xi2SelectDeviceEvents(xcb_window_t window); + void xi2SelectDeviceEventsCompatibility(xcb_window_t window); + bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab); + bool xi2MouseEventsDisabled() const; + bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } + bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; } + Qt::MouseButton xiToQtMouseButton(uint32_t b); #ifdef XCB_USE_XINPUT21 void xi2UpdateScrollingDevices(); -#endif // XCB_USE_XINPUT21 - +#endif #ifdef XCB_USE_XINPUT22 bool startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner); - bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab); - bool xi2MouseEvents() const; bool isTouchScreen(int id); -#endif // XCB_USE_XINPUT22 - - Qt::MouseButton xiToQtMouseButton(uint32_t b); - +#endif +#endif QXcbEventReader *eventReader() const { return m_reader; } bool canGrab() const { return m_canGrabServer; } @@ -542,8 +539,9 @@ private: void destroyScreen(QXcbScreen *screen); void initializeScreens(); bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; -#if QT_CONFIG(xinput2) + bool m_xi2Enabled = false; +#if QT_CONFIG(xinput2) int m_xi2Minor = -1; void initializeXInput2(); void xi2SetupDevice(void *info, bool removeExisting = true); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 8ed6909990..58e99ef3de 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -107,6 +107,41 @@ void QXcbConnection::xi2SelectStateEvents() XISelectEvents(dpy, DefaultRootWindow(dpy), &xiEventMask, 1); } +void QXcbConnection::xi2SelectDeviceEvents(xcb_window_t window) +{ + if (window == rootWindow()) + return; + + unsigned int bitMask = 0; + unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask); + bitMask |= XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; + // There is a check for enter/leave events in plain xcb enter/leave event handler, + // core enter/leave events will be ignored in this case. + bitMask |= XI_EnterMask; + bitMask |= XI_LeaveMask; + bitMask |= XI_PropertyEventMask; +#ifdef XCB_USE_XINPUT22 + if (isAtLeastXI22()) { + bitMask |= XI_TouchBeginMask; + bitMask |= XI_TouchUpdateMask; + bitMask |= XI_TouchEndMask; + } +#endif + + XIEventMask mask; + mask.mask_len = sizeof(bitMask); + mask.mask = xiBitMask; + mask.deviceid = XIAllMasterDevices; + Display *dpy = static_cast<Display *>(m_xlib_display); + Status result = XISelectEvents(dpy, window, &mask, 1); + if (result == Success) + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + else + qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result); +} + void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting) { XIDeviceInfo *deviceInfo = reinterpret_cast<XIDeviceInfo *>(info); @@ -299,96 +334,105 @@ void QXcbConnection::xi2SetupDevices() XIFreeDeviceInfo(devices); } -void QXcbConnection::xi2Select(xcb_window_t window) +/*! \internal + + Notes on QT_XCB_NO_XI2_MOUSE Handling: + + Here we don't select pointer button press/release and motion events on master devices, instead + we select these events directly on slave devices. This means that a master device will fallback + to sending core events for every XI_* event that is sent directly by a slave device. For more + details see "Event processing for attached slave devices" in XInput2 specification. To prevent + handling of the same event twice, we have checks for xi2MouseEventsDisabled() in XI2 event + handlers (but this is somewhat inconsistent in some situations). If the purpose for + QT_XCB_NO_XI2_MOUSE was so that an application using QAbstractNativeEventFilter would see core + mouse events before they are handled by Qt then QT_XCB_NO_XI2_MOUSE won't always work as + expected (e.g. we handle scroll event directly from a slave device event, before an application + has seen the fallback core event from a master device). + + The commit introducing QT_XCB_NO_XI2_MOUSE also states that setting this envvar "restores the + old behavior with broken grabbing". It did not elaborate why grabbing was not fixed for this + code path. The issue that this envvar tries to solve seem to be less important than broken + grabbing (broken apparently only for touch events). Thus, if you really want core mouse events + in your application and do not care about broken touch, then use QT_XCB_NO_XI2 (more on this + below) to disable the extension all together. The reason why grabbing might have not been fixed + is that calling XIGrabDevice with this code path for some reason always returns AlreadyGrabbed + (by debugging X server's code it appears that when we call XIGrabDevice, an X server first grabs + pointer via core pointer and then fails to do XI2 grab with AlreadyGrabbed; disclaimer - I did + not debug this in great detail). When we try supporting odd setups like QT_XCB_NO_XI2_MOUSE, we + are asking for trouble anyways. + + In conclusion, introduction of QT_XCB_NO_XI2_MOUSE causes more issues than solves - the above + mentioned inconsistencies, maintenance of this code path and that QT_XCB_NO_XI2_MOUSE replaces + less important issue with somewhat more important issue. It also makes us to use less optimal + code paths in certain situations (see xi2HandleHierarchyEvent). Using of QT_XCB_NO_XI2 has its + drawbacks too - no tablet and touch events. So the only real fix in this case is at an + application side (teach the application about xcb_ge_event_t events). Based on this, + QT_XCB_NO_XI2_MOUSE will be removed in ### Qt 6. It should not have existed in the first place, + native events seen by QAbstractNativeEventFilter is not really a public API, applications should + expect changes at this level and do ifdefs if something changes between Qt version. +*/ +void QXcbConnection::xi2SelectDeviceEventsCompatibility(xcb_window_t window) { - if (!m_xi2Enabled || window == rootWindow()) + if (window == rootWindow()) return; - Display *xDisplay = static_cast<Display *>(m_xlib_display); - unsigned int bitMask = 0; - unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask); - + unsigned int mask = 0; + unsigned char *bitMask = reinterpret_cast<unsigned char *>(&mask); + mask |= XI_PropertyEventMask; #ifdef XCB_USE_XINPUT22 if (isAtLeastXI22()) { - bitMask |= XI_TouchBeginMask; - bitMask |= XI_TouchUpdateMask; - bitMask |= XI_TouchEndMask; - bitMask |= XI_PropertyEventMask; // for tablets - if (xi2MouseEvents()) { - // We want both mouse and touch through XI2 if touch is supported (>= 2.2). - // The plain xcb press and motion events will not be delivered after this. - bitMask |= XI_ButtonPressMask; - bitMask |= XI_ButtonReleaseMask; - bitMask |= XI_MotionMask; - - // There is a check for enter/leave events in plain xcb enter/leave event handler - bitMask |= XI_EnterMask; - bitMask |= XI_LeaveMask; - - qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); - } - XIEventMask mask; - mask.mask_len = sizeof(bitMask); - mask.mask = xiBitMask; - // When xi2MouseEvents() is true (the default), pointer emulation for touch and tablet - // events will get disabled. This is preferable, as Qt Quick handles touch events - // directly, while for other applications QtGui synthesizes mouse events. - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); - if (result == Success) - QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); - else - qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); + mask |= XI_TouchBeginMask; + mask |= XI_TouchUpdateMask; + mask |= XI_TouchEndMask; } +#endif + XIEventMask xiMask; + xiMask.mask_len = sizeof(mask); + xiMask.mask = bitMask; + xiMask.deviceid = XIAllMasterDevices; + Display *dpy = static_cast<Display *>(m_xlib_display); + Status result = XISelectEvents(dpy, window, &xiMask, 1); + if (result == Success) + QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); + else + qCDebug(lcQpaXInput, "failed to select events, window %x, result %d", window, result); - const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); -#else - const bool pointerSelected = false; -#endif // XCB_USE_XINPUT22 + mask = XI_ButtonPressMask; + mask |= XI_ButtonReleaseMask; + mask |= XI_MotionMask; - QSet<int> tabletDevices; #if QT_CONFIG(tabletevent) + QSet<int> tabletDevices; if (!m_tabletData.isEmpty()) { - unsigned int tabletBitMask; - unsigned char *xiTabletBitMask = reinterpret_cast<unsigned char *>(&tabletBitMask); - QVector<XIEventMask> xiEventMask(m_tabletData.count()); - tabletBitMask = XI_PropertyEventMask; - if (!pointerSelected) - tabletBitMask |= XI_ButtonPressMask | XI_ButtonReleaseMask | XI_MotionMask; - for (int i = 0; i < m_tabletData.count(); ++i) { + const int nrTablets = m_tabletData.count(); + QVector<XIEventMask> xiEventMask(nrTablets); + for (int i = 0; i < nrTablets; ++i) { int deviceId = m_tabletData.at(i).deviceId; tabletDevices.insert(deviceId); xiEventMask[i].deviceid = deviceId; - xiEventMask[i].mask_len = sizeof(tabletBitMask); - xiEventMask[i].mask = xiTabletBitMask; + xiEventMask[i].mask_len = sizeof(mask); + xiEventMask[i].mask = bitMask; } - XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count()); + XISelectEvents(dpy, window, xiEventMask.data(), nrTablets); } -#endif // QT_CONFIG(tabletevent) +#endif #ifdef XCB_USE_XINPUT21 - // Enable each scroll device - if (!m_scrollingDevices.isEmpty() && !pointerSelected) { - // Only when XI2 mouse events are not enabled, otherwise motion and release are selected already. + if (!m_scrollingDevices.isEmpty()) { QVector<XIEventMask> xiEventMask(m_scrollingDevices.size()); - unsigned int scrollBitMask; - unsigned char *xiScrollBitMask = reinterpret_cast<unsigned char *>(&scrollBitMask); - - scrollBitMask = XI_MotionMask; - scrollBitMask |= XI_ButtonReleaseMask; - int i=0; + int i = 0; for (const ScrollingDevice& scrollingDevice : qAsConst(m_scrollingDevices)) { +#if QT_CONFIG(tabletevent) if (tabletDevices.contains(scrollingDevice.deviceId)) continue; // All necessary events are already captured. +#endif xiEventMask[i].deviceid = scrollingDevice.deviceId; - xiEventMask[i].mask_len = sizeof(scrollBitMask); - xiEventMask[i].mask = xiScrollBitMask; + xiEventMask[i].mask_len = sizeof(mask); + xiEventMask[i].mask = bitMask; i++; } - XISelectEvents(xDisplay, window, xiEventMask.data(), i); + XISelectEvents(dpy, window, xiEventMask.data(), i); } -#else - Q_UNUSED(xiBitMask); #endif } @@ -566,7 +610,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: - if (xi2MouseEvents() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) + if (!xi2MouseEventsDisabled() && eventListener && !(xiDeviceEvent->flags & XIPointerEmulated)) eventListener->handleXIMouseEvent(event); break; @@ -582,7 +626,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) xi2ProcessTouch(xiDeviceEvent, platformWindow); break; } - } else if (xiEnterEvent && xi2MouseEvents() && eventListener) { + } else if (xiEnterEvent && !xi2MouseEventsDisabled() && eventListener) { switch (xiEnterEvent->evtype) { case XI_Enter: case XI_Leave: @@ -593,15 +637,15 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) #endif // XCB_USE_XINPUT22 } -#ifdef XCB_USE_XINPUT22 -bool QXcbConnection::xi2MouseEvents() const +bool QXcbConnection::xi2MouseEventsDisabled() const { - static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); + static bool xi2MouseDisabled = qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); // FIXME: Don't use XInput2 mouse events when Xinerama extension // is enabled, because it causes problems with multi-monitor setup. - return mouseViaXI2 && isAtLeastXI22() && !has_xinerama_extension; + return xi2MouseDisabled || has_xinerama_extension; } +#ifdef XCB_USE_XINPUT22 bool QXcbConnection::isTouchScreen(int id) { auto device = touchDeviceForId(id); @@ -794,6 +838,7 @@ bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const Q } return false; } +#endif // XCB_USE_XINPUT22 bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) { @@ -854,7 +899,6 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) return grabbed; } -#endif // XCB_USE_XINPUT22 void QXcbConnection::xi2HandleHierarchyEvent(void *event) { @@ -862,10 +906,17 @@ void QXcbConnection::xi2HandleHierarchyEvent(void *event) // We only care about hotplugged devices if (!(xiEvent->flags & (XISlaveRemoved | XISlaveAdded))) return; + xi2SetupDevices(); - // Reselect events for all event-listening windows. - for (auto it = m_mapper.cbegin(), end = m_mapper.cend(); it != end; ++it) - xi2Select(it.key()); + + if (xi2MouseEventsDisabled()) { + // In compatibility mode (a.k.a xi2MouseEventsDisabled() mode) we select events for + // each device separately. When a new device appears, we have to select events from + // this device on all event-listening windows. This is not needed when events are + // selected via XIAllDevices/XIAllMasterDevices (as in xi2SelectDeviceEvents()). + for (auto it = m_mapper.cbegin(), end = m_mapper.cend(); it != end; ++it) + xi2SelectDeviceEventsCompatibility(it.key()); + } } void QXcbConnection::xi2HandleDeviceChangedEvent(void *event) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 891b53d2dc..e24bd07b6f 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -53,7 +53,7 @@ #include <stdio.h> #include <X11/keysym.h> -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) #include <X11/extensions/XI2proto.h> #undef KeyPress #undef KeyRelease @@ -800,7 +800,7 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) { if (m_config && !connection()->hasXKB()) { diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 74f9da0353..7f1c51fab8 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -74,7 +74,7 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) void updateXKBStateFromXI(void *modInfo, void *groupInfo); #endif #if QT_CONFIG(xkb) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c3d00b53bf..affc2a0dd6 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -576,9 +576,13 @@ void QXcbWindow::create() atom(QXcbAtom::_XEMBED_INFO), 32, 2, (void *)data); - #if QT_CONFIG(xinput2) - connection()->xi2Select(m_window); + if (connection()->hasXInput2()) { + if (connection()->xi2MouseEventsDisabled()) + connection()->xi2SelectDeviceEventsCompatibility(m_window); + else + connection()->xi2SelectDeviceEvents(m_window); + } #endif setWindowState(window()->windowStates()); @@ -2237,9 +2241,10 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) * not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events. */ if (conn) { + const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton); -#ifdef XCB_USE_XINPUT22 - return mouseButtonsPressed || (conn->isAtLeastXI22() && conn->xi2MouseEvents()); +#if QT_CONFIG(xinput2) + return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled()); #else return mouseButtonsPressed; #endif @@ -2342,7 +2347,6 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i handleMouseEvent(timestamp, local, global, modifiers, source); } -// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); @@ -2363,13 +2367,12 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time); } -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) static inline int fixed1616ToInt(FP1616 val) { return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); } -// 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(); @@ -2431,7 +2434,6 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource } } -// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) { xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event); @@ -2591,8 +2593,9 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) { if (!grab && connection()->mouseGrabber() == this) connection()->setMouseGrabber(Q_NULLPTR); -#ifdef XCB_USE_XINPUT22 - if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) { + +#if QT_CONFIG(xinput2) + if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) { bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab); if (grab && result) connection()->setMouseGrabber(this); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index b5bf33520f..1ce9b0a42f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -138,7 +138,7 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) override; void handleFocusOutEvent(const xcb_focus_out_event_t *event) override; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override; -#ifdef XCB_USE_XINPUT22 +#if QT_CONFIG(xinput2) void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override; void handleXIEnterLeave(xcb_ge_event_t *) override; #endif |