QtBase  v6.3.1
qtestmouse.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtTest module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QTESTMOUSE_H
41 #define QTESTMOUSE_H
42 
43 #if 0
44 // inform syncqt
45 #pragma qt_no_master_include
46 #endif
47 
48 #include <QtTest/qttestglobal.h>
49 #include <QtTest/qtestassert.h>
50 #include <QtTest/qtestsystem.h>
51 #include <QtTest/qtestspontaneevent.h>
52 #include <QtCore/qpoint.h>
53 #include <QtCore/qstring.h>
54 #include <QtCore/qpointer.h>
55 #include <QtGui/qevent.h>
56 #include <QtGui/qwindow.h>
57 
58 #ifdef QT_WIDGETS_LIB
59 #include <QtWidgets/qapplication.h>
60 #include <QtWidgets/qwidget.h>
61 #endif
62 
63 #include <QtCore/QDebug>
64 
66 
67 Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global,
68  Qt::MouseButtons state, Qt::MouseButton button,
69  QEvent::Type type, Qt::KeyboardModifiers mods, int timestamp);
70 
71 namespace QTestPrivate
72 {
73  extern Q_TESTLIB_EXPORT Qt::MouseButtons qtestMouseButtons;
74 }
75 
76 namespace QTest
77 {
79 
80  extern Q_TESTLIB_EXPORT int lastMouseTimestamp;
81 
82  // This value is used to emulate timestamps to avoid creating double clicks by mistake.
83  // Use this constant instead of QStyleHints::mouseDoubleClickInterval property to avoid tests
84  // to depend on platform themes.
85  static const int mouseDoubleClickInterval = 500;
86 
97  static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button,
98  Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
99  {
101  extern int Q_TESTLIB_EXPORT defaultMouseDelay();
102 
103  // pos is in window local coordinates
104  const QSize windowSize = window->geometry().size();
105  if (windowSize.width() <= pos.x() || windowSize.height() <= pos.y()) {
106  qWarning("Mouse event at %d, %d occurs outside target window (%dx%d).",
107  pos.x(), pos.y(), windowSize.width(), windowSize.height());
108  }
109 
110  if (delay == -1 || delay < defaultMouseDelay())
111  delay = defaultMouseDelay();
112  lastMouseTimestamp += qMax(1, delay);
113 
114  if (pos.isNull())
115  pos = QPoint(window->width() / 2, window->height() / 2);
116 
117  QTEST_ASSERT(!stateKey || stateKey & Qt::KeyboardModifierMask);
118 
119  stateKey &= Qt::KeyboardModifierMask;
120 
121  QPointF global = window->mapToGlobal(pos);
123 
124  using namespace QTestPrivate;
125  switch (action)
126  {
127  case MouseDClick:
128  qtestMouseButtons.setFlag(button, true);
130  stateKey, lastMouseTimestamp);
131  qtestMouseButtons.setFlag(button, false);
133  stateKey, lastMouseTimestamp);
134  Q_FALLTHROUGH();
135  case MousePress:
136  case MouseClick:
137  qtestMouseButtons.setFlag(button, true);
139  stateKey, lastMouseTimestamp);
140  if (action == MousePress)
141  break;
142  Q_FALLTHROUGH();
143  case MouseRelease:
144  qtestMouseButtons.setFlag(button, false);
146  stateKey, lastMouseTimestamp);
147  lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated
148  break;
149  case MouseMove:
151  stateKey, lastMouseTimestamp);
152  break;
153  default:
154  QTEST_ASSERT(false);
155  }
156  qApp->processEvents();
157  }
158 
160  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
161  QPoint pos = QPoint(), int delay=-1)
162  { mouseEvent(MousePress, window, button, stateKey, pos, delay); }
164  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
165  QPoint pos = QPoint(), int delay=-1)
166  { mouseEvent(MouseRelease, window, button, stateKey, pos, delay); }
168  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
169  QPoint pos = QPoint(), int delay=-1)
170  { mouseEvent(MouseClick, window, button, stateKey, pos, delay); }
172  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
173  QPoint pos = QPoint(), int delay=-1)
174  { mouseEvent(MouseDClick, window, button, stateKey, pos, delay); }
175  inline void mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1)
176  { mouseEvent(MouseMove, window, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); }
177 
178 #ifdef QT_WIDGETS_LIB
179  static void mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button,
180  Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
181  {
183 
184  if (pos.isNull())
185  pos = widget->rect().center();
186 
187 #ifdef QTEST_QPA_MOUSE_HANDLING
188  QWindow *w = widget->window()->windowHandle();
189  QTEST_ASSERT(w);
190  mouseEvent(action, w, button, stateKey, w->mapFromGlobal(widget->mapToGlobal(pos)), delay);
191 #else
192  extern int Q_TESTLIB_EXPORT defaultMouseDelay();
193 
194  if (delay == -1 || delay < defaultMouseDelay())
195  delay = defaultMouseDelay();
196  lastMouseTimestamp += qMax(1, delay);
197 
198  if (action == MouseClick) {
199  mouseEvent(MousePress, widget, button, stateKey, pos);
200  mouseEvent(MouseRelease, widget, button, stateKey, pos);
201  return;
202  }
203 
204  QTEST_ASSERT(!stateKey || stateKey & Qt::KeyboardModifierMask);
205 
206  stateKey &= Qt::KeyboardModifierMask;
207 
208  QEvent::Type meType;
209  using namespace QTestPrivate;
210  switch (action)
211  {
212  case MousePress:
213  qtestMouseButtons.setFlag(button, true);
214  meType = QEvent::MouseButtonPress;
215  break;
216  case MouseRelease:
217  qtestMouseButtons.setFlag(button, false);
219  break;
220  case MouseDClick:
221  qtestMouseButtons.setFlag(button, true);
223  break;
224  case MouseMove:
225  // ### Qt 7: compatibility with < Qt 6.3, we should not rely on QCursor::setPos
226  // for generating mouse move events, and code that depends on QCursor::pos should
227  // be tested using QCursor::setPos explicitly.
230  qApp->processEvents();
231  return;
232  }
233  meType = QEvent::MouseMove;
234  break;
235  default:
236  QTEST_ASSERT(false);
237  }
239  me.setTimestamp(lastMouseTimestamp);
240  if (action == MouseRelease) // avoid double clicks being generated
241  lastMouseTimestamp += mouseDoubleClickInterval;
242 
244  if (!qApp->notify(widget, &me)) {
245  static const char *const mouseActionNames[] =
246  { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
247  qWarning("Mouse event \"%s\" not accepted by receiving widget",
248  mouseActionNames[static_cast<int>(action)]);
249  }
250 #endif
251  }
252 
253  inline void mousePress(QWidget *widget, Qt::MouseButton button,
254  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
255  QPoint pos = QPoint(), int delay=-1)
256  { mouseEvent(MousePress, widget, button, stateKey, pos, delay); }
257  inline void mouseRelease(QWidget *widget, Qt::MouseButton button,
258  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
259  QPoint pos = QPoint(), int delay=-1)
260  { mouseEvent(MouseRelease, widget, button, stateKey, pos, delay); }
261  inline void mouseClick(QWidget *widget, Qt::MouseButton button,
262  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
263  QPoint pos = QPoint(), int delay=-1)
264  { mouseEvent(MouseClick, widget, button, stateKey, pos, delay); }
265  inline void mouseDClick(QWidget *widget, Qt::MouseButton button,
266  Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
267  QPoint pos = QPoint(), int delay=-1)
268  { mouseEvent(MouseDClick, widget, button, stateKey, pos, delay); }
269  inline void mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
270  { mouseEvent(MouseMove, widget, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); }
271 #endif // QT_WIDGETS_LIB
272 }
273 
275 
276 #endif // QTESTMOUSE_H
static void setPos(int x, int y)
Definition: qcursor.cpp:276
@ MouseMove
Definition: qcoreevent.h:76
@ MouseButtonPress
Definition: qcoreevent.h:73
@ MouseButtonDblClick
Definition: qcoreevent.h:75
@ MouseButtonRelease
Definition: qcoreevent.h:74
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:231
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
static const QPointingDevice * primaryPointingDevice(const QString &seatName=QString())
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
static void setSpontaneous(QEvent *ev)
QWidget * window() const
Definition: qwidget.cpp:4319
QPointF mapToGlobal(const QPointF &) const
QRect rect
the internal geometry of the widget excluding any window frame
Definition: qwidget.h:150
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
QOpenGLWidget * widget
[1]
QPushButton * button
[2]
else opt state
[0]
#define local
Definition: zutil.h:30
[15]
Definition: tst_encoder.cpp:33
Q_TESTLIB_EXPORT int lastMouseTimestamp
Definition: qtestmouse.cpp:48
int Q_TESTLIB_EXPORT defaultMouseDelay()
Definition: qtestcase.cpp:491
MouseAction
Definition: qtestmouse.h:78
@ MouseMove
Definition: qtestmouse.h:78
@ MousePress
Definition: qtestmouse.h:78
@ MouseDClick
Definition: qtestmouse.h:78
@ MouseClick
Definition: qtestmouse.h:78
@ MouseRelease
Definition: qtestmouse.h:78
void mouseMove(QWindow *window, QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:175
void mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=Qt::KeyboardModifiers(), QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:171
void mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=Qt::KeyboardModifiers(), QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:163
void mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=Qt::KeyboardModifiers(), QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:167
void mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=Qt::KeyboardModifiers(), QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:159
Q_TESTLIB_EXPORT Qt::MouseButtons qtestMouseButtons
Definition: qtestcase.cpp:382
MouseButton
Definition: qnamespace.h:81
@ NoButton
Definition: qnamespace.h:82
@ KeyboardModifierMask
Definition: qnamespace.h:1082
action
Definition: devices.py:78
#define Q_FALLTHROUGH()
#define qApp
#define qWarning
Definition: qlogging.h:179
GLenum type
Definition: qopengl.h:270
GLfloat GLfloat GLfloat w
[0]
#define QTEST_ASSERT(cond)
Definition: qtestassert.h:48
QT_BEGIN_NAMESPACE Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods, int timestamp)
aWidget window() -> setWindowTitle("New Window Title")
[2]
Global global
Definition: main.cpp:114
@ windowSize