summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindow.cpp
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@qt.io>2017-06-01 16:26:06 +0200
committerGatis Paeglis <gatis.paeglis@qt.io>2017-08-09 16:55:25 +0000
commit9184384bc9d9d71a146fff535021357258a0295e (patch)
treefaecbc4ad9c1d48221815979323fbe4a3c774534 /src/plugins/platforms/xcb/qxcbwindow.cpp
parent0ad79dd0f00013831ea06ea4b0d7875db285b85c (diff)
xcb: use XInput2 for mouse starting from 2.0 not 2.2
53d289ec4c0f512a3475da4bbf1f940cd6838ac fixed the issue of not getting touch events when grabbing via the plain xcb functions. And due to wanting to support a setup where mouse events are delivered via core events it was chosen to use mouse via XI2 only when really necessary. Thus starting only from 2.2, the version from which the mouse+touch grabbing becomes the issue (XI2 introduced touch support from 2.2). The same patch states that using QT_XCB_NO_XI2_MOUSE restores to the old behavior (grabbing via core) with broken touch grabbing. Broken only with 2.2+, not 2.0 and 2.1 since those versions of protocol do not know about touch. All of this implies the following: 1) The user code that already depends on QT_XCB_NO_XI2_MOUSE, won't see any behavioural difference if we will use XInput starting from 2.0 for mouse. Mouse grabbing will continue to be done via core (xcb_grab_pointer) as mentioned above and thus touch grabbing will continue to be broken with 2.2+. 2) The code that has never cared how we get the native events (core vs xinput2), won't see any behavioural difference. In this case grabbing will always be done via XI2 (XIGrabDevice) grab when XI2.0+ is available. Since there is no difference in the outcome, we migth as well use XI2 for mouse from 2.0, not 2.2. Extension events are always better choice than core. Besides the broken touch grabbing issue with QT_XCB_NO_XI2_MOUSE, there are other issues with that code path, for details see internal documentation of xi2SelectDeviceEventsCompatibility(), where the conclusion is: *** If your code relies on QT_XCB_NO_XI2_MOUSE, then your code needs fixing. *** This patch also cleans up how we select XInput2 events, by separating the QT_XCB_NO_XI2_MOUSE code path. This has two benefits - improved code readability and will make the deprecation of QT_XCB_NO_XI2_MOUSE easier. The patch removes some sparse comments as the behavior is now documented in one place, see xi2SelectDeviceEventsCompatibility(). [ChangeLog][Platform Specific Changes][Linux] The QT_XCB_NO_XI2_MOUSE environment variable is deprecated and will be removed in Qt 6. If your application relies on behavior set by QT_XCB_NO_XI2_MOUSE, it should be updated accordingly. [ChangeLog][Platform Specific Changes][Linux] Pointer event delivery on X11 is now done starting from XInput version 2.0 (when available) instead of 2.2. XInput support can be disabled by setting QT_XCB_NO_XI2=1 environment variable. Note that using QT_XCB_NO_XI2 would also disable tablet and touch support. Change-Id: I661b36d6710b9f6ec71fecc8287ba479432bff4c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp23
1 files changed, 13 insertions, 10 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index c3d00b53bf..affc2a0dd6 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -576,9 +576,13 @@ void QXcbWindow::create()
atom(QXcbAtom::_XEMBED_INFO),
32, 2, (void *)data);
-
#if QT_CONFIG(xinput2)
- connection()->xi2Select(m_window);
+ if (connection()->hasXInput2()) {
+ if (connection()->xi2MouseEventsDisabled())
+ connection()->xi2SelectDeviceEventsCompatibility(m_window);
+ else
+ connection()->xi2SelectDeviceEvents(m_window);
+ }
#endif
setWindowState(window()->windowStates());
@@ -2237,9 +2241,10 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
* not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events.
*/
if (conn) {
+
const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
-#ifdef XCB_USE_XINPUT22
- return mouseButtonsPressed || (conn->isAtLeastXI22() && conn->xi2MouseEvents());
+#if QT_CONFIG(xinput2)
+ return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled());
#else
return mouseButtonsPressed;
#endif
@@ -2342,7 +2347,6 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i
handleMouseEvent(timestamp, local, global, modifiers, source);
}
-// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available.
void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
{
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
@@ -2363,13 +2367,12 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time);
}
-#ifdef XCB_USE_XINPUT22
+#if QT_CONFIG(xinput2)
static inline int fixed1616ToInt(FP1616 val)
{
return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF);
}
-// With XI 2.2+ press/release/motion comes here instead of the above handlers.
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
{
QXcbConnection *conn = connection();
@@ -2431,7 +2434,6 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
}
}
-// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events
void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
{
xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event);
@@ -2591,8 +2593,9 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
{
if (!grab && connection()->mouseGrabber() == this)
connection()->setMouseGrabber(Q_NULLPTR);
-#ifdef XCB_USE_XINPUT22
- if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) {
+
+#if QT_CONFIG(xinput2)
+ if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
if (grab && result)
connection()->setMouseGrabber(this);