aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickevents.cpp483
-rw-r--r--src/quick/items/qquickevents_p_p.h42
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp4
-rw-r--r--src/quick/items/qquickloader.cpp10
-rw-r--r--src/quick/items/qquickrendercontrol.cpp4
-rw-r--r--src/quick/items/qquicktextcontrol.cpp3
-rw-r--r--src/quick/items/qquicktranslate.cpp1
-rw-r--r--src/quick/items/qquickwindow.cpp147
-rw-r--r--src/quick/items/qquickwindow_p.h3
11 files changed, 647 insertions, 58 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 90e72ebde6..8653d758de 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -40,6 +40,7 @@
#include "qquickevents_p_p.h"
#include <QtCore/qmap.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qtouchdevice_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickwindow_p.h>
@@ -447,7 +448,85 @@ Item {
\l inverted always returns false.
*/
-typedef QHash<QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
+/*!
+ \qmltype PointerDevice
+ \instantiates QQuickPointerDevice
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about a pointing device
+
+ A pointing device can be a mouse, a touchscreen, or a stylus on a graphics
+ tablet.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::type
+
+ This property holds the type of the pointing device.
+
+ Valid values are:
+
+ \value DeviceType.UnknownDevice
+ the device cannot be identified
+ \value DeviceType.Mouse
+ a mouse
+ \value DeviceType.TouchScreen
+ a touchscreen providing absolute coordinates
+ \value DeviceType.TouchPad
+ a trackpad or touchpad providing relative coordinates
+ \value DeviceType.Stylus
+ a pen-like device
+ \value DeviceType.Airbrush
+ a stylus with a thumbwheel to adjust
+ \l {QTabletEvent::tangentialPressure}{tangentialPressure}
+ \value DeviceType.Puck
+ a device that is similar to a flat mouse with a
+ transparent circle with cross-hairs (same as \l QTabletEvent::Puck)
+
+ \sa QTouchDevice::DeviceType
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::capabilities
+
+ This property holds a bitwise combination of the capabilities of the
+ pointing device. It tells you under which conditions events are sent,
+ and which properties of PointerEvent are expected to be valid.
+
+ Valid values are:
+
+ \value CapabilityFlag.Position
+ the \l {QtQuick::EventPoint::position}{position} and
+ \l {QtQuick::EventPoint::scenePosition}{scenePosition} properties
+ \value CapabilityFlag.Area
+ the \l {QtQuick::EventTouchPoint::ellipseDiameters}{ellipseDiameters} property
+ \value CapabilityFlag.Pressure
+ the \l {QtQuick::EventTouchPoint::pressure}{pressure} property
+ \value CapabilityFlag.Velocity
+ the \l {QtQuick::PointerEvent::velocity}{velocity} property
+ \value CapabilityFlag.Scroll
+ a \l {QtQuick::PointerDevice::DeviceType::Mouse}{Mouse} has a wheel, or the
+ operating system recognizes scroll gestures on a
+ \l {QtQuick::PointerDevice::DeviceType::TouchPad}{TouchPad}
+ \value CapabilityFlag.Hover
+ events are sent even when no button is pressed, or the finger or stylus
+ is not in contact with the surface
+ \value CapabilityFlag.Rotation
+ the \l {QtQuick::EventTouchPoint::rotation}{rotation} property
+ \value CapabilityFlag.XTilt
+ horizontal angle between a stylus and the axis perpendicular to the surface
+ \value CapabilityFlag.YTilt
+ vertical angle between a stylus and the axis perpendicular to the surface
+
+ \sa QTouchDevice::capabilities
+*/
+
+typedef QHash<const QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)
struct ConstructableQQuickPointerDevice : public QQuickPointerDevice
@@ -483,7 +562,7 @@ static const QString pointDeviceName(const QQuickEventPoint *point)
}
-QQuickPointerDevice *QQuickPointerDevice::touchDevice(QTouchDevice *d)
+QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d)
{
if (g_touchDevices->contains(d))
return g_touchDevices->value(d);
@@ -531,6 +610,118 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
return nullptr;
}
+/*!
+ \qmltype EventPoint
+ \qmlabstract
+ \instantiates QQuickEventPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual point within a PointerEvent
+
+ A PointerEvent contains an EventPoint for each point of contact: one corresponding
+ to the mouse cursor, or one for each finger touching a touchscreen.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::position
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the upper-left corner of the Item which has the PointerHandler.
+ If a contact patch is available from the pointing device, this point
+ represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePosition
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the scene. If a contact patch is available from the \l device,
+ this point represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePressPosition
+
+ This property holds the scene-relative position at which the press event
+ (on a touch device) or most recent change in QQuickPointerEvent::buttons()
+ (on a mouse or tablet stylus) occurred.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::sceneGrabPosition
+
+ This property holds the scene-relative position at which the EventPoint was
+ located when setGrabber() was called most recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty vector2d QtQuick::EventPoint::velocity
+
+ This property holds average recent velocity: how fast and in which
+ direction the event point has been moving recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::state
+
+ This property tells what the user is currently doing at this point.
+
+ It can be one of:
+ \value Pressed
+ The user's finger is now pressing a touchscreen, button or stylus
+ which was not pressed already
+ \value Updated
+ The touchpoint or position is being moved, with no change in pressed state
+ \value Stationary
+ The touchpoint or position is not being moved, and there is also
+ no change in pressed state
+ \value Released
+ The user's finger has now released a touch point, button or stylus
+ which was pressed
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::pointId
+
+ This property holds the ID of the event, if any.
+
+ Touchpoints have automatically-incrementing IDs: each time the user
+ presses a finger against the touchscreen, it will be a larger number.
+ In other cases, it will be -1.
+
+ \sa PointerDevice.uniqueId
+*/
+
+/*!
+ \readonly
+ \qmlproperty bool QtQuick::EventPoint::accepted
+
+ Setting \a accepted to true prevents the event from being propagated to
+ Items below the PointerHandler's Item.
+
+ Generally, if the handler acts on the mouse event, then it should be
+ accepted so that items lower in the stacking order do not also respond to
+ the same event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty real QtQuick::EventPoint::timeHeld
+
+ This property holds the amount of time in seconds that the button or touchpoint has
+ been held. It can be used to detect a "long press", and can drive an
+ animation to show progress toward activation of the "long press" action.
+*/
+
void QQuickEventPoint::reset(Qt::TouchPointState state, const QPointF &scenePos, int pointId, ulong timestamp, const QVector2D &velocity)
{
m_scenePos = scenePos;
@@ -761,10 +952,15 @@ void QQuickEventPoint::cancelAllGrabs(QQuickPointerHandler *handler)
}
/*!
- Set this point as \a accepted (true) or rejected (false).
- Accepting a point is intended to stop event propagation.
- It does not imply any kind of grab, passive or exclusive.
- TODO explain further under what conditions propagation really does stop...
+ Sets this point as \a accepted (true) or rejected (false).
+
+ During delivery of the current event to the Items in the scene, each Item
+ or Pointer Handler should accept the points for which it is taking
+ responsibility. As soon as all points within the event are accepted, event
+ propagation stops. However accepting the point does not imply any kind of
+ grab, passive or exclusive.
+
+ \sa setExclusiveGrabber, QQuickPointerHandler::setPassiveGrab, QQuickPointerHandler::setExclusiveGrab
*/
void QQuickEventPoint::setAccepted(bool accepted)
{
@@ -774,6 +970,86 @@ void QQuickEventPoint::setAccepted(bool accepted)
}
}
+
+/*!
+ \qmltype EventTouchPoint
+ \qmlabstract
+ \instantiates QQuickEventTouchPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual touch point within a PointerEvent
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointerUniqueId QtQuick::EventTouchPoint::uniqueId
+
+ This property holds the unique ID of the fiducial or stylus in use, if any.
+
+ On touchscreens that can track physical objects (such as knobs or game
+ pieces) in addition to fingers, each object usually has a unique ID.
+ Likewise, each stylus that can be used with a graphics tablet usually has a
+ unique serial number. Qt so far only supports numeric IDs. You can get the
+ actual number as uniqueId.numeric, but that is a device-specific detail.
+ In the future, there may be support for non-numeric IDs, so you should
+ not assume that the number is meaningful.
+
+ If you need to identify specific objects, your application should provide
+ UI for registering objects and mapping them to functionality: allow the
+ user to select a meaning, virtual tool, or action, prompt the user to bring
+ the object into proximity, and store a mapping from uniqueId to its
+ purpose, for example in \l Settings.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::rotation
+
+ This property holds the rotation angle of the stylus on a graphics tablet
+ or the contact patch of a touchpoint on a touchscreen.
+
+ It is valid only with certain tablet stylus devices and touchscreens that
+ can measure the rotation angle. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::pressure
+
+ This property tells how hard the user is pressing the stylus on a graphics
+ tablet or the finger against a touchscreen, in the range from \c 0 (no
+ measurable pressure) to \c 1.0 (maximum pressure which the device can
+ measure).
+
+ It is valid only with certain tablets and touchscreens that can measure
+ pressure. Otherwise, it will be \c 1.0 when pressed.
+*/
+
+/*!
+ \readonly
+ \qmlproperty size QtQuick::EventTouchPoint::ellipseDiameters
+
+ This property holds the diameters of the contact patch, if the event
+ comes from a touchpoint and the \l device provides this information.
+
+ A touchpoint is modeled as an elliptical area where the finger is pressed
+ against the touchscreen. (In fact, it could also be modeled as a bitmap; but
+ in that case we expect an elliptical bounding estimate to be fitted to the
+ contact patch before the event is sent.) The harder the user presses, the
+ larger the contact patch; so, these diameters provide an alternate way of
+ detecting pressure, in case the device does not include a separate pressure
+ sensor. The ellipse is centered on \l scenePos (\l pos in the PointerHandler's
+ Item's local coordinates). The \l rotation property provides the
+ rotation of the ellipse, if known. It is expected that if the \l rotation
+ is zero, the verticalDiameter of the ellipse is the larger one (the major axis),
+ because of the usual hand position, reaching upward or outward across the surface.
+
+ If the contact patch is unknown, or the \l device is not a touchscreen,
+ these values will be zero.
+*/
+
QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent)
: QQuickEventPoint(parent), m_rotation(0), m_pressure(0)
{}
@@ -846,6 +1122,24 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
}
/*!
+ \qmltype PointerEvent
+ \instantiates QQuickPointerEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about an event from a pointing device
+
+ A PointerEvent is an event describing contact or movement across a surface,
+ provided by a mouse, a touchpoint (single finger on a touchscreen), or a
+ stylus on a graphics tablet. The \l device property provides more
+ information about where the event came from.
+
+ \sa PointerHandler
+
+ \image touchpoint-metrics.png
+*/
+
+/*!
\internal
\class QQuickPointerEvent
@@ -859,6 +1153,68 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
dynamically create and destroy objects of this type for each event.
*/
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerEvent::button
+
+ This property holds the \l {Qt::MouseButton}{button} that caused the event,
+ if any. If the \l device does not have buttons, or the event is a hover
+ event, it will be \c Qt.NoButton.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::buttons
+
+ This property holds the combination of mouse or stylus
+ \l {Qt::MouseButton}{buttons} pressed when the event was generated. For move
+ events, this is all buttons that are pressed down. For press events, this
+ includes the button that caused the event, as well as any others that were
+ already held. For release events, this excludes the button that caused the
+ event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::modifiers
+
+ This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} flags
+ that existed immediately before the event occurred.
+
+ It contains a bitwise combination of the following flags:
+ \value Qt.NoModifier
+ No modifier key is pressed.
+ \value Qt.ShiftModifier
+ A Shift key on the keyboard is pressed.
+ \value Qt.ControlModifier
+ A Ctrl key on the keyboard is pressed.
+ \value Qt.AltModifier
+ An Alt key on the keyboard is pressed.
+ \value Qt.MetaModifier
+ A Meta key on the keyboard is pressed.
+ \value Qt.KeypadModifier
+ A keypad button is pressed.
+
+ For example, to react to a Shift key + Left mouse button click:
+ \qml
+ Item {
+ TapHandler {
+ onTapped: {
+ if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
+ doSomething();
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::PointerEvent::device
+
+ This property holds the device that generated the event.
+*/
+
QQuickPointerEvent::~QQuickPointerEvent()
{}
@@ -975,6 +1331,36 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
point->localizePosition(target);
}
+QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QNativeGestureEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ m_device = QQuickPointerDevice::touchDevice(ev->device());
+ m_device->eventDeliveryTargets().clear();
+ Qt::TouchPointState state = Qt::TouchPointMoved;
+ switch (type()) {
+ case Qt::BeginNativeGesture:
+ state = Qt::TouchPointPressed;
+ break;
+ case Qt::EndNativeGesture:
+ state = Qt::TouchPointReleased;
+ break;
+ default:
+ break;
+ }
+ quint64 deviceId = QTouchDevicePrivate::get(const_cast<QTouchDevice *>(ev->device()))->id; // a bit roundabout since QTouchDevice::mTouchDeviceId is protected
+ m_gesturePoint->reset(state, ev->windowPos(), deviceId << 24, ev->timestamp());
+ return this;
+}
+
+void QQuickPointerNativeGestureEvent::localize(QQuickItem *target)
+{
+ m_gesturePoint->localizePosition(target);
+}
+
QQuickEventPoint *QQuickPointerMouseEvent::point(int i) const {
if (i == 0)
return m_mousePoint;
@@ -987,6 +1373,12 @@ QQuickEventPoint *QQuickPointerTouchEvent::point(int i) const {
return nullptr;
}
+QQuickEventPoint *QQuickPointerNativeGestureEvent::point(int i) const {
+ if (i == 0)
+ return m_gesturePoint;
+ return nullptr;
+}
+
QQuickEventPoint::QQuickEventPoint(QQuickPointerEvent *parent)
: QObject(parent), m_pointId(0), m_exclusiveGrabber(nullptr), m_timestamp(0), m_pressTimestamp(0),
m_state(QQuickEventPoint::Released), m_accept(false), m_grabberIsHandler(false)
@@ -1068,7 +1460,7 @@ bool QQuickPointerMouseEvent::isUpdateEvent() const
bool QQuickPointerMouseEvent::isReleaseEvent() const
{
auto me = static_cast<QMouseEvent*>(m_event);
- return me->type() == QEvent::MouseButtonRelease;
+ return me && me->type() == QEvent::MouseButtonRelease;
}
bool QQuickPointerTouchEvent::allPointsAccepted() const {
@@ -1207,6 +1599,64 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
}
/*!
+ Returns the exclusive grabber of this event, if any, in a vector.
+*/
+QVector<QObject *> QQuickPointerNativeGestureEvent::exclusiveGrabbers() const
+{
+ QVector<QObject *> result;
+ if (QObject *grabber = m_gesturePoint->exclusiveGrabber())
+ result << grabber;
+ return result;
+}
+
+/*!
+ Remove all passive and exclusive grabbers of this event, without notifying.
+*/
+void QQuickPointerNativeGestureEvent::clearGrabbers() const {
+ m_gesturePoint->setGrabberItem(nullptr);
+ m_gesturePoint->clearPassiveGrabbers();
+}
+
+/*!
+ Returns whether the given \a handler is the exclusive grabber of this event.
+*/
+bool QQuickPointerNativeGestureEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
+{
+ return m_gesturePoint->exclusiveGrabber() == handler;
+}
+
+bool QQuickPointerNativeGestureEvent::isPressEvent() const
+{
+ return type() == Qt::BeginNativeGesture;
+}
+
+bool QQuickPointerNativeGestureEvent::isUpdateEvent() const
+{
+ switch (type()) {
+ case Qt::BeginNativeGesture:
+ case Qt::EndNativeGesture:
+ return false;
+ default:
+ return true;
+ }
+}
+
+bool QQuickPointerNativeGestureEvent::isReleaseEvent() const
+{
+ return type() == Qt::EndNativeGesture;
+}
+
+Qt::NativeGestureType QQuickPointerNativeGestureEvent::type() const
+{
+ return static_cast<QNativeGestureEvent *>(m_event)->gestureType();
+}
+
+qreal QQuickPointerNativeGestureEvent::value() const
+{
+ return static_cast<QNativeGestureEvent *>(m_event)->value();
+}
+
+/*!
\internal
Returns a pointer to the QQuickEventPoint which has the \a pointId as
\l {QQuickEventPoint::pointId}{pointId}.
@@ -1228,6 +1678,12 @@ QQuickEventPoint *QQuickPointerTouchEvent::pointById(int pointId) const {
return nullptr;
}
+QQuickEventPoint *QQuickPointerNativeGestureEvent::pointById(int pointId) const {
+ if (m_gesturePoint && pointId == m_gesturePoint->pointId())
+ return m_gesturePoint;
+ return nullptr;
+}
+
/*!
\internal
@@ -1346,6 +1802,19 @@ QTouchEvent *QQuickPointerTouchEvent::asTouchEvent() const
return static_cast<QTouchEvent *>(m_event);
}
+bool QQuickPointerNativeGestureEvent::allPointsAccepted() const {
+ return m_gesturePoint->isAccepted();
+}
+
+bool QQuickPointerNativeGestureEvent::allUpdatedPointsAccepted() const {
+ return m_gesturePoint->state() == QQuickEventPoint::Pressed || m_gesturePoint->isAccepted();
+}
+
+bool QQuickPointerNativeGestureEvent::allPointsGrabbed() const
+{
+ return m_gesturePoint->exclusiveGrabber() != nullptr;
+}
+
#ifndef QT_NO_DEBUG_STREAM
Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerDevice *dev) {
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 2954695b1b..09a63febdc 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -66,6 +66,7 @@ QT_BEGIN_NAMESPACE
class QQuickPointerDevice;
class QQuickPointerEvent;
class QQuickPointerMouseEvent;
+class QQuickPointerNativeGestureEvent;
class QQuickPointerTabletEvent;
class QQuickPointerTouchEvent;
class QQuickPointerHandler;
@@ -270,7 +271,6 @@ public:
Updated = Qt::TouchPointMoved,
Stationary = Qt::TouchPointStationary,
Released = Qt::TouchPointReleased
- // Canceled = Qt::TouchPointReleased << 1 // 0x10 // TODO maybe
};
Q_DECLARE_FLAGS(States, State)
Q_FLAG(States)
@@ -414,9 +414,11 @@ public: // helpers for C++ only (during event delivery)
virtual QQuickPointerMouseEvent *asPointerMouseEvent() { return nullptr; }
virtual QQuickPointerTouchEvent *asPointerTouchEvent() { return nullptr; }
virtual QQuickPointerTabletEvent *asPointerTabletEvent() { return nullptr; }
+ virtual QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() { return nullptr; }
virtual const QQuickPointerMouseEvent *asPointerMouseEvent() const { return nullptr; }
virtual const QQuickPointerTouchEvent *asPointerTouchEvent() const { return nullptr; }
virtual const QQuickPointerTabletEvent *asPointerTabletEvent() const { return nullptr; }
+ virtual const QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() const { return nullptr; }
virtual bool allPointsAccepted() const = 0;
virtual bool allUpdatedPointsAccepted() const = 0;
virtual bool allPointsGrabbed() const = 0;
@@ -516,6 +518,42 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickPointerEvent
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::NativeGestureType type READ type CONSTANT)
+ Q_PROPERTY(qreal value READ value CONSTANT)
+
+public:
+ QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
+ : QQuickPointerEvent(parent, device), m_gesturePoint(new QQuickEventPoint(this)) { }
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ void localize(QQuickItem *target) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() override { return this; }
+ const QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() const override { return this; }
+ int pointCount() const override { return 1; }
+ QQuickEventPoint *point(int i) const override;
+ QQuickEventPoint *pointById(int pointId) const override;
+ bool allPointsAccepted() const override;
+ bool allUpdatedPointsAccepted() const override;
+ bool allPointsGrabbed() const override;
+ QVector<QObject *> exclusiveGrabbers() const override;
+ void clearGrabbers() const override;
+ bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
+ Qt::NativeGestureType type() const;
+ qreal value() const;
+
+private:
+ QQuickEventPoint *m_gesturePoint;
+
+ Q_DISABLE_COPY(QQuickPointerNativeGestureEvent)
+};
+
+
// ### Qt 6: move this to qtbase, replace QTouchDevice and the enums in QTabletEvent
class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
{
@@ -580,7 +618,7 @@ public:
QString name() const { return m_name; }
QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
- static QQuickPointerDevice *touchDevice(QTouchDevice *d);
+ static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
static QQuickPointerDevice *tabletDevice(qint64);
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 993d622087..6579175cc6 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -122,6 +122,7 @@ void debugFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1)
\li \l Rotation
\li \l Scale
\li \l Translate
+ \li \l Matrix4x4
\endlist
The Transform types let you create and control advanced transformations that can be configured
@@ -7972,6 +7973,11 @@ QQuickItemLayer *QQuickItemPrivate::layer() const
#endif
}
+bool QQuickItemPrivate::hasPointerHandlers() const
+{
+ return extra.isAllocated() && !extra->pointerHandlers.isEmpty();
+}
+
#if QT_CONFIG(quick_shadereffect)
QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
: m_item(item)
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 387ce326c2..9ed5286f22 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -279,6 +279,8 @@ public:
QQuickItemLayer *layer() const;
+ bool hasPointerHandlers() const;
+
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
static int data_count(QQmlListProperty<QObject> *);
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 3c87496c83..869fdeadc8 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -402,6 +402,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
qmlRegisterType<QQuickTextEdit, 10>(uri, 2, 10, "TextEdit");
qmlRegisterType<QQuickText, 10>(uri, 2, 10, "Text");
+
+#if QT_CONFIG(quick_path)
+ qmlRegisterType<QQuickPathAngleArc, 2>(uri, 2, 11, "PathAngleArc");
+#endif
}
static void initResources()
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 9f27beb298..27afe5a5db 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -852,6 +852,7 @@ qreal QQuickLoader::progress() const
\qmlproperty bool QtQuick::Loader::asynchronous
This property holds whether the component will be instantiated asynchronously.
+By default it is \c false.
When used in conjunction with the \l source property, loading and compilation
will also be performed in a background thread.
@@ -915,9 +916,14 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
if (!item)
return;
- if (loaderGeometryChanged && q->widthValid())
+ const bool needToUpdateWidth = loaderGeometryChanged && q->widthValid();
+ const bool needToUpdateHeight = loaderGeometryChanged && q->heightValid();
+
+ if (needToUpdateWidth && needToUpdateHeight)
+ item->setSize(QSizeF(q->width(), q->height()));
+ else if (needToUpdateWidth)
item->setWidth(q->width());
- if (loaderGeometryChanged && q->heightValid())
+ else if (needToUpdateHeight)
item->setHeight(q->height());
if (updatingSize)
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 7e995936af..58b76fa862 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -393,6 +393,8 @@ QImage QQuickRenderControl::grab()
#endif
} else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->polishItems();
+ cd->syncSceneGraph();
QSGSoftwareRenderer *softwareRenderer = static_cast<QSGSoftwareRenderer *>(cd->renderer);
if (softwareRenderer) {
const qreal dpr = d->window->effectiveDevicePixelRatio();
@@ -402,8 +404,6 @@ QImage QQuickRenderControl::grab()
QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
softwareRenderer->setCurrentPaintDevice(&grabContent);
softwareRenderer->markDirty();
- cd->polishItems();
- cd->syncSceneGraph();
d->rc->endSync();
render();
softwareRenderer->setCurrentPaintDevice(prevDev);
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 2e23d69e5b..874c02fc99 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -432,6 +432,7 @@ void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /
#endif
emit q->selectionChanged();
}
+ q->updateCursorRectangle(true);
}
void QQuickTextControlPrivate::_q_updateCurrentCharFormatAndSelection()
@@ -1150,7 +1151,6 @@ void QQuickTextControlPrivate::mouseMoveEvent(QMouseEvent *e, const QPointF &mou
if (interactionFlags & Qt::TextEditable) {
if (cursor.position() != oldCursorPos) {
emit q->cursorPositionChanged();
- q->updateCursorRectangle(true);
}
_q_updateCurrentCharFormatAndSelection();
#if QT_CONFIG(im)
@@ -1159,7 +1159,6 @@ void QQuickTextControlPrivate::mouseMoveEvent(QMouseEvent *e, const QPointF &mou
#endif
} else if (cursor.position() != oldCursorPos) {
emit q->cursorPositionChanged();
- q->updateCursorRectangle(true);
}
selectionChanged(true);
repaintOldAndNewSelection(oldSelection);
diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp
index 9937c692a5..1c8dd02b92 100644
--- a/src/quick/items/qquicktranslate.cpp
+++ b/src/quick/items/qquicktranslate.cpp
@@ -467,6 +467,7 @@ public:
\instantiates QQuickMatrix4x4
\inqmlmodule QtQuick
\ingroup qtquick-visual-transforms
+ \since 5.3
\brief Provides a way to apply a 4x4 tranformation matrix to an \l Item
The Matrix4x4 type provides a way to apply a transformation to an
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 3dfc1295fb..caae188ed8 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1644,10 +1644,15 @@ void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
{
- Q_Q(QQuickWindow);
-
- if (activeFocusItem)
- q->sendEvent(activeFocusItem, e);
+ if (activeFocusItem) {
+ QQuickItem *item = activeFocusItem;
+ e->accept();
+ QCoreApplication::sendEvent(item, e);
+ while (!e->isAccepted() && (item = item->parentItem())) {
+ e->accept();
+ QCoreApplication::sendEvent(item, e);
+ }
+ }
}
QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos)
@@ -1664,6 +1669,36 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t
return me;
}
+void QQuickWindowPrivate::deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers,
+ QQuickPointerEvent *pointerEvent)
+{
+ const QVector<QQuickPointerHandler *> &eventDeliveryTargets = pointerEvent->device()->eventDeliveryTargets();
+ QVarLengthArray<QPair<QQuickItem *, bool>, 4> sendFilteredPointerEventResult;
+ for (auto handler : passiveGrabbers) {
+ // a null pointer in passiveGrabbers is unlikely, unless the grabbing handler was deleted dynamically
+ if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) {
+ bool alreadyFiltered = false;
+ QQuickItem *par = handler->parentItem();
+
+ // see if we already have sent a filter event to the parent
+ auto it = std::find_if(sendFilteredPointerEventResult.begin(), sendFilteredPointerEventResult.end(),
+ [par](const QPair<QQuickItem *, bool> &pair) { return pair.first == par; });
+ if (it != sendFilteredPointerEventResult.end()) {
+ // Yes, the event was already filtered to that parent, do not call it again but use
+ // the result of the previous call to determine if we should call the handler.
+ alreadyFiltered = it->second;
+ } else {
+ alreadyFiltered = sendFilteredPointerEvent(pointerEvent, par);
+ sendFilteredPointerEventResult << qMakePair<QQuickItem*, bool>(par, alreadyFiltered);
+ }
+ if (!alreadyFiltered)
+ handler->handlePointerEvent(pointerEvent);
+ }
+ }
+}
+
+
+
void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent)
{
auto point = pointerEvent->point(0);
@@ -1712,14 +1747,8 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven
// if this is an update or release from an actual mouse,
// and the point wasn't grabbed, deliver only to PointerHandlers:
// passive grabbers first, then the rest
- const QVector<QQuickPointerHandler *> &eventDeliveryTargets = pointerEvent->device()->eventDeliveryTargets();
- for (auto handler : point->passiveGrabbers()) {
- // a null pointer in passiveGrabbers is unlikely, unless the grabbing handler was deleted dynamically
- if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) {
- if (!sendFilteredPointerEvent(pointerEvent, handler->parentItem()))
- handler->handlePointerEvent(pointerEvent);
- }
- }
+ deliverToPassiveGrabbers(point->passiveGrabbers(), pointerEvent);
+
// If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order
if (!pointerEvent->allPointsGrabbed() && pointerEvent->buttons()) {
QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePosition(), false, false);
@@ -1740,9 +1769,6 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven
// make sure not to accept unhandled events
pointerEvent->setAccepted(false);
}
- // failsafe: never allow any kind of grab to persist after release
- if (mouseIsReleased)
- pointerEvent->clearGrabbers();
}
bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
@@ -1915,10 +1941,20 @@ bool QQuickWindowPrivate::deliverNativeGestureEvent(QQuickItem *item, QNativeGes
return true;
}
- QPointF p = item->mapFromScene(event->localPos());
+ // Try the Item's pointer handlers first
+ QQuickPointerEvent *pointerEvent = pointerEventInstance(event);
+ pointerEvent->localize(item);
+ if (itemPrivate->handlePointerEvent(pointerEvent, false)) {
+ if (pointerEvent->allPointsAccepted()) {
+ event->accept();
+ return true;
+ }
+ }
+ // If still not accepted, try direct delivery to the item
+ QPointF p = item->mapFromScene(event->localPos());
if (item->contains(p)) {
- QNativeGestureEvent copy(event->gestureType(), p, event->windowPos(), event->screenPos(),
+ QNativeGestureEvent copy(event->gestureType(), event->device(), p, event->windowPos(), event->screenPos(),
event->value(), 0L, 0L); // TODO can't copy things I can't access
event->accept();
item->event(&copy);
@@ -2164,23 +2200,36 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents()
}
}
-QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device) const
+QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const
{
- // the list of devices should be very small so a linear search should be ok
- for (QQuickPointerEvent *e: pointerEventInstances) {
+ // Search for a matching reusable event object.
+ for (QQuickPointerEvent *e : pointerEventInstances) {
+ // If device can generate native gestures (e.g. a trackpad), there might be two QQuickPointerEvents:
+ // QQuickPointerNativeGestureEvent and QQuickPointerTouchEvent. Use eventType to disambiguate.
+ if (eventType == QEvent::NativeGesture && !qobject_cast<QQuickPointerNativeGestureEvent*>(e))
+ continue;
+ // Otherwise we assume there's only one event type per device.
+ // More disambiguation tests might need to be added above if that changes later.
if (e->device() == device)
return e;
}
+ // Not found: we have to create a suitable event instance.
QQuickPointerEvent *ev = nullptr;
QQuickWindow *q = const_cast<QQuickWindow*>(q_func());
switch (device->type()) {
case QQuickPointerDevice::Mouse:
+ // QWindowSystemInterface::handleMouseEvent() does not take a device parameter:
+ // we assume all mouse events come from one mouse (the "core pointer").
+ // So when the event is a mouse event, device == QQuickPointerDevice::genericMouseDevice()
ev = new QQuickPointerMouseEvent(q, device);
break;
case QQuickPointerDevice::TouchPad:
case QQuickPointerDevice::TouchScreen:
- ev = new QQuickPointerTouchEvent(q, device);
+ if (eventType == QEvent::NativeGesture)
+ ev = new QQuickPointerNativeGestureEvent(q, device);
+ else // assume QEvent::Type is one of TouchBegin/Update/End
+ ev = new QQuickPointerTouchEvent(q, device);
break;
default:
// TODO tablet event types
@@ -2200,29 +2249,29 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) const
{
QQuickPointerDevice *dev = nullptr;
- QQuickPointerEvent *ev = nullptr;
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
dev = QQuickPointerDevice::genericMouseDevice();
- ev = pointerEventInstance(dev);
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
- ev = pointerEventInstance(dev);
break;
// TODO tablet event types
+ case QEvent::NativeGesture:
+ dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
+ break;
default:
break;
}
- Q_ASSERT(ev);
- return ev->reset(event);
+ Q_ASSERT(dev);
+ return pointerEventInstance(dev, event->type())->reset(event);
}
void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
@@ -2235,6 +2284,9 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
skipDelivery.clear();
if (event->asPointerMouseEvent()) {
deliverMouseEvent(event->asPointerMouseEvent());
+ // failsafe: never allow any kind of grab to persist after release
+ if (event->isReleaseEvent() && event->buttons() == Qt::NoButton)
+ event->clearGrabbers();
} else if (event->asPointerTouchEvent()) {
deliverTouchEvent(event->asPointerTouchEvent());
} else {
@@ -2273,10 +2325,12 @@ QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, cons
}
bool relevant = item->contains(itemPos);
- if (relevant && checkMouseButtons && item->acceptedMouseButtons() == Qt::NoButton)
- relevant = false;
- if (relevant && checkAcceptsTouch && !(item->acceptTouchEvents() || item->acceptedMouseButtons()))
- relevant = false;
+ if (!(itemPrivate->hasPointerHandlers())) {
+ if (relevant && checkMouseButtons && item->acceptedMouseButtons() == Qt::NoButton)
+ relevant = false;
+ if (relevant && checkAcceptsTouch && !(item->acceptTouchEvents() || item->acceptedMouseButtons()))
+ relevant = false;
+ }
if (relevant)
targets << item; // add this item last: children take precedence
return targets;
@@ -2368,16 +2422,9 @@ void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *eve
int pointCount = event->pointCount();
// Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once)
- const QVector<QQuickPointerHandler *> &eventDeliveryTargets = event->device()->eventDeliveryTargets();
for (int i = 0; i < pointCount; ++i) {
QQuickEventPoint *point = event->point(i);
- for (auto handler : point->passiveGrabbers()) {
- if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) {
- if (sendFilteredPointerEvent(event, handler->parentItem()))
- return;
- handler->handlePointerEvent(event);
- }
- }
+ deliverToPassiveGrabbers(point->passiveGrabbers(), event);
}
// If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order
@@ -2740,10 +2787,24 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (receiver->acceptedMouseButtons()) {
QPointF localPos = receiver->mapFromScene(pme->point(0)->scenePosition());
QMouseEvent *me = pme->asMouseEvent(localPos);
+ const bool wasAccepted = me->isAccepted();
+ me->setAccepted(true);
+ auto oldMouseGrabber = pme->point(0)->grabberItem();
if (filteringParent->childMouseEventFilter(receiver, me)) {
qCDebug(DBG_MOUSE) << "mouse event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
filtered = true;
+ if (me->isAccepted() && pme->isPressEvent()) {
+ auto mouseGrabber = pme->point(0)->grabberItem();
+ if (mouseGrabber && mouseGrabber != receiver && mouseGrabber != oldMouseGrabber) {
+ receiver->mouseUngrabEvent();
+ } else {
+ pme->point(0)->setGrabberItem(receiver);
+ }
+ }
+ } else {
+ // Restore accepted state if the event was not filtered.
+ me->setAccepted(wasAccepted);
}
}
} else if (QQuickPointerTouchEvent *pte = event->asPointerTouchEvent()) {
@@ -2755,13 +2816,12 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
#endif
if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
// get a touch event customized for delivery to filteringParent
- QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(filteringParent, true));
+ QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true));
if (filteringParentTouchEvent) {
QVarLengthArray<QPair<QQuickPointerHandler *, QQuickEventPoint *>, 32> passiveGrabsToCancel;
if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) {
qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent;
skipDelivery.append(filteringParent);
- filteringParent->grabMouse();
for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) {
auto pointerEventPoint = pte->pointById(point.id());
for (auto handler : pointerEventPoint->passiveGrabbers()) {
@@ -2769,7 +2829,9 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
if (!passiveGrabsToCancel.contains(grab))
passiveGrabsToCancel.append(grab);
}
- event->pointById(point.id())->setAccepted();
+ QQuickEventPoint *pt = event->pointById(point.id());
+ pt->setAccepted();
+ pt->setGrabberItem(filteringParent);
}
return true;
} else {
@@ -2810,7 +2872,8 @@ bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event
qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
pointerEventInstance(touchMouseDevice)->pointById(tp.id())->setGrabberItem(filteringParent);
touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
- filteringParent->grabMouse();
+ if (mouseEvent->isAccepted())
+ filteringParent->grabMouse();
auto pointerEventPoint = pte->pointById(tp.id());
for (auto handler : pointerEventPoint->passiveGrabbers()) {
QPair<QQuickPointerHandler *, QQuickEventPoint *> grab(handler, pointerEventPoint);
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index c636719258..06891406ab 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -146,6 +146,7 @@ public:
void grabTouchPoints(QObject *grabber, const QVector<int> &ids);
void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true);
static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0);
+ void deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers, QQuickPointerEvent *pointerEvent);
void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent);
bool sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent);
bool sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent = nullptr);
@@ -166,7 +167,7 @@ public:
// the device-specific event instances which are reused during event delivery
mutable QVector<QQuickPointerEvent *> pointerEventInstances;
- QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device) const;
+ QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType = QEvent::None) const;
// delivery of pointer events:
QQuickPointerEvent *pointerEventInstance(QEvent *ev) const;