1// Copyright (C) 2018 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#include <private/qguiapplication_p.h>
5#include <private/qeventpoint_p.h>
6
7#include <qpa/qplatformintegration.h>
8
9#include "qtestsupport_gui.h"
10#include "qwindow.h"
11
12#include <QtCore/qtestsupport_core.h>
13#include <QtCore/qthread.h>
14#include <QtCore/QDebug>
15
16QT_BEGIN_NAMESPACE
17
18/*!
19 \since 5.0
20
21 Returns \c true, if \a window is active within \a timeout milliseconds. Otherwise returns \c false.
22
23 The method is useful in tests that call QWindow::show() and rely on the window actually being
24 active (i.e. being visible and having focus) before proceeding.
25
26 \note The method will time out and return \c false if another window prevents \a window from
27 becoming active.
28
29 \note Since focus is an exclusive property, \a window may loose its focus to another window at
30 any time - even after the method has returned \c true.
31
32 \sa qWaitForWindowExposed(), QWindow::isActive()
33*/
34Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
35{
36 if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))) {
37 qWarning() << "qWaitForWindowActive was called on a platform that doesn't support window"
38 << "activation. This means there is an error in the test and it should either"
39 << "check for the WindowActivation platform capability before calling"
40 << "qWaitForWindowActivate, use qWaitForWindowExposed instead, or skip the test."
41 << "Falling back to qWaitForWindowExposed.";
42 return qWaitForWindowExposed(window, timeout);
43 }
44 return QTest::qWaitFor(predicate: [&]() { return window->isActive(); }, timeout);
45}
46
47/*!
48 \since 5.0
49
50 Returns \c true, if \a window is exposed within \a timeout milliseconds. Otherwise returns \c false.
51
52 The method is useful in tests that call QWindow::show() and rely on the window actually being
53 being visible before proceeding.
54
55 \note A window mapped to screen may still not be considered exposed, if the window client area is
56 not visible, e.g. because it is completely covered by other windows.
57 In such cases, the method will time out and return \c false.
58
59 \sa qWaitForWindowActive(), QWindow::isExposed()
60*/
61Q_GUI_EXPORT bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
62{
63 return QTest::qWaitFor(predicate: [&]() { return window->isExposed(); }, timeout);
64}
65
66namespace QTest {
67
68QTouchEventSequence::~QTouchEventSequence()
69{
70 if (commitWhenDestroyed)
71 QTouchEventSequence::commit();
72}
73QTouchEventSequence& QTouchEventSequence::press(int touchId, const QPoint &pt, QWindow *window)
74{
75 auto &p = point(touchId);
76 QMutableEventPoint::setGlobalPosition(p, arg: mapToScreen(window, pt));
77 QMutableEventPoint::setState(p, arg: QEventPoint::State::Pressed);
78 return *this;
79}
80QTouchEventSequence& QTouchEventSequence::move(int touchId, const QPoint &pt, QWindow *window)
81{
82 auto &p = point(touchId);
83 QMutableEventPoint::setGlobalPosition(p, arg: mapToScreen(window, pt));
84 QMutableEventPoint::setState(p, arg: QEventPoint::State::Updated);
85 return *this;
86}
87QTouchEventSequence& QTouchEventSequence::release(int touchId, const QPoint &pt, QWindow *window)
88{
89 auto &p = point(touchId);
90 QMutableEventPoint::setGlobalPosition(p, arg: mapToScreen(window, pt));
91 QMutableEventPoint::setState(p, arg: QEventPoint::State::Released);
92 return *this;
93}
94QTouchEventSequence& QTouchEventSequence::stationary(int touchId)
95{
96 auto &p = pointOrPreviousPoint(touchId);
97 QMutableEventPoint::setState(p, arg: QEventPoint::State::Stationary);
98 return *this;
99}
100
101bool QTouchEventSequence::commit(bool processEvents)
102{
103 if (points.isEmpty())
104 return false;
105 QThread::sleep(nsec: std::chrono::milliseconds{1});
106 bool ret = false;
107 if (targetWindow)
108 ret = qt_handleTouchEventv2(w: targetWindow, device, points: points.values());
109 if (processEvents)
110 QCoreApplication::processEvents();
111 previousPoints = points;
112 points.clear();
113 return ret;
114}
115
116QTouchEventSequence::QTouchEventSequence(QWindow *window, QPointingDevice *aDevice, bool autoCommit)
117 : targetWindow(window), device(aDevice), commitWhenDestroyed(autoCommit)
118{
119}
120
121QPoint QTouchEventSequence::mapToScreen(QWindow *window, const QPoint &pt)
122{
123 if (window)
124 return window->mapToGlobal(pos: pt);
125 return targetWindow ? targetWindow->mapToGlobal(pos: pt) : pt;
126}
127
128QEventPoint &QTouchEventSequence::point(int touchId)
129{
130 if (!points.contains(key: touchId))
131 points[touchId] = QEventPoint(touchId);
132 return points[touchId];
133}
134
135QEventPoint &QTouchEventSequence::pointOrPreviousPoint(int touchId)
136{
137 if (!points.contains(key: touchId)) {
138 if (previousPoints.contains(key: touchId))
139 points[touchId] = previousPoints.value(key: touchId);
140 else
141 points[touchId] = QEventPoint(touchId);
142 }
143 return points[touchId];
144}
145
146} // namespace QTest
147
148QT_END_NAMESPACE
149

source code of qtbase/src/gui/kernel/qtestsupport_gui.cpp