summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qwindowsysteminterface.cpp
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@theqtcompany.com>2015-04-29 13:17:31 +0200
committerMorten Johan Sørvig <morten.sorvig@theqtcompany.com>2015-08-27 21:58:39 +0000
commitee767c838a0e0a91394a24b21d44d862d3b60416 (patch)
treee46613ec123541418fdc1d1bb244d86c350e4e38 /src/gui/kernel/qwindowsysteminterface.cpp
parentac9643c85ff829583c8be958b5eea4d543070882 (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.cpp33
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);