summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-03-27 11:51:02 +0100
committerMichal Klocek <michal.klocek@theqtcompany.com>2015-06-01 06:34:22 +0000
commit53d289ec4c0f512a3475da4bbf1f940cd6838ace (patch)
tree8eebcb92e851a58aa36f994757c235419c964454 /src/plugins/platforms/xcb/qxcbconnection.cpp
parent2d7004c58752eda813496fcf8a7d2582e956ba5e (diff)
xcb: Use XIGrabDevice instead of xcb_grab_pointer with XI 2.2
Switch to using the pointer events from XI2 when touch is available (i.e. version is >= 2.2). This allows us to select and grab the button and motion events together with the touch ones. This prevents the issue of not getting touch events when grabbing via the plain xcb functions. To prevent touch sequences from being replayed after ungrabbing (for example after dismissing a popup that caused a grab), we try to accept touches via XIAllowTouchEvents. Unfortunately this leads to a deadlock and therefore we can only do it when we know we have a new enough libXi. This is a configure time check which is not ideal since the system on which apps run can have a newer libXi than the machine that did the Qt build, but seems like the best we can do. The environment variable QT_XCB_NO_XI2_MOUSE can be set to 1 in order to prevent processing mouse events through XInput. This restores the old behavior with broken grabbing. [ChangeLog][QtGui] Pointer event delivery on X11 is now done via XInput 2.2+ when available. Done-with: Michal Klocek <michal.klocek@theqtcompany.com> Done-with: Alexander Volkov <a.volkov@rusbitech.ru> Task-number: QTBUG-43525 Task-number: QTBUG-45054 Task-number: QTBUG-30417 Change-Id: I7cb2002b31bef4cd527aa427549dcf2d5467968e Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp79
1 files changed, 35 insertions, 44 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 92d064df9b..80c844e658 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -70,7 +70,6 @@
#endif
#if defined(XCB_USE_XINPUT2)
-#include <X11/extensions/XInput2.h>
#include <X11/extensions/XI2proto.h>
#endif
@@ -457,6 +456,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
, m_focusWindow(0)
, m_systemTrayTracker(0)
, m_glIntegration(Q_NULLPTR)
+ , m_xiGrab(false)
{
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
@@ -909,7 +909,7 @@ static Qt::MouseButtons translateMouseButtons(int s)
return ret;
}
-static Qt::MouseButton translateMouseButton(xcb_button_t s)
+Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s)
{
switch (s) {
case 1: return Qt::LeftButton;
@@ -944,39 +944,6 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s)
}
}
-void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev)
-{
- xcb_button_press_event_t *event = (xcb_button_press_event_t *)ev;
-
- // the event explicitly contains the state of the three first buttons,
- // the rest we need to manage ourselves
- m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
- m_buttons |= translateMouseButton(event->detail);
- qCDebug(lcQpaXInput, "xcb: pressed mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
-}
-
-void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
-{
- xcb_button_release_event_t *event = (xcb_button_release_event_t *)ev;
-
- // the event explicitly contains the state of the three first buttons,
- // the rest we need to manage ourselves
- m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
- m_buttons &= ~translateMouseButton(event->detail);
- qCDebug(lcQpaXInput, "xcb: released mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
-}
-
-void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev)
-{
- xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev;
-
- m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
-#ifdef Q_XCB_DEBUG
- qCDebug(lcQpaXInput, "xcb: moved mouse to %4d, %4d; button state %X",
- event->event_x, event->event_y, static_cast<unsigned int>(m_buttons));
-#endif
-}
-
#ifndef QT_NO_XKB
namespace {
typedef union {
@@ -1018,18 +985,35 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
switch (response_type) {
case XCB_EXPOSE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
- case XCB_BUTTON_PRESS:
- m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state);
- handleButtonPress(event);
+
+ // press/release/motion is only delivered here when XI 2.2+ is _not_ in use
+ case XCB_BUTTON_PRESS: {
+ xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event;
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ // the event explicitly contains the state of the three first buttons,
+ // the rest we need to manage ourselves
+ m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state);
+ m_buttons |= translateMouseButton(ev->detail);
+ qCDebug(lcQpaXInput, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons));
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
- case XCB_BUTTON_RELEASE:
- m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state);
- handleButtonRelease(event);
+ }
+ case XCB_BUTTON_RELEASE: {
+ xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event;
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state);
+ m_buttons &= ~translateMouseButton(ev->detail);
+ qCDebug(lcQpaXInput, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons));
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
- case XCB_MOTION_NOTIFY:
- m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
- handleMotionNotify(event);
+ }
+ case XCB_MOTION_NOTIFY: {
+ xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event;
+ m_keyboard->updateXKBStateFromCore(ev->state);
+ m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state);
+ qCDebug(lcQpaXInput, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y,
+ ev->detail, static_cast<unsigned int>(m_buttons));
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
+ }
+
case XCB_CONFIGURE_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
case XCB_MAP_NOTIFY:
@@ -1090,6 +1074,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
#if defined(XCB_USE_XINPUT2)
case XCB_GE_GENERIC:
+ // Here the windowEventListener is invoked from xi2HandleEvent()
if (m_xi2Enabled)
xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
break;
@@ -1931,6 +1916,12 @@ void QXcbConnection::initializeXKB()
#endif
}
+bool QXcbConnection::xi2MouseEvents() const
+{
+ static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE");
+ return mouseViaXI2;
+}
+
#if defined(XCB_USE_XINPUT2)
static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number)
{