diff options
Diffstat (limited to 'src/gui/kernel/qwindowsysteminterface.cpp')
| -rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 236 |
1 files changed, 180 insertions, 56 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 850b69d729d..09e6e2deb81 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -40,14 +40,17 @@ #include <qpa/qplatformdrag.h> #include <qpa/qplatformintegration.h> #include <qdebug.h> +#include "qhighdpiscaling_p.h" QT_BEGIN_NAMESPACE QElapsedTimer QWindowSystemInterfacePrivate::eventTime; -bool QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = false; +bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false; QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed; QMutex QWindowSystemInterfacePrivate::flushEventMutex; +QAtomicInt QWindowSystemInterfacePrivate::eventAccepted; +QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler; //------------------------------------------------------------ // @@ -93,14 +96,14 @@ void QWindowSystemInterface::handleLeaveEvent(QWindow *tlw) */ void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local, const QPointF& global) { - bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents; + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; if (wasSynchronous) - setSynchronousWindowsSystemEvents(false); + setSynchronousWindowSystemEvents(false); handleLeaveEvent(leave); handleEnterEvent(enter, local, global); if (wasSynchronous) { flushWindowSystemEvents(); - setSynchronousWindowsSystemEvents(true); + setSynchronousWindowSystemEvents(true); } } @@ -138,7 +141,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState */ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect) { - QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect); + QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -167,7 +170,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = - new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source); + new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -184,7 +187,7 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest QWindowSystemInterfacePrivate::MouseEvent * e = new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QWindowSystemInterfacePrivate::FrameStrutMouse, - local, global, b, mods, source); + QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -302,38 +305,38 @@ bool QWindowSystemInterface::tryHandleExtendedShortcutEvent(QWindow *w, ulong ti } -void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { +bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleKeyEvent(w, time, t, k, mods, text, autorep, count); + return handleKeyEvent(w, time, t, k, mods, text, autorep, count); } -void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) +bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { // 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(tlw, timestamp, k, mods, text)) - return; + return true; #endif // Q_OS_OSX QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); + return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, +bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *w, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text, bool autorep, ushort count) { unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, + return handleExtendedKeyEvent(w, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } -void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, +bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, @@ -344,7 +347,7 @@ void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); + return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } void QWindowSystemInterface::handleWheelEvent(QWindow *w, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods) { @@ -382,14 +385,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con // Simple case: vertical deltas only: if (angleDelta.y() != 0 && angleDelta.x() == 0) { - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } // Simple case: horizontal deltas only: if (angleDelta.y() == 0 && angleDelta.x() != 0) { - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } @@ -397,12 +400,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con // Both horizontal and vertical deltas: Send two wheel events. // The first event contains the Qt 5 pixel and angle delta as points, // and in addition the Qt 4 compatibility vertical angle delta. - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); // The second event contains null pixel and angle points and the // Qt 4 compatibility horizontal angle delta. - e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source); + e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -440,23 +443,60 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e windowSystemEventQueue.remove(event); } -void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev) +void QWindowSystemInterfacePrivate::postWindowSystemEvent(WindowSystemEvent *ev) { - if (synchronousWindowsSystemEvents) { - QGuiApplicationPrivate::processWindowSystemEvent(ev); + windowSystemEventQueue.append(ev); + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher(); + if (dispatcher) + dispatcher->wakeUp(); +} + +/*! + Handles a window system event. + + By default this function posts the event on the window system event queue and + wakes the Gui event dispatcher. Qt Gui will then handle the event asynchonously + at a later point. The return value is not used in asynchronous mode and will + always be true. + + In synchronous mode Qt Gui will process the event immediately. The return value + indicates if Qt accepted the event. + + \sa flushWindowSystemEvents(), setSynchronousWindowSystemEvents() +*/ +bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev) +{ + bool accepted = true; + if (synchronousWindowSystemEvents) { + if (QThread::currentThread() == QGuiApplication::instance()->thread()) { + // Process the event immediately on the current thread and return the accepted state. + QGuiApplicationPrivate::processWindowSystemEvent(ev); + accepted = ev->eventAccepted; + delete ev; + } else { + // Post the event on the Qt main thread queue and flush the queue. + // This will wake up the Gui thread which will process the event. + // Return the accepted state for the last event on the queue, + // which is the event posted by this function. + postWindowSystemEvent(ev); + accepted = QWindowSystemInterface::flushWindowSystemEvents(); + } } else { - windowSystemEventQueue.append(ev); - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher(); - if (dispatcher) - dispatcher->wakeUp(); + postWindowSystemEvent(ev); } + return accepted; } -void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device) +void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device) { QTouchDevicePrivate::registerDevice(device); } +void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device) +{ + QTouchDevicePrivate::unregisterDevice(device); +} + void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device, const QList<TouchPoint> &points, Qt::KeyboardModifiers mods) { @@ -464,12 +504,16 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device, handleTouchEvent(w, time, device, points, mods); } -QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type) +QList<QTouchEvent::TouchPoint> + QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, + const QWindow *window, + QEvent::Type *type) { QList<QTouchEvent::TouchPoint> touchPoints; Qt::TouchPointStates states; QTouchEvent::TouchPoint p; + touchPoints.reserve(points.count()); QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin(); QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd(); while (point != end) { @@ -479,16 +523,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints p.setState(point->state); const QPointF screenPos = point->area.center(); - p.setScreenPos(screenPos); - p.setScreenRect(point->area); + p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window)); + p.setScreenRect(QHighDpi::fromNativePixels(point->area, window)); // The local pos and rect are not set, they will be calculated // when the event gets processed by QGuiApplication. - p.setNormalizedPos(point->normalPosition); - p.setVelocity(point->velocity); + p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window)); + p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window)); p.setFlags(point->flags); - p.setRawScreenPositions(point->rawPositions); + p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window)); touchPoints.append(p); ++point; @@ -506,6 +550,27 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints return touchPoints; } +QList<QWindowSystemInterface::TouchPoint> + QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList, + const QWindow *window) +{ + QList<QWindowSystemInterface::TouchPoint> newList; + newList.reserve(pointList.size()); + foreach (const QTouchEvent::TouchPoint &pt, pointList) { + QWindowSystemInterface::TouchPoint p; + p.id = pt.id(); + p.flags = pt.flags(); + p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window); + p.area = QHighDpi::toNativePixels(pt.screenRect(), window); + p.pressure = pt.pressure(); + p.state = pt.state(); + p.velocity = pt.velocity(); + p.rawPositions = pt.rawScreenPositions(); + newList.append(p); + } + return newList; +} + void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device, const QList<TouchPoint> &points, Qt::KeyboardModifiers mods) { @@ -516,7 +581,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo return; QEvent::Type type; - QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type); + QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type); QWindowSystemInterfacePrivate::TouchEvent *e = new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods); @@ -549,14 +614,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt:: void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry) { QWindowSystemInterfacePrivate::ScreenGeometryEvent *e = - new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry); + new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft())); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY) { QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e = - new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); + new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -575,7 +640,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw) void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion ®ion) { - QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region); + QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw)); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -584,30 +649,37 @@ void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::Process Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread()); QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex); - flushWindowSystemEvents(flags); + sendWindowSystemEvents(flags); QWindowSystemInterfacePrivate::eventsFlushed.wakeOne(); } -void QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) +/*! + Make Qt Gui process all events on the event queue immediately. Return the + accepted state for the last event on the queue. +*/ +bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) { const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count(); if (!count) - return; + return false; if (!QGuiApplication::instance()) { qWarning().nospace() << "QWindowSystemInterface::flushWindowSystemEvents() invoked after " "QGuiApplication destruction, discarding " << count << " events."; QWindowSystemInterfacePrivate::windowSystemEventQueue.clear(); - return; + return false; } if (QThread::currentThread() != QGuiApplication::instance()->thread()) { + // Post a FlushEvents event which will trigger a call back to + // deferredFlushWindowSystemEvents from the Gui thread. QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex); QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(flags); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); + QWindowSystemInterfacePrivate::postWindowSystemEvent(e); QWindowSystemInterfacePrivate::eventsFlushed.wait(&QWindowSystemInterfacePrivate::flushEventMutex); } else { sendWindowSystemEvents(flags); } + return QWindowSystemInterfacePrivate::eventAccepted.load() > 0; } bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) @@ -621,17 +693,42 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFla QWindowSystemInterfacePrivate::getWindowSystemEvent(); if (!event) break; - nevents++; - QGuiApplicationPrivate::processWindowSystemEvent(event); + + if (QWindowSystemInterfacePrivate::eventHandler) { + if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event)) + nevents++; + } else { + nevents++; + QGuiApplicationPrivate::processWindowSystemEvent(event); + } + + // Record the accepted state for the processed event + // (excluding flush events). This state can then be + // returned by flushWindowSystemEvents(). + if (event->type != QWindowSystemInterfacePrivate::FlushEvents) + QWindowSystemInterfacePrivate::eventAccepted.store(event->eventAccepted); + delete event; } return (nevents > 0); } -void QWindowSystemInterface::setSynchronousWindowsSystemEvents(bool enable) +void QWindowSystemInterfacePrivate::installWindowSystemEventHandler(QWindowSystemEventHandler *handler) +{ + if (!eventHandler) + eventHandler = handler; +} + +void QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(QWindowSystemEventHandler *handler) +{ + if (eventHandler == handler) + eventHandler = 0; +} + +void QWindowSystemInterface::setSynchronousWindowSystemEvents(bool enable) { - QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = enable; + QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = enable; } int QWindowSystemInterface::windowSystemEventsQueued() @@ -642,12 +739,12 @@ int QWindowSystemInterface::windowSystemEventsQueued() #ifndef QT_NO_DRAGANDDROP QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) { - return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions); + return QGuiApplicationPrivate::processDrag(w, dropData, QHighDpi::fromNativeLocalPosition(p, w) ,supportedActions); } QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions) { - return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions); + return QGuiApplicationPrivate::processDrop(w, dropData, QHighDpi::fromNativeLocalPosition(p, w),supportedActions); } #endif // QT_NO_DRAGANDDROP @@ -681,8 +778,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons Qt::KeyboardModifiers modifiers) { QWindowSystemInterfacePrivate::TabletEvent *e = - new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure, - xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); + new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp, + QHighDpi::fromNativeLocalPosition(local, w), + QHighDpi::fromNativePixels(global, w), + device, pointerType, buttons, pressure, + xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } @@ -807,13 +907,23 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo } #endif -Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) { - QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods); +// 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) +{ + 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) { + 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) @@ -839,17 +949,31 @@ static QList<struct QWindowSystemInterface::TouchPoint> touchPointList(const QLi QList<struct QWindowSystemInterface::TouchPoint> newList; Q_FOREACH (QTouchEvent::TouchPoint p, pointList) - { newList.append(touchPoint(p)); - } + return newList; } -Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, +Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, const QList<QTouchEvent::TouchPoint> &points, Qt::KeyboardModifiers mods = Qt::NoModifier) { + bool wasSynchronous = QWindowSystemInterfacePrivate::synchronousWindowSystemEvents; + QWindowSystemInterface::setSynchronousWindowSystemEvents(true); QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); + QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } +QWindowSystemEventHandler::~QWindowSystemEventHandler() +{ + QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this); +} + +bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) +{ + QGuiApplicationPrivate::processWindowSystemEvent(e); + return true; +} + + QT_END_NAMESPACE |
