Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickdeliveryagent_p_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QQUICKDELIVERYAGENT_P_P_H
6#define QQUICKDELIVERYAGENT_P_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick/private/qquickdeliveryagent_p.h>
20#include <QtGui/qevent.h>
21#include <QtCore/qstack.h>
22#include <QtCore/qxpfunctional.h>
23
24#include <private/qevent_p.h>
25#include <private/qpointingdevice_p.h>
26
27#include <QtCore/qpointer.h>
28#include <private/qobject_p.h>
29
30#include <memory>
31
32QT_BEGIN_NAMESPACE
33
34class QQuickDragGrabber;
35class QQuickItem;
36class QQuickPointerHandler;
37class QQuickWindow;
38
39/*! \internal
40 Extra device-specific data to be stored in QInputDevicePrivate::qqExtra.
41
42 \c deliveryTargets is a list of objects that have already been visited
43 during event delivery:
44 - QQuickPointerHandlerPrivate::deviceDeliveryTargets() returns the whole
45 list by reference
46 - QQuickPointerHandler::handlePointerEvent() appends to it
47 - QQuickItemPrivate::handlePointerEvent() checks it to prevent delivery to
48 the same handler multiple times
49*/
53
54class Q_QUICK_EXPORT QQuickDeliveryAgentPrivate : public QObjectPrivate
55{
56public:
57 Q_DECLARE_PUBLIC(QQuickDeliveryAgent)
58 QQuickDeliveryAgentPrivate(QQuickItem *root);
59 ~QQuickDeliveryAgentPrivate();
60
61 QQuickItem *rootItem = nullptr;
62
63 QQuickItem *activeFocusItem = nullptr;
64
65 void deliverKeyEvent(QKeyEvent *e);
66
67 enum FocusOption {
68 DontChangeFocusProperty = 0x01,
69 DontChangeSubFocusItem = 0x02
70 };
71 Q_DECLARE_FLAGS(FocusOptions, FocusOption)
72
73 void setFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
74 void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason, FocusOptions = { });
75 static void notifyFocusChangesRecur(QQuickItem **item, int remaining, Qt::FocusReason reason);
76 void clearFocusObject();
77 void updateFocusItemTransform();
78
79 QQuickItem *focusTargetItem() const;
80
81 // Keeps track of the item currently receiving mouse events
82#if QT_CONFIG(quick_draganddrop)
83 QQuickDragGrabber *dragGrabber = nullptr;
84#endif
85 QQuickItem *lastUngrabbed = nullptr;
86 QStack<QPointerEvent *> eventsInDelivery;
87 QFlatMap<QPointer<QQuickItem>, uint> hoverItems;
88 QVector<QQuickItem *> hasFiltered; // during event delivery to a single receiver, the filtering parents for which childMouseEventFilter was already called
89 QVector<QQuickItem *> skipDelivery; // during delivery of one event to all receivers, Items to which we know delivery is no longer necessary
90
91 std::unique_ptr<QMutableTouchEvent> delayedTouch;
92 QList<const QPointingDevice *> knownPointingDevices;
93
94 uint currentHoverId = 0;
95#if QT_CONFIG(wheelevent)
96 uint lastWheelEventAccepted = 0;
97#endif
98 uchar compressedTouchCount = 0;
99 bool allowChildEventFiltering = true;
100 bool frameSynchronousHoverEnabled = true;
101 bool hoveredLeafItemFound = false;
102
103 bool isSubsceneAgent = false;
104 static bool subsceneAgentsExist;
105 // QQuickDeliveryAgent::event() sets this to the one that's currently (trying to) handle the event
106 static QQuickDeliveryAgent *currentEventDeliveryAgent;
107 static QQuickDeliveryAgent *currentOrItemDeliveryAgent(const QQuickItem *item);
108
109 Qt::FocusReason lastFocusReason = Qt::OtherFocusReason;
110 int pointerEventRecursionGuard = 0;
111
112 int touchMouseId = -1; // only for obsolete stuff like QQuickItem::grabMouse()
113 // TODO get rid of these
114 const QPointingDevice *touchMouseDevice = nullptr;
115 ulong touchMousePressTimestamp = 0;
116 QPoint touchMousePressPos; // in screen coordinates
117
118 QQuickDeliveryAgent::Transform *sceneTransform = nullptr;
119
120 bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; }
121 void cancelTouchMouseSynthesis();
122
123 bool checkIfDoubleTapped(ulong newPressEventTimestamp, const QPoint &newPressPos);
124 void resetIfDoubleTapPrevented(const QEventPoint &pressedPoint);
125 QPointingDevicePrivate::EventPointData *mousePointData();
126 QPointerEvent *eventInDelivery() const;
127
128 // Mouse positions are saved in widget coordinates
129 QPointF lastMousePosition;
130 bool deliverTouchAsMouse(QQuickItem *item, QTouchEvent *pointerEvent);
131 static void translateTouchEvent(QTouchEvent *touchEvent);
132 void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true, bool cancel = false);
133 void clearGrabbers(QPointerEvent *pointerEvent);
134 void onGrabChanged(QObject *grabber, QPointingDevice::GrabTransition transition, const QPointerEvent *event, const QEventPoint &point);
135 static QPointerEvent *clonePointerEvent(QPointerEvent *event, std::optional<QPointF> transformedLocalPos = std::nullopt);
136 void deliverToPassiveGrabbers(const QVector<QPointer<QObject> > &passiveGrabbers, QPointerEvent *pointerEvent);
137 bool sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent);
138 bool sendFilteredPointerEvent(QPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent = nullptr);
139 bool sendFilteredPointerEventImpl(QPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent);
140 bool deliverSinglePointEventUntilAccepted(QPointerEvent *);
141
142 // entry point of events to the window
143 void handleTouchEvent(QTouchEvent *);
144 void handleMouseEvent(QMouseEvent *);
145 bool compressTouchEvent(QTouchEvent *);
146 void flushFrameSynchronousEvents(QQuickWindow *win);
147 void deliverDelayedTouchEvent();
148 void handleWindowDeactivate(QQuickWindow *win);
149 void handleWindowHidden(QQuickWindow *win);
150
151 // utility functions that used to be in QQuickPointerEvent et al.
152 bool allUpdatedPointsAccepted(const QPointerEvent *ev);
153 static void localizePointerEvent(QPointerEvent *ev, const QQuickItem *dest);
154 QList<QObject *> exclusiveGrabbers(QPointerEvent *ev);
155 static bool anyPointGrabbed(const QPointerEvent *ev);
156 static bool allPointsGrabbed(const QPointerEvent *ev);
157 static bool isMouseEvent(const QPointerEvent *ev);
158 static bool isMouseOrWheelEvent(const QPointerEvent *ev);
159 static bool isHoverEvent(const QPointerEvent *ev);
160 static bool isHoveringMoveEvent(const QPointerEvent *ev);
161 static bool isTouchEvent(const QPointerEvent *ev);
162 static bool isTabletEvent(const QPointerEvent *ev);
163 static bool isEventFromMouseOrTouchpad(const QPointerEvent *ev);
164 static bool isSynthMouse(const QPointerEvent *ev);
165 static bool isWithinDoubleClickInterval(ulong timeInterval);
166 static bool isWithinDoubleTapDistance(const QPoint &distanceBetweenPresses);
167 static bool isSinglePointDevice(const QInputDevice *dev);
168 static QQuickPointingDeviceExtra *deviceExtra(const QInputDevice *device);
169
170 // delivery of pointer events:
171 void touchToMouseEvent(QEvent::Type type, const QEventPoint &p, const QTouchEvent *touchEvent, QMutableSinglePointEvent *mouseEvent);
172 void ensureDeviceConnected(const QPointingDevice *dev);
173 void deliverPointerEvent(QPointerEvent *);
174 bool deliverTouchCancelEvent(QTouchEvent *);
175 bool deliverPressOrReleaseEvent(QPointerEvent *, bool handlersOnly = false);
176 void deliverUpdatedPoints(QPointerEvent *event);
177 void deliverMatchingPointsToItem(QQuickItem *item, bool isGrabber, QPointerEvent *pointerEvent, bool handlersOnly = false);
178
179 QVector<QQuickItem *> eventTargets(QQuickItem *, const QEvent *event, QPointF scenePos, qxp::function_ref<std::optional<bool> (QQuickItem *, const QEvent *)> predicate) const;
180 QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointerEvent *event, const QEventPoint &point,
181 bool checkMouseButtons, bool checkAcceptsTouch) const;
182 QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const;
183
184 // hover delivery
185 enum class HoverChange : uint8_t {
186 Clear,
187 Set,
188 };
189 bool deliverHoverEvent(const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp);
190 bool deliverHoverEventRecursive(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp);
191 bool deliverHoverEventToItem(QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, ulong timestamp,
192 HoverChange hoverChange);
193 bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos,
194 Qt::KeyboardModifiers modifiers, ulong timestamp);
195 bool clearHover(ulong timestamp = 0);
196
197#if QT_CONFIG(quick_draganddrop)
198 void deliverDragEvent(QQuickDragGrabber *, QEvent *);
199 bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *,
200 QVarLengthArray<QQuickItem *, 64> *currentGrabItems = nullptr,
201 QObject *formerTarget = nullptr);
202#endif
203
204 static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
205
206 static bool dragOverThreshold(qreal d, Qt::Axis axis, const QEventPoint &tp, int startDragThreshold = -1);
207
208 static bool dragOverThreshold(QVector2D delta);
209
210 // context menu events
211 QVector<QQuickItem *> contextMenuTargets(QQuickItem *item, const QContextMenuEvent *event) const;
212 void deliverContextMenuEvent(QContextMenuEvent *event);
213};
214
215Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickDeliveryAgentPrivate::FocusOptions)
216
217QT_END_NAMESPACE
218
219#endif // QQUICKDELIVERYAGENT_P_P_H
QVector< QObject * > deliveryTargets