diff options
author | Morten Johan Sørvig <morten.sorvig@theqtcompany.com> | 2015-04-29 13:17:31 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@theqtcompany.com> | 2015-08-27 21:58:39 +0000 |
commit | ee767c838a0e0a91394a24b21d44d862d3b60416 (patch) | |
tree | e46613ec123541418fdc1d1bb244d86c350e4e38 /src/gui/kernel/qwindowsysteminterface.cpp | |
parent | ac9643c85ff829583c8be958b5eea4d543070882 (diff) |
Implement threaded synchronous WS events
Make handleWindowSystemEvent() support being called
from secondary threads in synchronousWindowSystemEvent
mode.
This is implemented by posting the event to the Gui
event queue (which will wake the Qt Gui thread), and
then calling flushWindowSystemEvents which will block
the calling thread until the event has been processed.
Change-Id: I7e8e68c1e0290c17105563268e316b0f8205b3ce
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'src/gui/kernel/qwindowsysteminterface.cpp')
-rw-r--r-- | src/gui/kernel/qwindowsysteminterface.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 01f4be6dd0..0a9da737dc 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -442,18 +442,33 @@ void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *e windowSystemEventQueue.remove(event); } +void QWindowSystemInterfacePrivate::postWindowSystemEvent(WindowSystemEvent *ev) +{ + windowSystemEventQueue.append(ev); + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher(); + if (dispatcher) + dispatcher->wakeUp(); +} + bool QWindowSystemInterfacePrivate::handleWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *ev) { bool accepted = true; if (synchronousWindowSystemEvents) { - QGuiApplicationPrivate::processWindowSystemEvent(ev); - accepted = ev->eventAccepted; - delete ev; + 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; } @@ -636,9 +651,11 @@ bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFl 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); |