xcb: fix freeze when (un)plugging input devices
.. in an application that has many native windows. We don't need to select XI_HierarchyChangedMask and XI_DeviceChangedMask for every window. It is enough to register one window for these events to update state of our X11 client (application). Furthermore, XIAllDevices and XIAllMasterDevices always apply, even if the device has been added after the client has selected for events. So there is no need to call XISelectEvents on XIAllDevices/XIAllMasterDevices again, if we are not updating event masks. With this patch and the test application from QTBUG-57013, removing/attaching a device takes few hundred milliseconds instead of 23-24 seconds. Task-number: QTBUG-57013 Change-Id: Ieb0b5ee25feef2922f901165825cb4a1289fc852 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
4585889467
commit
e71f7d7736
@ -428,6 +428,7 @@ public:
|
||||
|
||||
#if QT_CONFIG(xinput2)
|
||||
void xi2Select(xcb_window_t window);
|
||||
void xi2SelectStateEvents();
|
||||
#endif
|
||||
#ifdef XCB_USE_XINPUT21
|
||||
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
|
||||
|
@ -90,12 +90,29 @@ void QXcbConnection::initializeXInput2()
|
||||
#else
|
||||
qCDebug(lcQpaXInputDevices, "XInput version %d.%d is available and Qt supports 2.0", xiMajor, m_xi2Minor);
|
||||
#endif
|
||||
xi2SelectStateEvents();
|
||||
}
|
||||
|
||||
xi2SetupDevices();
|
||||
}
|
||||
}
|
||||
|
||||
void QXcbConnection::xi2SelectStateEvents()
|
||||
{
|
||||
// These state events do not depend on a specific X window, but are global
|
||||
// for the X client's (application's) state.
|
||||
unsigned int bitMask = 0;
|
||||
unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask);
|
||||
XIEventMask xiEventMask;
|
||||
bitMask = XI_HierarchyChangedMask;
|
||||
bitMask |= XI_DeviceChangedMask;
|
||||
xiEventMask.deviceid = XIAllDevices;
|
||||
xiEventMask.mask_len = sizeof(bitMask);
|
||||
xiEventMask.mask = xiBitMask;
|
||||
Display *dpy = static_cast<Display *>(m_xlib_display);
|
||||
XISelectEvents(dpy, DefaultRootWindow(dpy), &xiEventMask, 1);
|
||||
}
|
||||
|
||||
void QXcbConnection::xi2SetupDevices()
|
||||
{
|
||||
#if QT_CONFIG(tabletevent)
|
||||
@ -371,17 +388,6 @@ void QXcbConnection::xi2Select(xcb_window_t window)
|
||||
#else
|
||||
Q_UNUSED(xiBitMask);
|
||||
#endif
|
||||
|
||||
{
|
||||
// Listen for hotplug events
|
||||
XIEventMask xiEventMask;
|
||||
bitMask = XI_HierarchyChangedMask;
|
||||
bitMask |= XI_DeviceChangedMask;
|
||||
xiEventMask.deviceid = XIAllDevices;
|
||||
xiEventMask.mask_len = sizeof(bitMask);
|
||||
xiEventMask.mask = xiBitMask;
|
||||
XISelectEvents(xDisplay, window, &xiEventMask, 1);
|
||||
}
|
||||
}
|
||||
|
||||
XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
|
||||
|
Loading…
Reference in New Issue
Block a user