diff options
Diffstat (limited to 'src/gui/kernel/qpointingdevice.cpp')
-rw-r--r-- | src/gui/kernel/qpointingdevice.cpp | 160 |
1 files changed, 100 insertions, 60 deletions
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp index 176a5fedf4..c4c1e5fd5c 100644 --- a/src/gui/kernel/qpointingdevice.cpp +++ b/src/gui/kernel/qpointingdevice.cpp @@ -1,45 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module 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$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qpointingdevice.h" #include "qpointingdevice_p.h" #include "qwindowsysteminterface_p.h" +#include "qeventpoint_p.h" + #include <QList> #include <QLoggingCategory> #include <QMutex> @@ -49,6 +15,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + Q_LOGGING_CATEGORY(lcPointerGrab, "qt.pointer.grab"); /*! @@ -143,11 +111,53 @@ Q_LOGGING_CATEGORY(lcPointerGrab, "qt.pointer.grab"); Any of the above (used as a default filter value). */ +/*! \enum QPointingDevice::GrabTransition + + This enum represents a transition of exclusive or passive grab + from one object (possibly \c nullptr) to another (possibly \c nullptr). + It is emitted as an argument of the QPointingDevice::grabChanged() signal. + + Valid values are: + + \value GrabExclusive + Emitted after QPointerEvent::setExclusiveGrabber(). + \value UngrabExclusive + Emitted after QPointerEvent::setExclusiveGrabber() when the grabber is + set to \c nullptr, to notify that the grab has terminated normally. + \value CancelGrabExclusive + Emitted after QPointerEvent::setExclusiveGrabber() when the grabber is set + to a different object, to notify that the old grabber's grab is "stolen". + \value GrabPassive + Emitted after QPointerEvent::addPassiveGrabber(). + \value UngrabPassive + Emitted when a passive grab is terminated normally, + for example after QPointerEvent::removePassiveGrabber(). + \value CancelGrabPassive + Emitted when a passive grab is terminated abnormally (a gesture is canceled). + \value OverrideGrabPassive + This value is not currently used. +*/ + +/*! \fn void QPointingDevice::grabChanged(QObject *grabber, QPointingDevice::GrabTransition transition, const QPointerEvent *event, const QEventPoint &point) const + + This signal is emitted when the \a grabber object gains or loses an + exclusive or passive grab of \a point during delivery of \a event. + The \a transition tells what happened, from the perspective of the + \c grabber object. + + \note A grab transition from one object to another results in two signals, + to notify that one object has lost its grab, and to notify that there is + another grabber. In other cases, when transitioning to or from a non-grabbing + state, only one signal is emitted: the \a grabber argument is never \c nullptr. + + \sa QPointerEvent::setExclusiveGrabber(), QPointerEvent::addPassiveGrabber(), QPointerEvent::removePassiveGrabber() +*/ + /*! Creates a new invalid pointing device instance as a child of \a parent. */ QPointingDevice::QPointingDevice(QObject *parent) - : QInputDevice(*(new QPointingDevicePrivate(QLatin1String("unknown"), -1, + : QInputDevice(*(new QPointingDevicePrivate("unknown"_L1, -1, DeviceType::Unknown, PointerType::Unknown, Capability::None, 0, 0)), parent) { @@ -177,9 +187,10 @@ QPointingDevice::QPointingDevice(QPointingDevicePrivate &d, QObject *parent) { } +#if QT_DEPRECATED_SINCE(6, 0) /*! \internal - \deprecated Please use the constructor rather than setters. + \deprecated [6.0] Please use the constructor rather than setters. Sets the device type \a devType and infers the pointer type. */ @@ -210,7 +221,7 @@ void QPointingDevice::setType(DeviceType devType) /*! \internal - \deprecated Please use the constructor rather than setters. + \deprecated [6.0] Please use the constructor rather than setters. */ void QPointingDevice::setCapabilities(QInputDevice::Capabilities caps) { @@ -220,13 +231,14 @@ void QPointingDevice::setCapabilities(QInputDevice::Capabilities caps) /*! \internal - \deprecated Please use the constructor rather than setters. + \deprecated [6.0] Please use the constructor rather than setters. */ void QPointingDevice::setMaximumTouchPoints(int c) { Q_D(QPointingDevice); d->maximumTouchPoints = c; } +#endif // QT_DEPRECATED_SINCE(6, 0) /*! Returns the pointer type. @@ -284,7 +296,7 @@ const QPointingDevice *QPointingDevice::primaryPointingDevice(const QString& sea const QPointingDevice *mouse = nullptr; const QPointingDevice *touchpad = nullptr; for (const QInputDevice *dev : v) { - if (dev->seatName() != seatName) + if (!seatName.isNull() && dev->seatName() != seatName) continue; if (dev->type() == QInputDevice::DeviceType::Mouse) { if (!mouse) @@ -301,19 +313,22 @@ const QPointingDevice *QPointingDevice::primaryPointingDevice(const QString& sea qCDebug(lcQpaInputDevices) << "no mouse-like devices registered for seat" << seatName << "The platform plugin should have provided one via " "QWindowSystemInterface::registerInputDevice(). Creating a default mouse for now."; - mouse = new QPointingDevice(QLatin1String("core pointer"), 1, DeviceType::Mouse, + mouse = new QPointingDevice("core pointer"_L1, 1, DeviceType::Mouse, PointerType::Generic, Capability::Position, 1, 3, seatName, QPointingDeviceUniqueId(), QCoreApplication::instance()); QInputDevicePrivate::registerDevice(mouse); return mouse; } - if (v.length() > 1) + if (v.size() > 1) qCDebug(lcQpaInputDevices) << "core pointer ambiguous for seat" << seatName; if (mouse) return mouse; return touchpad; } +QPointingDevicePrivate::~QPointingDevicePrivate() + = default; + /*! \internal Finds the device instance belonging to the drawing or eraser end of a particular stylus, @@ -422,13 +437,12 @@ QPointingDevicePrivate::EventPointData *QPointingDevicePrivate::queryPointById(i */ QPointingDevicePrivate::EventPointData *QPointingDevicePrivate::pointById(int id) const { - auto it = activePoints.find(id); - if (it == activePoints.end()) { + const auto [it, inserted] = activePoints.try_emplace(id); + if (inserted) { Q_Q(const QPointingDevice); - QPointingDevicePrivate::EventPointData epd; - QMutableEventPoint::from(epd.eventPoint).setId(id); - QMutableEventPoint::from(epd.eventPoint).setDevice(q); - return &activePoints.insert(id, epd).first.value(); + auto &epd = it.value(); + QMutableEventPoint::setId(epd.eventPoint, id); + QMutableEventPoint::setDevice(epd.eventPoint, q); } return &it.value(); } @@ -451,7 +465,7 @@ void QPointingDevicePrivate::removePointById(int id) QObject *QPointingDevicePrivate::firstActiveTarget() const { for (auto &pt : activePoints.values()) { - if (auto target = QMutableEventPoint::constFrom(pt.eventPoint).target()) + if (auto target = QMutableEventPoint::target(pt.eventPoint)) return target; } return nullptr; @@ -466,7 +480,7 @@ QObject *QPointingDevicePrivate::firstActiveTarget() const QWindow *QPointingDevicePrivate::firstActiveWindow() const { for (auto &pt : activePoints.values()) { - if (auto window = QMutableEventPoint::constFrom(pt.eventPoint).window()) + if (auto window = QMutableEventPoint::window(pt.eventPoint)) return window; } return nullptr; @@ -493,6 +507,7 @@ void QPointingDevicePrivate::setExclusiveGrabber(const QPointerEvent *event, con qWarning() << "point is not in activePoints" << point; return; } + Q_ASSERT(persistentPoint->eventPoint.id() == point.id()); if (persistentPoint->exclusiveGrabber == exclusiveGrabber) return; auto oldGrabber = persistentPoint->exclusiveGrabber; @@ -505,9 +520,11 @@ void QPointingDevicePrivate::setExclusiveGrabber(const QPointerEvent *event, con << "@" << point.scenePosition() << ": grab" << oldGrabber << "->" << exclusiveGrabber; } - QMutableEventPoint::from(persistentPoint->eventPoint).setGlobalGrabPosition(point.globalPosition()); + QMutableEventPoint::setGlobalGrabPosition(persistentPoint->eventPoint, point.globalPosition()); if (exclusiveGrabber) emit q->grabChanged(exclusiveGrabber, QPointingDevice::GrabExclusive, event, point); + else + persistentPoint->exclusiveGrabberContext.clear(); } /*! @@ -545,6 +562,17 @@ bool QPointingDevicePrivate::addPassiveGrabber(const QPointerEvent *event, const return true; } +bool QPointingDevicePrivate::setPassiveGrabberContext(QPointingDevicePrivate::EventPointData *epd, QObject *grabber, QObject *context) +{ + qsizetype i = epd->passiveGrabbers.indexOf(grabber); + if (i < 0) + return false; + if (epd->passiveGrabbersContext.size() <= i) + epd->passiveGrabbersContext.resize(i + 1); + epd->passiveGrabbersContext[i] = context; + return true; +} + bool QPointingDevicePrivate::removePassiveGrabber(const QPointerEvent *event, const QEventPoint &point, QObject *grabber) { Q_Q(QPointingDevice); @@ -553,7 +581,7 @@ bool QPointingDevicePrivate::removePassiveGrabber(const QPointerEvent *event, co qWarning() << "point is not in activePoints" << point; return false; } - int i = persistentPoint->passiveGrabbers.indexOf(grabber); + qsizetype i = persistentPoint->passiveGrabbers.indexOf(grabber); if (i >= 0) { if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) { qCDebug(lcPointerGrab) << name << "point" << point.id() << point.state() @@ -561,6 +589,10 @@ bool QPointingDevicePrivate::removePassiveGrabber(const QPointerEvent *event, co } emit q->grabChanged(grabber, QPointingDevice::UngrabPassive, event, point); persistentPoint->passiveGrabbers.removeAt(i); + if (persistentPoint->passiveGrabbersContext.size()) { + Q_ASSERT(persistentPoint->passiveGrabbersContext.size() > i); + persistentPoint->passiveGrabbersContext.removeAt(i); + } return true; } return false; @@ -583,6 +615,7 @@ void QPointingDevicePrivate::clearPassiveGrabbers(const QPointerEvent *event, co for (auto g : persistentPoint->passiveGrabbers) emit q->grabChanged(g, QPointingDevice::UngrabPassive, event, point); persistentPoint->passiveGrabbers.clear(); + persistentPoint->passiveGrabbersContext.clear(); } /*! @@ -606,15 +639,20 @@ void QPointingDevicePrivate::removeGrabber(QObject *grabber, bool cancel) << "@" << epd.eventPoint.scenePosition() << ": grab" << grabber << "-> nullptr"; epd.exclusiveGrabber.clear(); + epd.exclusiveGrabberContext.clear(); emit q->grabChanged(grabber, cancel ? QPointingDevice::CancelGrabExclusive : QPointingDevice::UngrabExclusive, nullptr, epd.eventPoint); } - int pi = epd.passiveGrabbers.indexOf(grabber); + qsizetype pi = epd.passiveGrabbers.indexOf(grabber); if (pi >= 0) { qCDebug(lcPointerGrab) << name << "point" << epd.eventPoint.id() << epd.eventPoint.state() << ": removing passive grabber" << grabber; epd.passiveGrabbers.removeAt(pi); + if (epd.passiveGrabbersContext.size()) { + Q_ASSERT(epd.passiveGrabbersContext.size() > pi); + epd.passiveGrabbersContext.removeAt(pi); + } emit q->grabChanged(grabber, cancel ? QPointingDevice::CancelGrabPassive : QPointingDevice::UngrabPassive, nullptr, epd.eventPoint); @@ -642,9 +680,9 @@ const QPointingDevice *QPointingDevicePrivate::tabletDevice(QInputDevice::Device << deviceType << pointerType << Qt::hex << uniqueId.numericId() << "The platform plugin should have provided one via " "QWindowSystemInterface::registerInputDevice(). Creating a default one for now."; - dev = new QPointingDevice(QLatin1String("fake tablet"), 2, deviceType, pointerType, - QInputDevice::Capability::Position | QInputDevice::Capability::Pressure, - 1, 1, QString(), uniqueId, QCoreApplication::instance()); + dev = new QPointingDevice("fake tablet"_L1, 2, deviceType, pointerType, + QInputDevice::Capability::Position | QInputDevice::Capability::Pressure, + 1, 1, QString(), uniqueId, QCoreApplication::instance()); QInputDevicePrivate::registerDevice(dev); } return dev; @@ -670,7 +708,7 @@ QDebug operator<<(QDebug debug, const QPointingDevice *device) if (device) { debug << '"' << device->name() << "\" "; QtDebugUtils::formatQEnum(debug, device->type()); - debug << " id=" << Qt::hex << device->systemId() << Qt::dec; + debug << " id=" << device->systemId(); if (!device->seatName().isEmpty()) debug << " seat=" << device->seatName(); if (device->pointerType() != QPointingDevice::PointerType::Generic) { @@ -781,3 +819,5 @@ size_t qHash(QPointingDeviceUniqueId key, size_t seed) noexcept } QT_END_NAMESPACE + +#include "moc_qpointingdevice.cpp" |