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.7 6.5 6.2 5.15 Change-Id: I703158874413a1306ea99217bced4ba38382f543 Reviewed-by: Liang Qi <liang.qi@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit 5875da6d70303468eab85030a80f54c268f80b79) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
18a24eabbe
commit
d3780f2444
@ -682,96 +682,23 @@ static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
|
||||
return qreal(val) / 0x10000;
|
||||
}
|
||||
|
||||
//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<qt_xcb_input_device_event_t *>(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<qt_xcb_input_device_event_t *>(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;
|
||||
}
|
||||
}
|
||||
@ -783,27 +710,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
switch (xiEvent->event_type) {
|
||||
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);
|
||||
sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master
|
||||
|
Loading…
x
Reference in New Issue
Block a user