xcb: fix logic in QXcbConnection::initializeXInput2()

Things that were broken:

- The return values of XIQueryVersion interpreted wrongly. BadRequest
  means no XI2 support on the server. Nesting more XIQueryVersion
  calls to check for lower minor version of XI2 in this case does not
  make sense. On Success, server's supported X Input version is returned.
  Server's supported version can be lower than the version we have announced
  to support. In this case Qt client will be limited by X server's supported
  version (which is ok, as we do check the available version at runtime via
  QXcbConnection::isAtLeastXI2*).

- The code was _always_ announcing to X server that we support XI 2.2,
  by ignoring what actually is supported in the specific build (see
  XCB_USE_XINPUT ifdefs).

- qCDebug messages and logging categories were wrong too.

Change-Id: Ia84457f125474aa851b7a91ed19fc5b904ac359e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
Gatis Paeglis 2017-06-06 11:33:39 +02:00
parent f69d30804d
commit ac4e848c98
3 changed files with 32 additions and 23 deletions

View File

@ -553,7 +553,7 @@ private:
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
#if QT_CONFIG(xinput2)
bool m_xi2Enabled = false;
int m_xi2Minor = 2;
int m_xi2Minor = -1;
void initializeXInput2();
void xi2SetupDevices();
struct TouchDeviceData {

View File

@ -57,29 +57,39 @@ void QXcbConnection::initializeXInput2()
const_cast<QLoggingCategory&>(lcQpaXInput()).setEnabled(QtDebugMsg, true);
if (qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT_DEVICES"))
const_cast<QLoggingCategory&>(lcQpaXInputDevices()).setEnabled(QtDebugMsg, true);
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
// try 2.2 first, needed for TouchBegin/Update/End
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
m_xi2Minor = 0; // for tablet support 2.0 is enough
m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
} else
m_xi2Enabled = true;
} else
m_xi2Enabled = true;
if (m_xi2Enabled) {
#ifdef XCB_USE_XINPUT22
qCDebug(lcQpaXInputDevices, "XInput version %d.%d is available and Qt supports 2.2 or greater", xiMajor, m_xi2Minor);
m_startSystemResizeInfo.window = XCB_NONE;
#if defined(XCB_USE_XINPUT22)
m_xi2Minor = 2; // for touch support 2.2 is enough
#elif defined(XCB_USE_XINPUT21)
m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
#else
qCDebug(lcQpaXInputDevices, "XInput version %d.%d is available and Qt supports 2.0", xiMajor, m_xi2Minor);
m_xi2Minor = 0; // for tablet support 2.0 is enough
#endif
}
qCDebug(lcQpaXInput, "Plugin build with support for XInput 2 version up "
"to %d.%d", xiMajor, m_xi2Minor);
xi2SetupDevices();
switch (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor)) {
case Success:
// Server's supported version can be lower than the version we have
// announced to support. In this case Qt client will be limited by
// X server's supported version.
qCDebug(lcQpaXInput, "Using XInput version %d.%d", xiMajor, m_xi2Minor);
m_xi2Enabled = true;
#ifdef XCB_USE_XINPUT22
m_startSystemResizeInfo.window = XCB_NONE;
#endif
xi2SetupDevices();
break;
case BadRequest: // Must be an X server with XInput 1
qCDebug(lcQpaXInput, "X server does not support XInput 2");
break;
default: // BadValue
qCDebug(lcQpaXInput, "Internal error");
break;
}
}
}
@ -91,9 +101,6 @@ void QXcbConnection::xi2SetupDevices()
m_scrollingDevices.clear();
m_touchDevices.clear();
if (!m_xi2Enabled)
return;
Display *xDisplay = static_cast<Display *>(m_xlib_display);
int deviceCount = 0;
XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);

View File

@ -2451,12 +2451,14 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
case XI_Enter: {
const int event_x = fixed1616ToInt(ev->event_x);
const int event_y = fixed1616ToInt(ev->event_y);
qCDebug(lcQpaXInput, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d", event_x, event_y, ev->mode, ev->detail, ev->time);
qCDebug(lcQpaXInputEvents, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d",
event_x, event_y, ev->mode, ev->detail, ev->time);
handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
break;
}
case XI_Leave:
qCDebug(lcQpaXInput, "XI2 mouse leave, mode %d, detail %d, time %d", ev->mode, ev->detail, ev->time);
qCDebug(lcQpaXInputEvents, "XI2 mouse leave, mode %d, detail %d, time %d",
ev->mode, ev->detail, ev->time);
connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time);
break;