summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qpointingdevice.cpp19
-rw-r--r--src/gui/kernel/qpointingdevice_p.h2
-rw-r--r--src/plugins/platforms/xcb/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h23
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp171
-rw-r--r--src/plugins/platforms/xcb/qxcbscrollingdevice.cpp50
-rw-r--r--src/plugins/platforms/xcb/qxcbscrollingdevice_p.h79
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro2
8 files changed, 256 insertions, 91 deletions
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp
index eba17f52ee..6ef032098f 100644
--- a/src/gui/kernel/qpointingdevice.cpp
+++ b/src/gui/kernel/qpointingdevice.cpp
@@ -356,6 +356,25 @@ const QPointingDevice *QPointingDevicePrivate::queryTabletDevice(QInputDevice::D
/*!
\internal
+ Finds the device instance identified by its \a systemId.
+ Returns the device found, or \c nullptr if none was found.
+*/
+const QPointingDevice *QPointingDevicePrivate::pointingDeviceById(qint64 systemId)
+{
+ const auto &devices = QInputDevice::devices();
+ for (const QInputDevice *dev : devices) {
+ if (dev->type() >= QPointingDevice::DeviceType::Keyboard)
+ continue;
+ const QPointingDevice *pdev = static_cast<const QPointingDevice *>(dev);
+ const auto devPriv = QPointingDevicePrivate::get(pdev);
+ if (devPriv->systemId == systemId)
+ return pdev;
+ }
+ return nullptr;
+}
+
+/*!
+ \internal
First, ensure that the \a cancelEvent's QTouchEvent::points() list contains
all points that have exclusive grabs. Then send the event to each object
that has an exclusive grab of any of the points.
diff --git a/src/gui/kernel/qpointingdevice_p.h b/src/gui/kernel/qpointingdevice_p.h
index 6f787b4159..645c82673b 100644
--- a/src/gui/kernel/qpointingdevice_p.h
+++ b/src/gui/kernel/qpointingdevice_p.h
@@ -132,6 +132,8 @@ public:
QPointingDevice::PointerType pointerType,
QPointingDeviceUniqueId uniqueId,
qint64 systemId = 0);
+
+ static const QPointingDevice *pointingDeviceById(qint64 systemId);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/CMakeLists.txt b/src/plugins/platforms/xcb/CMakeLists.txt
index 865e4c94ca..ab19501991 100644
--- a/src/plugins/platforms/xcb/CMakeLists.txt
+++ b/src/plugins/platforms/xcb/CMakeLists.txt
@@ -26,6 +26,7 @@ qt_internal_add_module(XcbQpa
qxcbimage.cpp qxcbimage.h
qxcbintegration.cpp qxcbintegration.h
qxcbkeyboard.cpp qxcbkeyboard.h
+ qxcbscrollingdevice.cpp qxcbscrollingdevice_p.h
qxcbmime.cpp qxcbmime.h
qxcbnativeinterface.cpp qxcbnativeinterface.h
qxcbobject.h
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 67caf7d827..b62d461170 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -78,6 +78,7 @@ class QXcbScreen;
class QXcbWindow;
class QXcbDrag;
class QXcbKeyboard;
+class QXcbScrollingDevicePrivate;
class QXcbClipboard;
class QXcbWMSupport;
class QXcbNativeInterface;
@@ -264,7 +265,7 @@ private:
void xi2SetupSlavePointerDevice(void *info, bool removeExisting = true, QPointingDevice *master = nullptr);
void xi2SetupDevices();
- // TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
+ // TODO get rid of this: store minimal necessary info in a subclass of QPointingDevicePrivate
struct TouchDeviceData {
QPointingDevice *qtTouchDevice = nullptr;
QHash<int, QWindowSystemInterface::TouchPoint> touchPoints;
@@ -290,7 +291,7 @@ private:
void xi2HandleDeviceChangedEvent(void *event);
void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
#if QT_CONFIG(tabletevent)
- // TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
+ // TODO get rid of this: store minimal necessary info in a subclass of QXcbScrollingDevice (some tablets can scroll)
struct TabletData {
int deviceId = 0;
QString name;
@@ -314,21 +315,9 @@ private:
QList<TabletData> m_tabletData;
TabletData *tabletDataForDevice(int id);
#endif // QT_CONFIG(tabletevent)
- // TODO get rid of this: store a smaller struct in QPointingDevicePrivate::extra
- struct ScrollingDevice {
- int deviceId = 0;
- int verticalIndex = 0;
- int horizontalIndex = 0;
- double verticalIncrement = 0;
- double horizontalIncrement = 0;
- Qt::Orientations orientations;
- Qt::Orientations legacyOrientations;
- QPointF lastScrollPosition;
- };
- QHash<int, ScrollingDevice> m_scrollingDevices;
- void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
- void xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice);
- ScrollingDevice *scrollingDeviceForId(int id);
+ void xi2HandleScrollEvent(void *event, const QPointingDevice *scrollingDevice);
+ void xi2UpdateScrollingDevice(QXcbScrollingDevicePrivate *scrollingDevice);
+ QXcbScrollingDevicePrivate *scrollingDeviceForId(int id);
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 682cc9525a..03c45dfc3e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -39,6 +39,7 @@
#include "qxcbconnection.h"
#include "qxcbkeyboard.h"
+#include "qxcbscrollingdevice_p.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "QtCore/qmetaobject.h"
@@ -243,15 +244,24 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
}
}
#endif
- m_scrollingDevices.remove(deviceInfo->deviceid);
m_touchDevices.remove(deviceInfo->deviceid);
}
- qCDebug(lcQpaXInputDevices) << "input device " << xcb_input_xi_device_info_name(deviceInfo) << "ID" << deviceInfo->deviceid;
+ const QByteArray nameRaw = QByteArray(xcb_input_xi_device_info_name(deviceInfo),
+ xcb_input_xi_device_info_name_length(deviceInfo));
+ const QString name = QString::fromUtf8(nameRaw);
+ qCDebug(lcQpaXInputDevices) << "input device " << name << "ID" << deviceInfo->deviceid;
#if QT_CONFIG(tabletevent)
TabletData tabletData;
#endif
- ScrollingDevice scrollingDevice;
+ QXcbScrollingDevicePrivate *scrollingDeviceP = nullptr;
+ auto scrollingDevice = [&]() {
+ if (!scrollingDeviceP)
+ scrollingDeviceP = new QXcbScrollingDevicePrivate(name, deviceInfo->deviceid,
+ QInputDevice::Capability::Scroll);
+ return scrollingDeviceP;
+ };
+
int buttonCount = 32;
auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
for (; classes_it.rem; xcb_input_device_class_next(&classes_it)) {
@@ -271,21 +281,23 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
}
#endif // QT_CONFIG(tabletevent)
if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
- scrollingDevice.lastScrollPosition.setX(fixed3232ToReal(vci->value));
+ scrollingDevice()->lastScrollPosition.setX(fixed3232ToReal(vci->value));
else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
- scrollingDevice.lastScrollPosition.setY(fixed3232ToReal(vci->value));
+ scrollingDevice()->lastScrollPosition.setY(fixed3232ToReal(vci->value));
break;
}
case XCB_INPUT_DEVICE_CLASS_TYPE_SCROLL: {
auto *sci = reinterpret_cast<xcb_input_scroll_class_t *>(classinfo);
if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_VERTICAL) {
- scrollingDevice.orientations |= Qt::Vertical;
- scrollingDevice.verticalIndex = sci->number;
- scrollingDevice.verticalIncrement = fixed3232ToReal(sci->increment);
+ auto dev = scrollingDevice();
+ dev->orientations |= Qt::Vertical;
+ dev->verticalIndex = sci->number;
+ dev->verticalIncrement = fixed3232ToReal(sci->increment);
} else if (sci->scroll_type == XCB_INPUT_SCROLL_TYPE_HORIZONTAL) {
- scrollingDevice.orientations |= Qt::Horizontal;
- scrollingDevice.horizontalIndex = sci->number;
- scrollingDevice.horizontalIncrement = fixed3232ToReal(sci->increment);
+ auto dev = scrollingDevice();
+ dev->orientations |= Qt::Horizontal;
+ dev->horizontalIndex = sci->number;
+ dev->horizontalIncrement = fixed3232ToReal(sci->increment);
}
break;
}
@@ -300,13 +312,13 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
// button 4 and the wrong one on button 5. So we just check that they are not labelled with unrelated buttons.
if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp || qatom(label4) == QXcbAtom::ButtonWheelDown) &&
(!label5 || qatom(label5) == QXcbAtom::ButtonWheelUp || qatom(label5) == QXcbAtom::ButtonWheelDown))
- scrollingDevice.legacyOrientations |= Qt::Vertical;
+ scrollingDevice()->legacyOrientations |= Qt::Vertical;
}
if (bci->num_buttons >= 7) {
xcb_atom_t label6 = labels[5];
xcb_atom_t label7 = labels[6];
if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
- scrollingDevice.legacyOrientations |= Qt::Horizontal;
+ scrollingDevice()->legacyOrientations |= Qt::Horizontal;
}
buttonCount = bci->num_buttons;
qCDebug(lcQpaXInputDevices, " has %d buttons", bci->num_buttons);
@@ -332,9 +344,7 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
isTablet = true;
// But we need to be careful not to take the touch and tablet-button devices as tablets.
- QByteArray name = QByteArray(xcb_input_xi_device_info_name(deviceInfo),
- xcb_input_xi_device_info_name_length(deviceInfo));
- QByteArray nameLower = name.toLower();
+ QByteArray nameLower = nameRaw.toLower();
QString dbgType = QLatin1String("UNKNOWN");
if (nameLower.contains("eraser")) {
isTablet = true;
@@ -377,7 +387,7 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
if (isTablet) {
tabletData.deviceId = deviceInfo->deviceid;
- tabletData.name = QLatin1String(name);
+ tabletData.name = name;
m_tabletData.append(tabletData);
qCDebug(lcQpaXInputDevices) << " it's a tablet with pointer type" << dbgType;
QPointingDevice::Capabilities capsOverride = QInputDevice::Capability::None;
@@ -394,11 +404,9 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
}
#endif // QT_CONFIG(tabletevent)
- if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) {
- scrollingDevice.deviceId = deviceInfo->deviceid;
+ if (scrollingDeviceP) {
// Only use legacy wheel button events when we don't have real scroll valuators.
- scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations;
- m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
+ scrollingDeviceP->legacyOrientations &= ~scrollingDeviceP->orientations;
qCDebug(lcQpaXInputDevices) << " it's a scrolling device";
}
@@ -420,12 +428,18 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
if (!QInputDevicePrivate::fromId(deviceInfo->deviceid)) {
qCDebug(lcQpaXInputDevices) << " it's a mouse";
QInputDevice::Capabilities caps = QInputDevice::Capability::Position | QInputDevice::Capability::Hover;
- if (scrollingDevice.orientations || scrollingDevice.legacyOrientations)
- caps.setFlag(QInputDevice::Capability::Scroll);
- QWindowSystemInterface::registerInputDevice(new QPointingDevice(
- QString::fromUtf8(xcb_input_xi_device_info_name(deviceInfo)), deviceInfo->deviceid,
- QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
- caps, 1, buttonCount, (master ? master->seatName() : QString()), QPointingDeviceUniqueId(), master));
+ if (scrollingDeviceP) {
+ scrollingDeviceP->capabilities |= caps;
+ scrollingDeviceP->buttonCount = buttonCount;
+ if (master)
+ scrollingDeviceP->seatName = master->seatName();
+ QWindowSystemInterface::registerInputDevice(new QXcbScrollingMouse(*scrollingDeviceP, master));
+ } else {
+ QWindowSystemInterface::registerInputDevice(new QPointingDevice(
+ name, deviceInfo->deviceid,
+ QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
+ caps, 1, buttonCount, (master ? master->seatName() : QString()), QPointingDeviceUniqueId(), master));
+ }
}
}
@@ -434,7 +448,6 @@ void QXcbConnection::xi2SetupDevices()
#if QT_CONFIG(tabletevent)
m_tabletData.clear();
#endif
- m_scrollingDevices.clear();
m_touchDevices.clear();
m_xiMasterPointerIds.clear();
@@ -659,8 +672,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
#endif // QT_CONFIG(tabletevent)
- if (ScrollingDevice *device = scrollingDeviceForId(sourceDeviceId))
- xi2HandleScrollEvent(event, *device);
+ if (auto device = QPointingDevicePrivate::pointingDeviceById(sourceDeviceId))
+ xi2HandleScrollEvent(event, device);
if (xiDeviceEvent) {
switch (xiDeviceEvent->event_type) {
@@ -968,8 +981,8 @@ void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
break;
}
case XCB_INPUT_CHANGE_REASON_SLAVE_SWITCH: {
- if (ScrollingDevice *scrollingDevice = scrollingDeviceForId(xiEvent->sourceid))
- xi2UpdateScrollingDevice(*scrollingDevice);
+ if (auto *scrollingDevice = scrollingDeviceForId(xiEvent->sourceid))
+ xi2UpdateScrollingDevice(scrollingDevice);
break;
}
default:
@@ -978,16 +991,16 @@ void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
}
}
-void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice)
+void QXcbConnection::xi2UpdateScrollingDevice(QXcbScrollingDevicePrivate *scrollingDevice)
{
- auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, xcb_connection(), scrollingDevice.deviceId);
+ auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, xcb_connection(), scrollingDevice->systemId);
if (!reply || reply->num_infos <= 0) {
- qCDebug(lcQpaXInputDevices, "scrolling device %d no longer present", scrollingDevice.deviceId);
+ qCDebug(lcQpaXInputDevices, "scrolling device %lld no longer present", scrollingDevice->systemId);
return;
}
QPointF lastScrollPosition;
if (lcQpaXInputEvents().isDebugEnabled())
- lastScrollPosition = scrollingDevice.lastScrollPosition;
+ lastScrollPosition = scrollingDevice->lastScrollPosition;
xcb_input_xi_device_info_t *deviceInfo = xcb_input_xi_query_device_infos_iterator(reply.get()).data;
auto classes_it = xcb_input_xi_device_info_classes_iterator(deviceInfo);
@@ -997,68 +1010,75 @@ void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice)
auto *vci = reinterpret_cast<xcb_input_valuator_class_t *>(classInfo);
const int valuatorAtom = qatom(vci->label);
if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
- scrollingDevice.lastScrollPosition.setX(fixed3232ToReal(vci->value));
+ scrollingDevice->lastScrollPosition.setX(fixed3232ToReal(vci->value));
else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
- scrollingDevice.lastScrollPosition.setY(fixed3232ToReal(vci->value));
+ scrollingDevice->lastScrollPosition.setY(fixed3232ToReal(vci->value));
}
}
- if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled() && lastScrollPosition != scrollingDevice.lastScrollPosition))
- qCDebug(lcQpaXInputEvents, "scrolling device %d moved from (%f, %f) to (%f, %f)", scrollingDevice.deviceId,
+ if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled() && lastScrollPosition != scrollingDevice->lastScrollPosition))
+ qCDebug(lcQpaXInputEvents, "scrolling device %lld moved from (%f, %f) to (%f, %f)", scrollingDevice->systemId,
lastScrollPosition.x(), lastScrollPosition.y(),
- scrollingDevice.lastScrollPosition.x(),
- scrollingDevice.lastScrollPosition.y());
+ scrollingDevice->lastScrollPosition.x(),
+ scrollingDevice->lastScrollPosition.y());
}
void QXcbConnection::xi2UpdateScrollingDevices()
{
- QHash<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin();
- const QHash<int, ScrollingDevice>::iterator end = m_scrollingDevices.end();
- while (it != end) {
- xi2UpdateScrollingDevice(it.value());
- ++it;
+ const auto &devices = QInputDevice::devices();
+ for (const QInputDevice *dev : devices) {
+ if (dev->capabilities().testFlag(QInputDevice::Capability::Scroll)) {
+ const auto devPriv = QPointingDevicePrivate::get(static_cast<QPointingDevice *>(const_cast<QInputDevice *>(dev)));
+ xi2UpdateScrollingDevice(static_cast<QXcbScrollingDevicePrivate *>(devPriv));
+ }
}
}
-QXcbConnection::ScrollingDevice *QXcbConnection::scrollingDeviceForId(int id)
+QXcbScrollingDevicePrivate *QXcbConnection::scrollingDeviceForId(int id)
{
- ScrollingDevice *dev = nullptr;
- if (m_scrollingDevices.contains(id))
- dev = &m_scrollingDevices[id];
- return dev;
+ const QPointingDevice *dev = QPointingDevicePrivate::pointingDeviceById(id);
+ if (!dev)
+ return nullptr;
+ if (!dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
+ return nullptr;
+ auto devPriv = QPointingDevicePrivate::get(const_cast<QPointingDevice *>(dev));
+ return static_cast<QXcbScrollingDevicePrivate *>(devPriv);
}
-void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
+void QXcbConnection::xi2HandleScrollEvent(void *event, const QPointingDevice *dev)
{
auto *xiDeviceEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
+ if (!dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
+ return;
+ const auto scrollingDevice = static_cast<const QXcbScrollingDevicePrivate *>(QPointingDevicePrivate::get(dev));
- if (xiDeviceEvent->event_type == XCB_INPUT_MOTION && scrollingDevice.orientations) {
+ if (xiDeviceEvent->event_type == XCB_INPUT_MOTION && scrollingDevice->orientations) {
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint rawDelta;
QPoint angleDelta;
double value;
- if (scrollingDevice.orientations & Qt::Vertical) {
- if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.verticalIndex, &value)) {
- double delta = scrollingDevice.lastScrollPosition.y() - value;
- scrollingDevice.lastScrollPosition.setY(value);
- angleDelta.setY((delta / scrollingDevice.verticalIncrement) * 120);
+ if (scrollingDevice->orientations & Qt::Vertical) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice->verticalIndex, &value)) {
+ double delta = scrollingDevice->lastScrollPosition.y() - value;
+ scrollingDevice->lastScrollPosition.setY(value);
+ angleDelta.setY((delta / scrollingDevice->verticalIncrement) * 120);
// With most drivers the increment is 1 for wheels.
// For libinput it is hardcoded to a useless 15.
// For a proper touchpad driver it should be in the same order of magnitude as 120
- if (scrollingDevice.verticalIncrement > 15)
+ if (scrollingDevice->verticalIncrement > 15)
rawDelta.setY(delta);
- else if (scrollingDevice.verticalIncrement < -15)
+ else if (scrollingDevice->verticalIncrement < -15)
rawDelta.setY(-delta);
}
}
- if (scrollingDevice.orientations & Qt::Horizontal) {
- if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.horizontalIndex, &value)) {
- double delta = scrollingDevice.lastScrollPosition.x() - value;
- scrollingDevice.lastScrollPosition.setX(value);
- angleDelta.setX((delta / scrollingDevice.horizontalIncrement) * 120);
+ if (scrollingDevice->orientations & Qt::Horizontal) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice->horizontalIndex, &value)) {
+ double delta = scrollingDevice->lastScrollPosition.x() - value;
+ scrollingDevice->lastScrollPosition.setX(value);
+ angleDelta.setX((delta / scrollingDevice->horizontalIncrement) * 120);
// See comment under vertical
- if (scrollingDevice.horizontalIncrement > 15)
+ if (scrollingDevice->horizontalIncrement > 15)
rawDelta.setX(delta);
- else if (scrollingDevice.horizontalIncrement < -15)
+ else if (scrollingDevice->horizontalIncrement < -15)
rawDelta.setX(-delta);
}
}
@@ -1070,20 +1090,22 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
angleDelta = angleDelta.transposed();
rawDelta = rawDelta.transposed();
}
- qCDebug(lcQpaXInputEvents) << "scroll wheel @ window pos" << local << "delta px" << rawDelta << "angle" << angleDelta;
- QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, rawDelta, angleDelta, modifiers);
+ qCDebug(lcQpaXInputEvents) << "scroll wheel from device" << scrollingDevice->systemId
+ << "@ window pos" << local << "delta px" << rawDelta << "angle" << angleDelta;
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, dev,
+ local, global, rawDelta, angleDelta, modifiers);
}
}
- } else if (xiDeviceEvent->event_type == XCB_INPUT_BUTTON_RELEASE && scrollingDevice.legacyOrientations) {
+ } else if (xiDeviceEvent->event_type == XCB_INPUT_BUTTON_RELEASE && scrollingDevice->legacyOrientations) {
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
QPoint angleDelta;
- if (scrollingDevice.legacyOrientations & Qt::Vertical) {
+ if (scrollingDevice->legacyOrientations & Qt::Vertical) {
if (xiDeviceEvent->detail == 4)
angleDelta.setY(120);
else if (xiDeviceEvent->detail == 5)
angleDelta.setY(-120);
}
- if (scrollingDevice.legacyOrientations & Qt::Horizontal) {
+ if (scrollingDevice->legacyOrientations & Qt::Horizontal) {
if (xiDeviceEvent->detail == 6)
angleDelta.setX(120);
else if (xiDeviceEvent->detail == 7)
@@ -1096,7 +1118,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
if (modifiers & Qt::AltModifier)
angleDelta = angleDelta.transposed();
qCDebug(lcQpaXInputEvents) << "scroll wheel (button" << xiDeviceEvent->detail << ") @ window pos" << local << "delta angle" << angleDelta;
- QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, local, global, QPoint(), angleDelta, modifiers);
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiDeviceEvent->time, dev,
+ local, global, QPoint(), angleDelta, modifiers);
}
}
}
diff --git a/src/plugins/platforms/xcb/qxcbscrollingdevice.cpp b/src/plugins/platforms/xcb/qxcbscrollingdevice.cpp
new file mode 100644
index 0000000000..f37109ae9e
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbscrollingdevice.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qxcbscrollingdevice_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QXcbScrollingDevicePrivate::QXcbScrollingDevicePrivate(const QString &name, qint64 id, QInputDevice::Capabilities caps,
+ int buttonCount, const QString &seatName)
+ : QPointingDevicePrivate(name, id, QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
+ caps, 1, buttonCount, seatName)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbscrollingdevice_p.h b/src/plugins/platforms/xcb/qxcbscrollingdevice_p.h
new file mode 100644
index 0000000000..26839e3129
--- /dev/null
+++ b/src/plugins/platforms/xcb/qxcbscrollingdevice_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXCBSCROLLINGDEVICE_P_H
+#define QXCBSCROLLINGDEVICE_P_H
+
+#include <QtGui/private/qpointingdevice_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \internal
+ On the xcb platform, if a device's QPointingDevice::capabilities() includes
+ QInputDevice::Capability::Scroll, then its d-pointer must point to
+ an instance of this subclass, which tracks the scrolling valuators.
+*/
+class QXcbScrollingDevicePrivate : public QPointingDevicePrivate
+{
+ Q_DECLARE_PUBLIC(QPointingDevice)
+public:
+ QXcbScrollingDevicePrivate(const QString &name, qint64 id, QPointingDevice::Capabilities caps,
+ int buttonCount = 3, const QString &seatName = QString());
+
+ // scrolling-related data
+ int verticalIndex = 0;
+ int horizontalIndex = 0;
+ double verticalIncrement = 0;
+ double horizontalIncrement = 0;
+ Qt::Orientations orientations;
+ Qt::Orientations legacyOrientations;
+ mutable QPointF lastScrollPosition;
+ // end of scrolling-related data
+};
+
+class QXcbScrollingMouse : public QPointingDevice
+{
+public:
+ QXcbScrollingMouse(QXcbScrollingDevicePrivate &d, QObject *parent)
+ : QPointingDevice(d, parent) {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QXCBSCROLLINGDEVICE_P_H
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index bb57e16ab5..29eb2906e9 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -13,6 +13,7 @@ SOURCES = \
qxcbconnection.cpp \
qxcbintegration.cpp \
qxcbkeyboard.cpp \
+ qxcbscrollingdevice.cpp \
qxcbmime.cpp \
qxcbscreen.cpp \
qxcbwindow.cpp \
@@ -35,6 +36,7 @@ HEADERS = \
qxcbconnection.h \
qxcbintegration.h \
qxcbkeyboard.h \
+ qxcbscrollingdevice_p.h \
qxcbmime.h \
qxcbobject.h \
qxcbscreen.h \