7#include <QtQuick/qquickwindow.h>
9#include <QtGui/qtguiglobal.h>
10#include <QtGui/qtestsupport_gui.h>
11#include <QtGui/qwindow.h>
15Q_GUI_EXPORT
void qt_handleMouseEvent(
16 QWindow *window,
const QPointF &local,
const QPointF &global, Qt::MouseButtons state,
17 Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
int timestamp);
20 QWindow *w, QEvent::Type t,
int k, Qt::KeyboardModifiers mods,
21 const QString &text = QString(),
bool autorep =
false, ushort count = 1);
24 QWindow *window,
const QPointF &local,
const QPointF &global, QPoint pixelDelta,
25 QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase);
28 : QQuickEventReplayService(1, parent)
36 QQmlDebugPacket stream(message);
37 QQuickProfilerData data;
39 stream >> data.time >> data.messageType >> data.detailType;
41 if (data.messageType != Message::Event)
44 switch (data.detailType) {
46 case EventType::Mouse:
52 stream >> data.inputType >> data.inputA >> data.inputB;
54 bool isFirstEvent =
false;
56 QMutexLocker lock(&m_dataMutex);
57 isFirstEvent = m_data.isEmpty();
58 m_data.enqueue(std::move(data));
68 if (QWindow *focusWindow = QGuiApplication::focusWindow()) {
69 if (focusWindow->isExposed() && focusWindow->width() != 0 && focusWindow->height() != 0)
75 QWindow *found =
nullptr;
76 const QWindowList windowList = QGuiApplication::allWindows();
77 for (QWindow *window : windowList) {
78 if (!qobject_cast<QQuickWindow *>(window))
80 if (!window->isExposed() || window->width() == 0 || window->height() == 0)
92 if (!targetWindow()) {
95 QTimer::singleShot(16,
this, &QQuickEventReplayServiceImpl::start);
97 QMutexLocker lock(&m_dataMutex);
98 if (!m_data.isEmpty()) {
99 qWarning() <<
"Cannot determine target window for event replay. "
100 "Focus a window to use it.";
106 &m_schedule, &QTimer::timeout,
107 this, &QQuickEventReplayServiceImpl::sendNextEvent);
108 QObject::connect(
this, &QQuickEventReplayServiceImpl::dataAvailable,
this, [
this]() {
110 QMutexLocker lock(&m_dataMutex);
111 scheduleNextEvent(m_data.head());
114 QMutexLocker lock(&m_dataMutex);
115 if (!m_data.isEmpty())
116 scheduleNextEvent(m_data.head());
121 using InputEventType = QQmlProfilerDefinitions::InputEventType;
122 switch (profilerEventType) {
123 case InputEventType::InputKeyPress:
124 return QEvent::KeyPress;
125 case InputEventType::InputKeyRelease:
126 return QEvent::KeyRelease;
127 case InputEventType::InputMousePress:
128 return QEvent::MouseButtonPress;
129 case InputEventType::InputMouseDoubleClick:
130 return QEvent::MouseButtonDblClick;
131 case InputEventType::InputMouseMove:
132 return QEvent::MouseMove;
133 case InputEventType::InputMouseRelease:
134 return QEvent::MouseButtonRelease;
135 case InputEventType::InputMouseWheel:
136 return QEvent::Wheel;
144 QMutexLocker lock(&m_dataMutex);
145 const QQuickProfilerData data = m_data.dequeue();
146 if (!m_data.isEmpty())
147 scheduleNextEvent(m_data.head());
155 QWindow *window = targetWindow();
157 qWarning() <<
"Target window has disappeared during event replay";
161 const QQuickProfilerData data = takeNextEvent();
162 Q_ASSERT(data.messageType == Message::Event);
164 const QEvent::Type type = eventType(data.inputType);
165 switch (data.detailType) {
166 case EventType::Key: {
167 qt_handleKeyEvent(window, type, data.inputA, Qt::KeyboardModifiers(data.inputB));
170 case EventType::Mouse: {
171 switch (data.inputType) {
172 case InputEventType::InputMouseMove: {
173 m_currentPos = QPoint(data.inputA, data.inputB);
175 window, m_currentPos, window->mapToGlobal(m_currentPos), m_currentButtons,
176 Qt::NoButton, type, m_currentModifiers, m_elapsed.elapsed());
179 case InputEventType::InputMouseWheel: {
181 window, m_currentPos, window->mapToGlobal(m_currentPos), QPoint(),
182 QPoint(data.inputA, data.inputB), m_currentModifiers, Qt::ScrollUpdate);
185 case InputEventType::InputMouseDoubleClick:
189 m_currentButtons = Qt::MouseButtons(data.inputB);
191 window, m_currentPos, window->mapToGlobal(m_currentPos), m_currentButtons,
192 Qt::MouseButton(data.inputA), type, m_currentModifiers, m_elapsed.elapsed());
207 m_schedule.start(std::max((nextEvent.time - m_elapsed.nsecsElapsed()) / 1000000ll, 1ll));
void messageReceived(const QByteArray &) override
Combined button and popup list for selecting options.
static QWindow * targetWindow()
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
static QEvent::Type eventType(int profilerEventType)
Q_GUI_EXPORT void qt_handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase)