File indexing completed on 2025-02-21 10:12:23
0001
0002
0003
0004 #ifndef QTESTKEYBOARD_H
0005 #define QTESTKEYBOARD_H
0006
0007 #if 0
0008
0009 #pragma qt_no_master_include
0010 #endif
0011
0012 #include <QtTest/qtestassert.h>
0013 #include <QtTest/qttestglobal.h>
0014 #include <QtTest/qtestsystem.h>
0015 #include <QtTest/qtestspontaneevent.h>
0016
0017 #include <QtCore/qpointer.h>
0018 #include <QtGui/qguiapplication.h>
0019 #include <QtGui/qwindow.h>
0020 #include <QtGui/qevent.h>
0021 #if QT_CONFIG(shortcut)
0022 # include <QtGui/qkeysequence.h>
0023 #endif
0024
0025 #ifdef QT_WIDGETS_LIB
0026 #include <QtWidgets/qwidget.h>
0027 #include <QtWidgets/qapplication.h>
0028 #endif
0029
0030 QT_BEGIN_NAMESPACE
0031
0032 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);
0033 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);
0034
0035 namespace QTest
0036 {
0037 enum KeyAction { Press, Release, Click, Shortcut };
0038
0039 static void simulateEvent(QWindow *window, bool press, int code,
0040 Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
0041 {
0042 QEvent::Type type;
0043 type = press ? QEvent::KeyPress : QEvent::KeyRelease;
0044 qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay);
0045 qApp->processEvents();
0046 }
0047
0048 static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
0049 QString text, Qt::KeyboardModifiers modifier, int delay=-1)
0050 {
0051 QTEST_ASSERT(qApp);
0052
0053 if (!window)
0054 window = QGuiApplication::focusWindow();
0055
0056 QTEST_ASSERT(window);
0057
0058
0059 if (action == Click) {
0060 QPointer<QWindow> ptr(window);
0061 sendKeyEvent(Press, window, code, text, modifier, delay);
0062 if (!ptr)
0063 return;
0064 sendKeyEvent(Release, window, code, text, modifier, delay);
0065 return;
0066 }
0067
0068 bool repeat = false;
0069
0070 if (action == Shortcut) {
0071 int timestamp = 0;
0072 qt_sendShortcutOverrideEvent(window, timestamp, code, modifier, text, repeat);
0073 return;
0074 }
0075
0076 if (action == Press) {
0077 if (modifier & Qt::ShiftModifier)
0078 simulateEvent(window, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay);
0079
0080 if (modifier & Qt::ControlModifier)
0081 simulateEvent(window, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
0082
0083 if (modifier & Qt::AltModifier)
0084 simulateEvent(window, true, Qt::Key_Alt,
0085 modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
0086 if (modifier & Qt::MetaModifier)
0087 simulateEvent(window, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
0088 | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
0089 simulateEvent(window, true, code, modifier, text, repeat, delay);
0090 } else if (action == Release) {
0091 simulateEvent(window, false, code, modifier, text, repeat, delay);
0092
0093 if (modifier & Qt::MetaModifier)
0094 simulateEvent(window, false, Qt::Key_Meta, modifier, QString(), false, delay);
0095 if (modifier & Qt::AltModifier)
0096 simulateEvent(window, false, Qt::Key_Alt, modifier &
0097 (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
0098
0099 if (modifier & Qt::ControlModifier)
0100 simulateEvent(window, false, Qt::Key_Control,
0101 modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
0102
0103 if (modifier & Qt::ShiftModifier)
0104 simulateEvent(window, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
0105 }
0106 }
0107
0108
0109 static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
0110 char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
0111 {
0112 QString text;
0113 if (ascii)
0114 text = QString(QChar::fromLatin1(ascii));
0115 sendKeyEvent(action, window, code, text, modifier, delay);
0116 }
0117
0118 inline static void keyEvent(KeyAction action, QWindow *window, char ascii,
0119 Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0120 { sendKeyEvent(action, window, asciiToKey(ascii), ascii, modifier, delay); }
0121 inline static void keyEvent(KeyAction action, QWindow *window, Qt::Key key,
0122 Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0123 { sendKeyEvent(action, window, key, keyToAscii(key), modifier, delay); }
0124
0125 [[maybe_unused]] inline static void keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0126 { keyEvent(Click, window, key, modifier, delay); }
0127 [[maybe_unused]] inline static void keyClick(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0128 { keyEvent(Click, window, key, modifier, delay); }
0129 [[maybe_unused]] inline static void keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0130 { keyEvent(Release, window, key, modifier, delay); }
0131 [[maybe_unused]] inline static void keyRelease(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0132 { keyEvent(Release, window, key, modifier, delay); }
0133 [[maybe_unused]] inline static void keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0134 { keyEvent(Press, window, key, modifier, delay); }
0135 [[maybe_unused]] inline static void keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0136 { keyEvent(Press, window, key, modifier, delay); }
0137
0138 #if QT_CONFIG(shortcut)
0139 [[maybe_unused]] inline static void keySequence(QWindow *window, const QKeySequence &keySequence)
0140 {
0141 for (int i = 0; i < keySequence.count(); ++i) {
0142 const Qt::Key key = keySequence[i].key();
0143 const Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
0144 keyClick(window, key, modifiers);
0145 }
0146 }
0147 #endif
0148
0149 #ifdef QT_WIDGETS_LIB
0150 static void simulateEvent(QWidget *widget, bool press, int code,
0151 Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
0152 {
0153 QTEST_ASSERT(widget);
0154 extern int Q_TESTLIB_EXPORT defaultKeyDelay();
0155
0156 if (delay == -1 || delay < defaultKeyDelay())
0157 delay = defaultKeyDelay();
0158 if (delay > 0)
0159 QTest::qWait(delay);
0160
0161 QKeyEvent a(press ? QEvent::KeyPress : QEvent::KeyRelease, code, modifier, text, repeat);
0162 QSpontaneKeyEvent::setSpontaneous(&a);
0163
0164 if (press && qt_sendShortcutOverrideEvent(widget, a.timestamp(), code, modifier, text, repeat))
0165 return;
0166 if (!qApp->notify(widget, &a))
0167 qWarning("Keyboard event not accepted by receiving widget");
0168 }
0169
0170 static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
0171 QString text, Qt::KeyboardModifiers modifier, int delay=-1)
0172 {
0173 QTEST_ASSERT(qApp);
0174
0175 if (!widget)
0176 widget = QWidget::keyboardGrabber();
0177 if (!widget) {
0178
0179 if (QWidget *apw = QApplication::activePopupWidget())
0180 widget = apw->focusWidget() ? apw->focusWidget() : apw;
0181 }
0182 if (!widget) {
0183 QWindow *window = QGuiApplication::focusWindow();
0184 if (window) {
0185 sendKeyEvent(action, window, code, text, modifier, delay);
0186 return;
0187 }
0188 }
0189 if (!widget)
0190 widget = QApplication::focusWidget();
0191 if (!widget)
0192 widget = QApplication::activeWindow();
0193
0194 QTEST_ASSERT(widget);
0195
0196 if (action == Click) {
0197 QPointer<QWidget> ptr(widget);
0198 sendKeyEvent(Press, widget, code, text, modifier, delay);
0199 if (!ptr) {
0200
0201
0202 return;
0203 }
0204 sendKeyEvent(Release, widget, code, text, modifier, delay);
0205 return;
0206 }
0207
0208 bool repeat = false;
0209
0210 if (action == Press) {
0211 if (modifier & Qt::ShiftModifier)
0212 simulateEvent(widget, true, Qt::Key_Shift, Qt::KeyboardModifiers(), QString(), false, delay);
0213
0214 if (modifier & Qt::ControlModifier)
0215 simulateEvent(widget, true, Qt::Key_Control, modifier & Qt::ShiftModifier, QString(), false, delay);
0216
0217 if (modifier & Qt::AltModifier)
0218 simulateEvent(widget, true, Qt::Key_Alt,
0219 modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
0220 if (modifier & Qt::MetaModifier)
0221 simulateEvent(widget, true, Qt::Key_Meta, modifier & (Qt::ShiftModifier
0222 | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
0223 simulateEvent(widget, true, code, modifier, text, repeat, delay);
0224 } else if (action == Release) {
0225 simulateEvent(widget, false, code, modifier, text, repeat, delay);
0226
0227 if (modifier & Qt::MetaModifier)
0228 simulateEvent(widget, false, Qt::Key_Meta, modifier, QString(), false, delay);
0229 if (modifier & Qt::AltModifier)
0230 simulateEvent(widget, false, Qt::Key_Alt, modifier &
0231 (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier), QString(), false, delay);
0232
0233 if (modifier & Qt::ControlModifier)
0234 simulateEvent(widget, false, Qt::Key_Control,
0235 modifier & (Qt::ShiftModifier | Qt::ControlModifier), QString(), false, delay);
0236
0237 if (modifier & Qt::ShiftModifier)
0238 simulateEvent(widget, false, Qt::Key_Shift, modifier & Qt::ShiftModifier, QString(), false, delay);
0239 }
0240 }
0241
0242
0243 static void sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code,
0244 char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
0245 {
0246 QString text;
0247 if (ascii)
0248 text = QString(QChar::fromLatin1(ascii));
0249 sendKeyEvent(action, widget, code, text, modifier, delay);
0250 }
0251
0252 inline static void keyEvent(KeyAction action, QWidget *widget, char ascii,
0253 Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0254 { sendKeyEvent(action, widget, asciiToKey(ascii), ascii, modifier, delay); }
0255 inline static void keyEvent(KeyAction action, QWidget *widget, Qt::Key key,
0256 Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0257 { sendKeyEvent(action, widget, key, keyToAscii(key), modifier, delay); }
0258
0259 inline static void keyClicks(QWidget *widget, const QString &sequence,
0260 Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0261 {
0262 for (int i=0; i < sequence.size(); i++)
0263 keyEvent(Click, widget, sequence.at(i).toLatin1(), modifier, delay);
0264 }
0265
0266 inline static void keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0267 { keyEvent(Press, widget, key, modifier, delay); }
0268 inline static void keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0269 { keyEvent(Release, widget, key, modifier, delay); }
0270 inline static void keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0271 { keyEvent(Click, widget, key, modifier, delay); }
0272 inline static void keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0273 { keyEvent(Press, widget, key, modifier, delay); }
0274 inline static void keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0275 { keyEvent(Release, widget, key, modifier, delay); }
0276 inline static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
0277 { keyEvent(Click, widget, key, modifier, delay); }
0278
0279 #if QT_CONFIG(shortcut)
0280 inline static void keySequence(QWidget *widget, const QKeySequence &keySequence)
0281 {
0282 for (int i = 0; i < keySequence.count(); ++i) {
0283 const Qt::Key key = keySequence[i].key();
0284 const Qt::KeyboardModifiers modifiers = keySequence[i].keyboardModifiers();
0285 keyClick(widget, key, modifiers);
0286 }
0287 }
0288 #endif
0289
0290 #endif
0291
0292 }
0293
0294 QT_END_NAMESPACE
0295
0296 #endif