File indexing completed on 2025-09-16 09:06:18
0001
0002
0003
0004 #ifndef QTESTMOUSE_H
0005 #define QTESTMOUSE_H
0006
0007 #if 0
0008
0009 #pragma qt_no_master_include
0010 #endif
0011
0012 #include <QtTest/qttestglobal.h>
0013 #include <QtTest/qtestassert.h>
0014 #include <QtTest/qtestsystem.h>
0015 #include <QtTest/qtestspontaneevent.h>
0016 #include <QtCore/qpoint.h>
0017 #include <QtCore/qstring.h>
0018 #include <QtCore/qpointer.h>
0019 #include <QtGui/qevent.h>
0020 #include <QtGui/qwindow.h>
0021
0022 #ifdef QT_WIDGETS_LIB
0023 #include <QtWidgets/qapplication.h>
0024 #include <QtWidgets/qwidget.h>
0025 #endif
0026
0027 QT_BEGIN_NAMESPACE
0028
0029 Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global,
0030 Qt::MouseButtons state, Qt::MouseButton button,
0031 QEvent::Type type, Qt::KeyboardModifiers mods, int timestamp);
0032
0033 namespace QTestPrivate
0034 {
0035 extern Q_TESTLIB_EXPORT Qt::MouseButtons qtestMouseButtons;
0036 }
0037
0038 namespace QTest
0039 {
0040 enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDClick, MouseMove };
0041
0042 extern Q_TESTLIB_EXPORT int lastMouseTimestamp;
0043
0044
0045
0046
0047 static const int mouseDoubleClickInterval = 500;
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 static void mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button,
0066 Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
0067 {
0068 QTEST_ASSERT(window);
0069 extern int Q_TESTLIB_EXPORT defaultMouseDelay();
0070
0071
0072 const QSize windowSize = window->geometry().size();
0073 if (windowSize.width() <= pos.x() || windowSize.height() <= pos.y()) {
0074 qWarning("Mouse event at %d, %d occurs outside target window (%dx%d).",
0075 pos.x(), pos.y(), windowSize.width(), windowSize.height());
0076 }
0077
0078 int actualDelay = qMax(1, (delay == -1 || delay < defaultMouseDelay()) ? defaultMouseDelay() : delay);
0079
0080 if (pos.isNull())
0081 pos = QPoint(window->width() / 2, window->height() / 2);
0082
0083 QTEST_ASSERT(!stateKey || stateKey & Qt::KeyboardModifierMask);
0084
0085 stateKey &= Qt::KeyboardModifierMask;
0086
0087 QPointF global = window->mapToGlobal(pos);
0088 QPointer<QWindow> w(window);
0089
0090 using namespace QTestPrivate;
0091 switch (action)
0092 {
0093 case MouseDClick:
0094 qtestMouseButtons.setFlag(button, true);
0095 lastMouseTimestamp += actualDelay;
0096 qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress,
0097 stateKey, lastMouseTimestamp);
0098 qtestMouseButtons.setFlag(button, false);
0099 lastMouseTimestamp += actualDelay;
0100 qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease,
0101 stateKey, lastMouseTimestamp);
0102 Q_FALLTHROUGH();
0103 case MousePress:
0104 case MouseClick:
0105 qtestMouseButtons.setFlag(button, true);
0106 lastMouseTimestamp += actualDelay;
0107 qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonPress,
0108 stateKey, lastMouseTimestamp);
0109 if (action == MousePress)
0110 break;
0111 Q_FALLTHROUGH();
0112 case MouseRelease:
0113 qtestMouseButtons.setFlag(button, false);
0114 lastMouseTimestamp += actualDelay;
0115 qt_handleMouseEvent(w, pos, global, qtestMouseButtons, button, QEvent::MouseButtonRelease,
0116 stateKey, lastMouseTimestamp);
0117 if (delay == -1)
0118 lastMouseTimestamp += mouseDoubleClickInterval;
0119 break;
0120 case MouseMove:
0121 lastMouseTimestamp += actualDelay;
0122 qt_handleMouseEvent(w, pos, global, qtestMouseButtons, Qt::NoButton, QEvent::MouseMove,
0123 stateKey, lastMouseTimestamp);
0124 break;
0125 default:
0126 QTEST_ASSERT(false);
0127 }
0128 qApp->processEvents();
0129 }
0130
0131 inline void mousePress(QWindow *window, Qt::MouseButton button,
0132 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0133 QPoint pos = QPoint(), int delay=-1)
0134 { mouseEvent(MousePress, window, button, stateKey, pos, delay); }
0135 inline void mouseRelease(QWindow *window, Qt::MouseButton button,
0136 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0137 QPoint pos = QPoint(), int delay=-1)
0138 { mouseEvent(MouseRelease, window, button, stateKey, pos, delay); }
0139 inline void mouseClick(QWindow *window, Qt::MouseButton button,
0140 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0141 QPoint pos = QPoint(), int delay=-1)
0142 { mouseEvent(MouseClick, window, button, stateKey, pos, delay); }
0143 inline void mouseDClick(QWindow *window, Qt::MouseButton button,
0144 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0145 QPoint pos = QPoint(), int delay=-1)
0146 { mouseEvent(MouseDClick, window, button, stateKey, pos, delay); }
0147 inline void mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1)
0148 { mouseEvent(MouseMove, window, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); }
0149
0150 #ifdef QT_WIDGETS_LIB
0151 static void mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button,
0152 Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
0153 {
0154 QTEST_ASSERT(widget);
0155
0156 if (pos.isNull())
0157 pos = widget->rect().center();
0158
0159 #ifdef QTEST_QPA_MOUSE_HANDLING
0160 QWindow *w = widget->window()->windowHandle();
0161 QTEST_ASSERT(w);
0162 mouseEvent(action, w, button, stateKey, w->mapFromGlobal(widget->mapToGlobal(pos)), delay);
0163 #else
0164 extern int Q_TESTLIB_EXPORT defaultMouseDelay();
0165
0166 if (delay == -1 || delay < defaultMouseDelay())
0167 delay = defaultMouseDelay();
0168 lastMouseTimestamp += qMax(1, delay);
0169
0170 if (action == MouseClick) {
0171 mouseEvent(MousePress, widget, button, stateKey, pos);
0172 mouseEvent(MouseRelease, widget, button, stateKey, pos);
0173 return;
0174 }
0175
0176 QTEST_ASSERT(!stateKey || stateKey & Qt::KeyboardModifierMask);
0177
0178 stateKey &= Qt::KeyboardModifierMask;
0179
0180 QEvent::Type meType = QEvent::None;
0181 using namespace QTestPrivate;
0182 switch (action)
0183 {
0184 case MousePress:
0185 qtestMouseButtons.setFlag(button, true);
0186 meType = QEvent::MouseButtonPress;
0187 break;
0188 case MouseRelease:
0189 qtestMouseButtons.setFlag(button, false);
0190 meType = QEvent::MouseButtonRelease;
0191 break;
0192 case MouseDClick:
0193 qtestMouseButtons.setFlag(button, true);
0194 meType = QEvent::MouseButtonDblClick;
0195 break;
0196 case MouseMove:
0197
0198
0199
0200 if (qtestMouseButtons == Qt::NoButton) {
0201 QCursor::setPos(widget->mapToGlobal(pos));
0202 qApp->processEvents();
0203 return;
0204 }
0205 meType = QEvent::MouseMove;
0206 break;
0207 default:
0208 QTEST_ASSERT(false);
0209 }
0210 QMouseEvent me(meType, pos, widget->mapToGlobal(pos), button, qtestMouseButtons, stateKey, QPointingDevice::primaryPointingDevice());
0211 me.setTimestamp(lastMouseTimestamp);
0212 if (action == MouseRelease)
0213 lastMouseTimestamp += mouseDoubleClickInterval;
0214
0215 QSpontaneKeyEvent::setSpontaneous(&me);
0216 if (!qApp->notify(widget, &me)) {
0217 static const char *const mouseActionNames[] =
0218 { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" };
0219 qWarning("Mouse event \"%s\" not accepted by receiving widget",
0220 mouseActionNames[static_cast<int>(action)]);
0221 }
0222 #endif
0223 }
0224
0225 inline void mousePress(QWidget *widget, Qt::MouseButton button,
0226 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0227 QPoint pos = QPoint(), int delay=-1)
0228 { mouseEvent(MousePress, widget, button, stateKey, pos, delay); }
0229 inline void mouseRelease(QWidget *widget, Qt::MouseButton button,
0230 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0231 QPoint pos = QPoint(), int delay=-1)
0232 { mouseEvent(MouseRelease, widget, button, stateKey, pos, delay); }
0233 inline void mouseClick(QWidget *widget, Qt::MouseButton button,
0234 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0235 QPoint pos = QPoint(), int delay=-1)
0236 { mouseEvent(MouseClick, widget, button, stateKey, pos, delay); }
0237 inline void mouseDClick(QWidget *widget, Qt::MouseButton button,
0238 Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(),
0239 QPoint pos = QPoint(), int delay=-1)
0240 { mouseEvent(MouseDClick, widget, button, stateKey, pos, delay); }
0241 inline void mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
0242 { mouseEvent(MouseMove, widget, Qt::NoButton, Qt::KeyboardModifiers(), pos, delay); }
0243 #endif
0244 }
0245
0246 QT_END_NAMESPACE
0247
0248 #endif