summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-11-26 16:38:55 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2020-12-15 19:03:24 +0100
commitac210c73e43621f942d3cb947eef036fc5e7646e (patch)
tree4dd3a8b435525a520d6a0176ad6078fbbdbfdd2f /src/plugins/platforms
parent50e1976437f645e9d6571d4498e9d44388e59c19 (diff)
xcb: report wheel events from the correct device instance
Until now, all wheel events came from one "core pointer". It's useful in Qt Quick to tell the devices apart, because some support smooth scrolling and some don't. Also remove the QHash storing legacy ScrollingDevice structs, and use a subclass of QPointingDevicePrivate instead. Task-number: QTBUG-46412 Task-number: QTBUG-72167 Task-number: QTBUG-69433 Change-Id: Ie6a3d8dd494f981e8706b9a66a1021dfb51baec4 Reviewed-by: Liang Qi <liang.qi@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/plugins/platforms')
-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
6 files changed, 235 insertions, 91 deletions
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 \