xcb: use QXcbScrollingDevice for a touchpad
When using XQuartz on macOS, the virtual pointer device is detected as a touchpad, not a mouse; but QXcbConnection::xi2HandleScrollEvent() expects the device to be an instance of QXcbScrollingDevice for storage of some state. A touchpad that has the scrolling capability must be that type, not a plain QPointingDevice. Fixes: QTBUG-91402 Change-Id: I1b82766d4a3f87f656e56c0d8904def26fb0979a Reviewed-by: Liang Qi <liang.qi@qt.io> (cherry picked from commit f85e70c569f4aa979004889d20de8acec9a790bf) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
434c2a6be6
commit
84f0b4df0e
@ -79,6 +79,7 @@ class QXcbWindow;
|
|||||||
class QXcbDrag;
|
class QXcbDrag;
|
||||||
class QXcbKeyboard;
|
class QXcbKeyboard;
|
||||||
class QXcbScrollingDevice;
|
class QXcbScrollingDevice;
|
||||||
|
class QXcbScrollingDevicePrivate;
|
||||||
class QXcbClipboard;
|
class QXcbClipboard;
|
||||||
class QXcbWMSupport;
|
class QXcbWMSupport;
|
||||||
class QXcbNativeInterface;
|
class QXcbNativeInterface;
|
||||||
@ -284,7 +285,7 @@ private:
|
|||||||
QSizeF size; // device size in mm
|
QSizeF size; // device size in mm
|
||||||
bool providesTouchOrientation = false;
|
bool providesTouchOrientation = false;
|
||||||
};
|
};
|
||||||
TouchDeviceData *populateTouchDevices(void *info);
|
TouchDeviceData *populateTouchDevices(void *info, QXcbScrollingDevicePrivate *scrollingDeviceP);
|
||||||
TouchDeviceData *touchDeviceForId(int id);
|
TouchDeviceData *touchDeviceForId(int id);
|
||||||
void xi2HandleEvent(xcb_ge_event_t *event);
|
void xi2HandleEvent(xcb_ge_event_t *event);
|
||||||
void xi2HandleHierarchyEvent(void *event);
|
void xi2HandleHierarchyEvent(void *event);
|
||||||
|
@ -290,12 +290,12 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
|
|||||||
auto *sci = reinterpret_cast<xcb_input_scroll_class_t *>(classinfo);
|
auto *sci = reinterpret_cast<xcb_input_scroll_class_t *>(classinfo);
|
||||||
if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_VERTICAL) {
|
if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_VERTICAL) {
|
||||||
auto dev = scrollingDevice();
|
auto dev = scrollingDevice();
|
||||||
dev->orientations |= Qt::Vertical;
|
dev->orientations.setFlag(Qt::Vertical);
|
||||||
dev->verticalIndex = sci->number;
|
dev->verticalIndex = sci->number;
|
||||||
dev->verticalIncrement = fixed3232ToReal(sci->increment);
|
dev->verticalIncrement = fixed3232ToReal(sci->increment);
|
||||||
} else if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_HORIZONTAL) {
|
} else if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_HORIZONTAL) {
|
||||||
auto dev = scrollingDevice();
|
auto dev = scrollingDevice();
|
||||||
dev->orientations |= Qt::Horizontal;
|
dev->orientations.setFlag(Qt::Horizontal);
|
||||||
dev->horizontalIndex = sci->number;
|
dev->horizontalIndex = sci->number;
|
||||||
dev->horizontalIncrement = fixed3232ToReal(sci->increment);
|
dev->horizontalIncrement = fixed3232ToReal(sci->increment);
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isTablet) {
|
if (!isTablet) {
|
||||||
TouchDeviceData *dev = populateTouchDevices(deviceInfo);
|
TouchDeviceData *dev = populateTouchDevices(deviceInfo, scrollingDeviceP);
|
||||||
if (dev && lcQpaXInputDevices().isDebugEnabled()) {
|
if (dev && lcQpaXInputDevices().isDebugEnabled()) {
|
||||||
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen)
|
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen)
|
||||||
qCDebug(lcQpaXInputDevices, " it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
qCDebug(lcQpaXInputDevices, " it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
||||||
@ -520,7 +520,7 @@ QXcbConnection::TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
|
|||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info)
|
QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info, QXcbScrollingDevicePrivate *scrollingDeviceP)
|
||||||
{
|
{
|
||||||
auto *deviceInfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
|
auto *deviceInfo = reinterpret_cast<xcb_input_xi_device_info_t *>(info);
|
||||||
QPointingDevice::Capabilities caps;
|
QPointingDevice::Capabilities caps;
|
||||||
@ -581,6 +581,8 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
|
|||||||
} else if (valuatorAtom == QXcbAtom::AbsY) {
|
} else if (valuatorAtom == QXcbAtom::AbsY) {
|
||||||
caps |= QInputDevice::Capability::Position;
|
caps |= QInputDevice::Capability::Position;
|
||||||
dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
|
dev.size.setHeight((fixed3232ToReal(vci->max) - fixed3232ToReal(vci->min)) * 1000.0 / vciResolution);
|
||||||
|
} else if (valuatorAtom == QXcbAtom::RelVertWheel || valuatorAtom == QXcbAtom::RelHorizWheel) {
|
||||||
|
caps |= QInputDevice::Capability::Scroll;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -600,11 +602,24 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
|
|||||||
if (type == QInputDevice::DeviceType::TouchScreen || type == QInputDevice::DeviceType::TouchPad) {
|
if (type == QInputDevice::DeviceType::TouchScreen || type == QInputDevice::DeviceType::TouchPad) {
|
||||||
QInputDevice *master = const_cast<QInputDevice *>(QInputDevicePrivate::fromId(deviceInfo->attachment));
|
QInputDevice *master = const_cast<QInputDevice *>(QInputDevicePrivate::fromId(deviceInfo->attachment));
|
||||||
Q_ASSERT(master);
|
Q_ASSERT(master);
|
||||||
dev.qtTouchDevice = new QPointingDevice(QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo),
|
if (scrollingDeviceP) {
|
||||||
xcb_input_xi_device_info_name_length(deviceInfo)),
|
// valuators were already discovered in QXcbConnection::xi2SetupSlavePointerDevice, so just finish initialization
|
||||||
deviceInfo->deviceid,
|
scrollingDeviceP->deviceType = type;
|
||||||
type, QPointingDevice::PointerType::Finger, caps, maxTouchPoints, 0,
|
scrollingDeviceP->pointerType = QPointingDevice::PointerType::Finger;
|
||||||
master->seatName(), QPointingDeviceUniqueId(), master);
|
scrollingDeviceP->capabilities |= caps;
|
||||||
|
scrollingDeviceP->maximumTouchPoints = maxTouchPoints;
|
||||||
|
scrollingDeviceP->buttonCount = 3;
|
||||||
|
scrollingDeviceP->seatName = master->seatName();
|
||||||
|
dev.qtTouchDevice = new QXcbScrollingDevice(*scrollingDeviceP, master);
|
||||||
|
if (Q_UNLIKELY(!caps.testFlag(QInputDevice::Capability::Scroll)))
|
||||||
|
qCDebug(lcQpaXInputDevices) << "unexpectedly missing RelVert/HorizWheel atoms for touchpad with scroll capability" << dev.qtTouchDevice;
|
||||||
|
} else {
|
||||||
|
dev.qtTouchDevice = new QPointingDevice(QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo),
|
||||||
|
xcb_input_xi_device_info_name_length(deviceInfo)),
|
||||||
|
deviceInfo->deviceid,
|
||||||
|
type, QPointingDevice::PointerType::Finger, caps, maxTouchPoints, 0,
|
||||||
|
master->seatName(), QPointingDeviceUniqueId(), master);
|
||||||
|
}
|
||||||
if (caps != 0)
|
if (caps != 0)
|
||||||
QWindowSystemInterface::registerInputDevice(dev.qtTouchDevice);
|
QWindowSystemInterface::registerInputDevice(dev.qtTouchDevice);
|
||||||
m_touchDevices[deviceInfo->deviceid] = dev;
|
m_touchDevices[deviceInfo->deviceid] = dev;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user