Scrolling devices should not override touch or tablet devices
XISelectEvents override any earlier set event mask for the same device ids. This may cause touch devices to stop reporting touch events if they export scroll buttons or axis. The patch checks for each scrolling device if they are also a touch devices and includes the necessary bitmask if they are, and skips any devices also recognized as tablet devices as they already capture all relevant events. In addition tablet event handling will no longer block handling of wheel button events for scroll devices with the same device id. Task-number: QTBUG-38935 Change-Id: Ifd4657beb0a0cebffe89d3470ef2bd605eb3552e Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
parent
7cc175c9d6
commit
a8877f529d
@ -248,6 +248,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
}
|
||||
#endif // XCB_USE_XINPUT22
|
||||
|
||||
QSet<int> tabletDevices;
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
// For each tablet, select some additional event types.
|
||||
// Press, motion, etc. events must never be selected for _all_ devices
|
||||
@ -255,15 +256,19 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
// similar handlers useless and we have no intention to infect
|
||||
// all the pure xcb code with Xlib-based XI2.
|
||||
if (!m_tabletData.isEmpty()) {
|
||||
unsigned int tabletBitMask = bitMask;
|
||||
unsigned char *xiTabletBitMask = reinterpret_cast<unsigned char *>(&tabletBitMask);
|
||||
QVector<XIEventMask> xiEventMask(m_tabletData.count());
|
||||
bitMask |= XI_ButtonPressMask;
|
||||
bitMask |= XI_ButtonReleaseMask;
|
||||
bitMask |= XI_MotionMask;
|
||||
bitMask |= XI_PropertyEventMask;
|
||||
tabletBitMask |= XI_ButtonPressMask;
|
||||
tabletBitMask |= XI_ButtonReleaseMask;
|
||||
tabletBitMask |= XI_MotionMask;
|
||||
tabletBitMask |= XI_PropertyEventMask;
|
||||
for (int i = 0; i < m_tabletData.count(); ++i) {
|
||||
xiEventMask[i].deviceid = m_tabletData.at(i).deviceId;
|
||||
xiEventMask[i].mask_len = sizeof(bitMask);
|
||||
xiEventMask[i].mask = xiBitMask;
|
||||
int deviceId = m_tabletData.at(i).deviceId;
|
||||
tabletDevices.insert(deviceId);
|
||||
xiEventMask[i].deviceid = deviceId;
|
||||
xiEventMask[i].mask_len = sizeof(tabletBitMask);
|
||||
xiEventMask[i].mask = xiTabletBitMask;
|
||||
}
|
||||
XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count());
|
||||
}
|
||||
@ -273,17 +278,30 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
// Enable each scroll device
|
||||
if (!m_scrollingDevices.isEmpty()) {
|
||||
QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
|
||||
bitMask = XI_MotionMask;
|
||||
unsigned int scrollBitMask = 0;
|
||||
unsigned char *xiScrollBitMask = reinterpret_cast<unsigned char *>(&scrollBitMask);
|
||||
scrollBitMask = XI_MotionMask;
|
||||
scrollBitMask |= XI_ButtonReleaseMask;
|
||||
bitMask |= XI_MotionMask;
|
||||
bitMask |= XI_ButtonReleaseMask;
|
||||
int i=0;
|
||||
Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
|
||||
if (tabletDevices.contains(scrollingDevice.deviceId))
|
||||
continue; // All necessary events are already captured.
|
||||
xiEventMask[i].deviceid = scrollingDevice.deviceId;
|
||||
xiEventMask[i].mask_len = sizeof(bitMask);
|
||||
xiEventMask[i].mask = xiBitMask;
|
||||
if (m_touchDevices.contains(scrollingDevice.deviceId)) {
|
||||
xiEventMask[i].mask_len = sizeof(bitMask);
|
||||
xiEventMask[i].mask = xiBitMask;
|
||||
} else {
|
||||
xiEventMask[i].mask_len = sizeof(scrollBitMask);
|
||||
xiEventMask[i].mask = xiScrollBitMask;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size());
|
||||
XISelectEvents(xDisplay, window, xiEventMask.data(), i);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(xiBitMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -657,13 +675,15 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
|
||||
if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) { // ignore the physical buttons on the stylus
|
||||
tabletData->down = true;
|
||||
xi2ReportTabletEvent(*tabletData, xiEvent);
|
||||
}
|
||||
} else
|
||||
handled = false;
|
||||
break;
|
||||
case XI_ButtonRelease: // stylus up
|
||||
if (reinterpret_cast<xXIDeviceEvent *>(event)->detail == 1) {
|
||||
tabletData->down = false;
|
||||
xi2ReportTabletEvent(*tabletData, xiEvent);
|
||||
}
|
||||
} else
|
||||
handled = false;
|
||||
break;
|
||||
case XI_Motion:
|
||||
// Report TabletMove only when the stylus is touching the tablet.
|
||||
|
Loading…
Reference in New Issue
Block a user