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]() {
109 QMutexLocker lock(&m_dataMutex);
110 scheduleNextEvent(m_data.head());
113 QMutexLocker lock(&m_dataMutex);
114 if (!m_data.isEmpty())
115 scheduleNextEvent(m_data.head());
120 using InputEventType = QQmlProfilerDefinitions::InputEventType;
121 switch (profilerEventType) {
122 case InputEventType::InputKeyPress:
123 return QEvent::KeyPress;
124 case InputEventType::InputKeyRelease:
125 return QEvent::KeyRelease;
126 case InputEventType::InputMousePress:
127 return QEvent::MouseButtonPress;
128 case InputEventType::InputMouseDoubleClick:
129 return QEvent::MouseButtonDblClick;
130 case InputEventType::InputMouseMove:
131 return QEvent::MouseMove;
132 case InputEventType::InputMouseRelease:
133 return QEvent::MouseButtonRelease;
134 case InputEventType::InputMouseWheel:
135 return QEvent::Wheel;
143 QMutexLocker lock(&m_dataMutex);
144 const QQuickProfilerData data = m_data.dequeue();
145 if (!m_data.isEmpty())
146 scheduleNextEvent(m_data.head());
154 QWindow *window = targetWindow();
156 qWarning() <<
"Target window has disappeared during event replay";
160 const QQuickProfilerData data = takeNextEvent();
161 Q_ASSERT(data.messageType == Message::Event);
163 const QEvent::Type type = eventType(data.inputType);
164 switch (data.detailType) {
165 case EventType::Key: {
166 qt_handleKeyEvent(window, type, data.inputA, Qt::KeyboardModifiers(data.inputB));
169 case EventType::Mouse: {
170 switch (data.inputType) {
171 case InputEventType::InputMouseMove: {
172 m_currentPos = QPoint(data.inputA, data.inputB);
174 window, m_currentPos, window->mapToGlobal(m_currentPos), m_currentButtons,
175 Qt::NoButton, type, m_currentModifiers, m_elapsed.elapsed());
178 case InputEventType::InputMouseWheel: {
180 window, m_currentPos, window->mapToGlobal(m_currentPos), QPoint(),
181 QPoint(data.inputA, data.inputB), m_currentModifiers, Qt::ScrollUpdate);
184 case InputEventType::InputMouseDoubleClick:
188 m_currentButtons = Qt::MouseButtons(data.inputB);
190 window, m_currentPos, window->mapToGlobal(m_currentPos), m_currentButtons,
191 Qt::MouseButton(data.inputA), type, m_currentModifiers, m_elapsed.elapsed());
206 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)