https://bugreports.qt.io/browse/QTBUG-129509 https://bugreports.qt.io/browse/QTBUG-129514 https://codereview.qt-project.org/c/qt/qtbase/+/594889 From 42845904d51ad14b2ab41a165bd9b9b1a9459840 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 01 Oct 2024 12:46:30 +0200 Subject: [PATCH] Revert "xcb: handle XI2 input button and motion events from slave devices" This reverts commit b71be292780b858f2c55ce92601452e2ea946de2, which causes a regression when using mouse wheel and moving cursor together on scroll bar for some qt applications, like qutebrowser and qbittorrent. Fixes: QTBUG-129509 Fixes: QTBUG-129514 Task-number: QTBUG-110841 Pick-to: 6.8.0 6.8 6.7 6.5 6.2 5.15 Change-Id: I703158874413a1306ea99217bced4ba38382f543 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -683,94 +683,21 @@ } -//implementation is ported from https://codereview.qt-project.org/c/qt/qtbase/+/231552/12/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp#558 -namespace { - -/*! \internal - - Qt listens for XIAllDevices to avoid losing mouse events. This function - ensures that we don't process the same event twice: from a slave device and - then again from a master device. - - In a normal use case (e.g. mouse press and release inside a window), we will - drop events from master devices as duplicates. Other advantage of processing - events from slave devices is that they don't share button state. All buttons - on a master device share the state. - - Examples of special cases: - -\list - -\li During system move/resize, window manager (_NET_WM_MOVERESIZE) grabs the - master pointer, in this case we process the matching release from the slave - device. A master device event is not sent by the server, hence no duplicate - event to drop. If we listened for XIAllMasterDevices instead, we would never - see a release event in this case. - -\li If we dismiss a context menu by clicking somewhere outside a Qt application, - we will process the mouse press from the master pointer as that is the - device we are grabbing. We are not grabbing slave devices (grabbing on the - slave device is buggy according to 19d289ab1b5bde3e136765e5432b5c7d004df3a4). - And since the event occurs outside our window, the slave device event is - not sent to us by the server, hence no duplicate event to drop. - -\endlist -*/ -bool isDuplicateEvent(xcb_ge_event_t *event) -{ - Q_ASSERT(event); - - struct qXIEvent { - bool isValid = false; - uint16_t sourceid; - uint8_t evtype; - uint32_t detail; - int32_t root_x; - int32_t root_y; - }; - static qXIEvent lastSeenEvent; - - bool isDuplicate = false; - auto *xiDeviceEvent = reinterpret_cast(event); - if (lastSeenEvent.isValid) { - isDuplicate = lastSeenEvent.sourceid == xiDeviceEvent->sourceid && - lastSeenEvent.evtype == xiDeviceEvent->event_type && - lastSeenEvent.detail == xiDeviceEvent->detail && - lastSeenEvent.root_x == xiDeviceEvent->root_x && - lastSeenEvent.root_y == xiDeviceEvent->root_y; - } else { - lastSeenEvent.isValid = true; - } - lastSeenEvent.sourceid = xiDeviceEvent->sourceid; - lastSeenEvent.evtype = xiDeviceEvent->event_type; - lastSeenEvent.detail = xiDeviceEvent->detail; - lastSeenEvent.root_x = xiDeviceEvent->root_x; - lastSeenEvent.root_y = xiDeviceEvent->root_y; - - if (isDuplicate) { - qCDebug(lcQpaXInputEvents, "Duplicate XI2 event %d", event->event_type); - // This sanity check ensures that special cases like QTBUG-59277 keep working. - lastSeenEvent.isValid = false; // An event can be a duplicate only once. - } - - return isDuplicate; -} - -} // namespace - void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { auto *xiEvent = reinterpret_cast(event); - if (m_xiSlavePointerIds.contains(xiEvent->deviceid)) { - if (!(xiEvent->event_type == XCB_INPUT_BUTTON_PRESS - || xiEvent->event_type == XCB_INPUT_BUTTON_RELEASE - || xiEvent->event_type == XCB_INPUT_MOTION)) { - if (!m_duringSystemMoveResize) - return; - if (xiEvent->event == XCB_NONE) - return; - - if (xiEvent->event_type == XCB_INPUT_TOUCH_END) - abortSystemMoveResize(xiEvent->event); + setTime(xiEvent->time); + if (m_xiSlavePointerIds.contains(xiEvent->deviceid) && xiEvent->event_type != XCB_INPUT_PROPERTY) { + if (!m_duringSystemMoveResize) + return; + if (xiEvent->event == XCB_NONE) + return; + if (xiEvent->event_type == XCB_INPUT_BUTTON_RELEASE + && xiEvent->detail == XCB_BUTTON_INDEX_1 ) { + abortSystemMoveResize(xiEvent->event); + } else if (xiEvent->event_type == XCB_INPUT_TOUCH_END) { + abortSystemMoveResize(xiEvent->event); + return; + } else { return; } @@ -784,25 +711,9 @@ case XCB_INPUT_BUTTON_PRESS: case XCB_INPUT_BUTTON_RELEASE: - case XCB_INPUT_MOTION: { - if (isDuplicateEvent(event)) - return; - if (m_xiSlavePointerIds.contains(xiEvent->deviceid)) { - if (m_duringSystemMoveResize) { - if (xiEvent->event_type == XCB_INPUT_BUTTON_RELEASE - && xiEvent->detail == XCB_BUTTON_INDEX_1 ) { - abortSystemMoveResize(xiEvent->event); - } else { - return; - } - } - } - xiDeviceEvent = xiEvent; - eventListener = windowEventListenerFromId(xiDeviceEvent->event); - sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master - break; - } + case XCB_INPUT_MOTION: case XCB_INPUT_TOUCH_BEGIN: case XCB_INPUT_TOUCH_UPDATE: - case XCB_INPUT_TOUCH_END: { + case XCB_INPUT_TOUCH_END: + { xiDeviceEvent = xiEvent; eventListener = windowEventListenerFromId(xiDeviceEvent->event);