diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qpointingdevice.cpp | 19 | ||||
-rw-r--r-- | src/gui/kernel/qpointingdevice_p.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 23 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 171 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscrollingdevice.cpp | 50 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscrollingdevice_p.h | 79 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/xcb_qpa_lib.pro | 2 |
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 \ |