QtBase  v6.3.1
qtestkeyboard.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 QTESTKEYBOARD_H
41 #define QTESTKEYBOARD_H
42 
43 #if 0
44 // inform syncqt
45 #pragma qt_no_master_include
46 #endif
47 
48 #include <QtTest/qtestassert.h>
49 #include <QtTest/qttestglobal.h>
50 #include <QtTest/qtestsystem.h>
51 #include <QtTest/qtestspontaneevent.h>
52 
53 #include <QtCore/qpointer.h>
54 #include <QtGui/qguiapplication.h>
55 #include <QtGui/qwindow.h>
56 #include <QtGui/qevent.h>
57 #if QT_CONFIG(shortcut)
58 # include <QtGui/qkeysequence.h>
59 #endif
60 
61 #ifdef QT_WIDGETS_LIB
62 #include <QtWidgets/qwidget.h>
63 #include <QtWidgets/qapplication.h>
64 #endif
65 
67 
68 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);
69 Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1);
70 
71 namespace QTest
72 {
74 
75  static void simulateEvent(QWindow *window, bool press, int code,
76  Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
77  {
80  qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay);
81  qApp->processEvents();
82  }
83 
84  static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
85  QString text, Qt::KeyboardModifiers modifier, int delay=-1)
86  {
88 
89  if (!window)
91 
93 
94 
95  if (action == Click) {
97  sendKeyEvent(Press, window, code, text, modifier, delay);
98  if (!ptr)
99  return;
100  sendKeyEvent(Release, window, code, text, modifier, delay);
101  return;
102  }
103 
104  bool repeat = false;
105 
106  if (action == Shortcut) {
107  int timestamp = 0;
108  qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat);
109  return;
110  }
111 
112  if (action == Press) {
113  if (modifier & Qt::ShiftModifier)
114  simulateEvent(window, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay);
115 
116  if (modifier & Qt::ControlModifier)
117  simulateEvent(window, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
118 
119  if (modifier & Qt::AltModifier)
120  simulateEvent(window, true, Qt::Key_Alt,
121  modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
122  if (modifier & Qt::MetaModifier)
123  simulateEvent(window, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
124  | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
125  simulateEvent(window, true, code, modifier, text, repeat, delay);
126  } else if (action == Release) {
127  simulateEvent(window, false, code, modifier, text, repeat, delay);
128 
129  if (modifier & Qt::MetaModifier)
130  simulateEvent(window, false, Qt::Key_Meta, modifier, QString(), false, delay);
131  if (modifier & Qt::AltModifier)
132  simulateEvent(window, false, Qt::Key_Alt, modifier &
134 
135  if (modifier & Qt::ControlModifier)
136  simulateEvent(window, false, Qt::Key_Control,
137  modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
138 
139  if (modifier & Qt::ShiftModifier)
140  simulateEvent(window, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
141  }
142  }
143 
144  // Convenience function
145  static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
146  char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
147  {
148  QString text;
149  if (ascii)
150  text = QString(QChar::fromLatin1(ascii));
151  sendKeyEvent(action, window, code, text, modifier, delay);
152  }
153 
154  inline static void keyEvent(KeyAction action, QWindow *window, char ascii,
155  Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
156  { sendKeyEvent(action, window, asciiToKey(ascii), ascii, modifier, delay); }
157  inline static void keyEvent(KeyAction action, QWindow *window, Qt::Key key,
158  Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
159  { sendKeyEvent(action, window, key, keyToAscii(key), modifier, delay); }
160 
161  [[maybe_unused]] inline static void keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
162  { keyEvent(Click, window, key, modifier, delay); }
163  [[maybe_unused]] inline static void keyClick(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
164  { keyEvent(Click, window, key, modifier, delay); }
165  [[maybe_unused]] inline static void keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
166  { keyEvent(Release, window, key, modifier, delay); }
167  [[maybe_unused]] inline static void keyRelease(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
168  { keyEvent(Release, window, key, modifier, delay); }
169  [[maybe_unused]] inline static void keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
170  { keyEvent(Press, window, key, modifier, delay); }
171  [[maybe_unused]] inline static void keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
172  { keyEvent(Press, window, key, modifier, delay); }
173 
174 #if QT_CONFIG(shortcut)
175  [[maybe_unused]] inline static void keySequence(QWindow *window, const QKeySequence &keySequence)
176  {
177  for (int i = 0; i < keySequence.count(); ++i) {
178  const Qt::Key key = keySequence[i].key();
179  const Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
180  keyClick(window, key, modifiers);
181  }
182  }
183 #endif
184 
185 #ifdef QT_WIDGETS_LIB
186  static void simulateEvent(QWidget *widget, bool press, int code,
187  Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
188  {
190  extern int Q_TESTLIB_EXPORT defaultKeyDelay();
191 
192  if (delay == -1 || delay < defaultKeyDelay())
193  delay = defaultKeyDelay();
194  if (delay > 0)
195  QTest::qWait(delay);
196 
197  QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
199 
200  if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat))
201  return;
202  if (!qApp->notify(widget, &a))
203  qWarning("Keyboard event not accepted by receiving widget");
204  }
205 
206  static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
207  QString text, Qt::KeyboardModifiers modifier, int delay=-1)
208  {
210 
211  if (!widget)
213  if (!widget) {
214  // Popup widgets stealthily steal the keyboard grab
216  widget = apw->focusWidget() ? apw->focusWidget() : apw;
217  }
218  if (!widget) {
220  if (window) {
221  sendKeyEvent(action, window, code, text, modifier, delay);
222  return;
223  }
224  }
225  if (!widget)
227  if (!widget)
229 
231 
232  if (action == Click) {
234  sendKeyEvent(Press, widget, code, text, modifier, delay);
235  if (!ptr) {
236  // if we send key-events to embedded widgets, they might be destroyed
237  // when the user presses Return
238  return;
239  }
240  sendKeyEvent(Release, widget, code, text, modifier, delay);
241  return;
242  }
243 
244  bool repeat = false;
245 
246  if (action == Press) {
247  if (modifier & Qt::ShiftModifier)
248  simulateEvent(widget, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay);
249 
250  if (modifier & Qt::ControlModifier)
251  simulateEvent(widget, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
252 
253  if (modifier & Qt::AltModifier)
254  simulateEvent(widget, true, Qt::Key_Alt,
255  modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
256  if (modifier & Qt::MetaModifier)
257  simulateEvent(widget, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
258  | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
259  simulateEvent(widget, true, code, modifier, text, repeat, delay);
260  } else if (action == Release) {
261  simulateEvent(widget, false, code, modifier, text, repeat, delay);
262 
263  if (modifier & Qt::MetaModifier)
264  simulateEvent(widget, false, Qt::Key_Meta, modifier, QString(), false, delay);
265  if (modifier & Qt::AltModifier)
266  simulateEvent(widget, false, Qt::Key_Alt, modifier &
268 
269  if (modifier & Qt::ControlModifier)
270  simulateEvent(widget, false, Qt::Key_Control,
271  modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
272 
273  if (modifier & Qt::ShiftModifier)
274  simulateEvent(widget, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
275  }
276  }
277 
278  // Convenience function
279  static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
280  char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
281  {
282  QString text;
283  if (ascii)
284  text = QString(QChar::fromLatin1(ascii));
285  sendKeyEvent(action, widget, code, text, modifier, delay);
286  }
287 
288  inline static void keyEvent(KeyAction action, QWidget *widget, char ascii,
289  Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
290  { sendKeyEvent(action, widget, asciiToKey(ascii), ascii, modifier, delay); }
291  inline static void keyEvent(KeyAction action, QWidget *widget, Qt::Key key,
292  Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
293  { sendKeyEvent(action, widget, key, keyToAscii(key), modifier, delay); }
294 
295  inline static void keyClicks(QWidget *widget, const QString &sequence,
296  Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
297  {
298  for (int i=0; i < sequence.length(); i++)
299  keyEvent(Click, widget, sequence.at(i).toLatin1(), modifier, delay);
300  }
301 
302  inline static void keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
303  { keyEvent(Press, widget, key, modifier, delay); }
304  inline static void keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
305  { keyEvent(Release, widget, key, modifier, delay); }
306  inline static void keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
307  { keyEvent(Click, widget, key, modifier, delay); }
308  inline static void keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
309  { keyEvent(Press, widget, key, modifier, delay); }
310  inline static void keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
311  { keyEvent(Release, widget, key, modifier, delay); }
312  inline static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
313  { keyEvent(Click, widget, key, modifier, delay); }
314 
315 #if QT_CONFIG(shortcut)
316  inline static void keySequence(QWidget *widget, const QKeySequence &keySequence)
317  {
318  for (int i = 0; i < keySequence.count(); ++i) {
319  const Qt::Key key = keySequence[i].key();
320  const Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
321  keyClick(widget, key, modifiers);
322  }
323  }
324 #endif
325 
326 #endif // QT_WIDGETS_LIB
327 
328 }
329 
331 
332 #endif // QTESTKEYBOARD_H
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
static QWidget * focusWidget()
static QWidget * activePopupWidget()
static QWidget * activeWindow()
constexpr char toLatin1() const noexcept
Definition: qchar.h:488
static constexpr QChar fromLatin1(char c) noexcept
Definition: qchar.h:492
@ KeyRelease
Definition: qcoreevent.h:78
@ KeyPress
Definition: qcoreevent.h:77
static QWindow * focusWindow()
The QKeyEvent class describes a key event.
Definition: qevent.h:471
The QKeySequence class encapsulates a key sequence as used by shortcuts.
Definition: qkeysequence.h:71
int count() const
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
static void setSpontaneous(QEvent *ev)
The QString class provides a Unicode character string.
Definition: qstring.h:388
const QChar at(qsizetype i) const
Definition: qstring.h:1212
qsizetype length() const
Definition: qstring.h:415
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
QWidget * focusWidget() const
Definition: qwidget.cpp:6810
static QWidget * keyboardGrabber()
Definition: qwidget.cpp:12679
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
QOpenGLWidget * widget
[1]
QString text
[meta data]
GeneratorWrapper< T > repeat(size_t repeats, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4251
[15]
Definition: tst_encoder.cpp:33
@ Shortcut
Definition: qtestkeyboard.h:73
int Q_TESTLIB_EXPORT defaultKeyDelay()
Definition: qtestcase.cpp:503
Q_TESTLIB_EXPORT char keyToAscii(Qt::Key key)
Definition: qasciikey.cpp:239
Q_TESTLIB_EXPORT Qt::Key asciiToKey(char ascii)
Definition: qasciikey.cpp:52
Q_CORE_EXPORT void qWait(int ms)
@ Key_Shift
Definition: qnamespace.h:704
@ Key_Control
Definition: qnamespace.h:705
@ Key_Alt
Definition: qnamespace.h:707
@ Key_Meta
Definition: qnamespace.h:706
@ ShiftModifier
Definition: qnamespace.h:1075
@ ControlModifier
Definition: qnamespace.h:1076
@ MetaModifier
Definition: qnamespace.h:1078
@ NoModifier
Definition: qnamespace.h:1074
@ AltModifier
Definition: qnamespace.h:1077
action
Definition: devices.py:78
#define QString()
Definition: parse-defines.h:51
#define qApp
unsigned long ulong
Definition: qglobal.h:335
unsigned short ushort
Definition: qglobal.h:333
#define qWarning
Definition: qlogging.h:179
GLenum type
Definition: qopengl.h:270
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLenum GLsizei count
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
#define QTEST_ASSERT(cond)
Definition: qtestassert.h:48
QT_BEGIN_NAMESPACE 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)
Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text=QString(), bool autorep=false, ushort count=1)
aWidget window() -> setWindowTitle("New Window Title")
[2]
Definition: inftrees.h:24