diff options
Diffstat (limited to 'src/gui/kernel/qwindowsysteminterface.cpp')
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 118 |
1 files changed, 83 insertions, 35 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index b17978cb7d..17bce6c70f 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -45,9 +45,10 @@ QT_BEGIN_NAMESPACE QElapsedTimer QWindowSystemInterfacePrivate::eventTime; -bool QWindowSystemInterfacePrivate::synchronousWindowsSystemEvents = false; +bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false; QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed; QMutex QWindowSystemInterfacePrivate::flushEventMutex; +QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler; //------------------------------------------------------------ // @@ -93,14 +94,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); } } @@ -425,8 +426,9 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e void QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev) { - if (synchronousWindowsSystemEvents) { + if (synchronousWindowSystemEvents) { QGuiApplicationPrivate::processWindowSystemEvent(ev); + delete ev; } else { windowSystemEventQueue.append(ev); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher(); @@ -453,6 +455,7 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints 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) { @@ -604,17 +607,35 @@ 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); + } 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() @@ -790,13 +811,26 @@ 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); +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); } 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) { - QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count); + 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); } 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) @@ -804,35 +838,49 @@ 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<struct QWindowSystemInterface::TouchPoint> touchPointList(const QList<QTouchEvent::TouchPoint>& pointList) + +Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, + const QList<QTouchEvent::TouchPoint> &points, + Qt::KeyboardModifiers mods = Qt::NoModifier) { - QList<struct QWindowSystemInterface::TouchPoint> newList; + 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; - Q_FOREACH (QTouchEvent::TouchPoint p, pointList) - { - newList.append(touchPoint(p)); + QList<QTouchEvent::TouchPoint>::const_iterator point = points.constBegin(); + QList<QTouchEvent::TouchPoint>::const_iterator end = points.constEnd(); + while (point != end) { + states |= point->state(); + ++point; } - return newList; + + // 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); } -Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, - const QList<QTouchEvent::TouchPoint> &points, - Qt::KeyboardModifiers mods = Qt::NoModifier) +QWindowSystemEventHandler::~QWindowSystemEventHandler() +{ + QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this); +} + +bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) { - QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); + QGuiApplicationPrivate::processWindowSystemEvent(e); + return true; } QT_END_NAMESPACE |