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

source code of qtdeclarative/src/quick/util/qquickdeliveryagent_p_p.h