summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@qt.io>2017-07-19 09:09:16 +0200
committerGatis Paeglis <gatis.paeglis@qt.io>2017-07-19 12:48:55 +0000
commite71f7d7736ec2c845206daa5a48921affbcf8e44 (patch)
tree51300694891992e1e3b41e713796179f838ad649 /src
parent4585889467b6124f2e9ccca3d1c0da15e2bf790c (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp28
2 files changed, 18 insertions, 11 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index bba987983e..1129090eca 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -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; }
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 4d2a83b3cf..38ea2d9ab9 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -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)