Use XI2 event detail to determine changed mouse button

The button state part of the XI2 events appears to be badly constructed
on some devices and platforms. Even where supported the 'detail' field
of the XI2 events is what we should be reading since it indicates the
button the event refers to and not just the state of all buttons.

Task-number: QTBUG-38169
Change-Id: Iedb7971194b3c27448b72c285a54100c511c17e4
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
Allan Sandfeld Jensen 2014-04-29 12:32:34 +02:00 committed by The Qt Project
parent 3f885939c0
commit b80f732783
3 changed files with 6 additions and 20 deletions

View File

@ -1791,19 +1791,6 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
return true;
}
bool QXcbConnection::xi2GetButtonState(void *event, int buttonNum)
{
xXIDeviceEvent *xideviceevent = static_cast<xXIDeviceEvent *>(event);
unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
for (int i = 0; i < (xideviceevent->buttons_len * 4); i++) {
if (buttonNum < 8)
return (buttonsMaskAddr[i] & (1 << buttonNum));
buttonNum -= 8;
}
return false;
}
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
// - "pad0" became "extension"
// - "pad1" and "pad" became "pad0"

View File

@ -532,7 +532,6 @@ private:
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
static bool xi2GetButtonState(void *event, int buttonNum);
#endif
xcb_connection_t *m_connection;

View File

@ -575,7 +575,7 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
#ifdef XCB_USE_XINPUT21
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
if (xiEvent->evtype == XI_Motion) {
if (xiEvent->evtype == XI_Motion && scrollingDevice.orientations) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint rawDelta;
@ -612,20 +612,20 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
}
}
} else if (xiEvent->evtype == XI_ButtonRelease) {
} else if (xiEvent->evtype == XI_ButtonRelease && scrollingDevice.legacyOrientations) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint angleDelta;
if (scrollingDevice.legacyOrientations & Qt::Vertical) {
if (xi2GetButtonState(xiDeviceEvent, 4))
if (xiDeviceEvent->detail == 4)
angleDelta.setY(120);
else if (xi2GetButtonState(xiDeviceEvent, 5))
else if (xiDeviceEvent->detail == 5)
angleDelta.setY(-120);
}
if (scrollingDevice.legacyOrientations & Qt::Horizontal) {
if (xi2GetButtonState(xiDeviceEvent, 6))
if (xiDeviceEvent->detail == 6)
angleDelta.setX(120);
if (xi2GetButtonState(xiDeviceEvent, 7))
else if (xiDeviceEvent->detail == 7)
angleDelta.setX(-120);
}
if (!angleDelta.isNull()) {