diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 3500792f4e..78bce0f0e3 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -901,26 +901,23 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo } #endif +// The following functions are used by testlib, and need to be synchronous to avoid +// race conditions with plugins delivering native events from secondary threads. + Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp) { - QWindowSystemInterfacePrivate::MouseEvent e(w, timestamp, local, global, b, mods, Qt::MouseEventNotSynthesized); - QGuiApplicationPrivate::processWindowSystemEvent(&e); + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); + QWindowSystemInterface::handleMouseEvent(w, timestamp, local, global, b, mods); + QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } 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) { - unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); - - // This is special handling needed for OS X which eventually will call sendEvent(), on other platforms - // this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for - // shortcut overriding on other platforms. -#if defined(Q_OS_OSX) - if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(w, timestamp, k, mods, text)) - return; -#endif // Q_OS_OSX - - QWindowSystemInterfacePrivate::KeyEvent e(w, timestamp, t, k, mods, text, autorep, count); - QGuiApplicationPrivate::processWindowSystemEvent(&e); + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); + QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count); + QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } 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) @@ -928,37 +925,37 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count); } +static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) +{ + QWindowSystemInterface::TouchPoint p; + p.id = pt.id(); + p.flags = pt.flags(); + p.normalPosition = pt.normalizedPos(); + p.area = pt.screenRect(); + p.pressure = pt.pressure(); + p.state = pt.state(); + p.velocity = pt.velocity(); + p.rawPositions = pt.rawScreenPositions(); + return p; +} +static QList touchPointList(const QList& pointList) +{ + QList newList; + + Q_FOREACH (QTouchEvent::TouchPoint p, pointList) + newList.append(touchPoint(p)); + + return newList; +} + Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier) { - unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); - - if (!points.size()) // Touch events must have at least one point - return; - - if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices. - return; - - QEvent::Type type; - Qt::TouchPointStates states; - - QList::const_iterator point = points.constBegin(); - QList::const_iterator end = points.constEnd(); - while (point != end) { - states |= point->state(); - ++point; - } - - // Determine the event type based on the combined point states. - type = QEvent::TouchUpdate; - if (states == Qt::TouchPointPressed) - type = QEvent::TouchBegin; - else if (states == Qt::TouchPointReleased) - type = QEvent::TouchEnd; - - QWindowSystemInterfacePrivate::TouchEvent e(w, timestamp, type, device, points, mods); - QGuiApplicationPrivate::processWindowSystemEvent(&e); + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); + QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); + QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } QWindowSystemEventHandler::~QWindowSystemEventHandler()