iOS: Only use root level native runloop if at first level of processEvents
We used to support calling QEventLoop::exec() from within a processEvent recursion and still jump down to the root native runloop, but this does not work as intended due to how QEventDispatcherCoreFoundation uses flags in its ProcessEventsState for e.g. deferred wake up or timer updates. The logic in QEventDispatcherCoreFoundation assumes that the next recursion to processEvents will be handled by itself, so that it can interpret the flags in ProcessEventsState. The iOS event dispatcher subclass, QIOSEventDispatcher, does neither of these things, and should only be used from a 'clean' state. Change-Id: I44fa156feecc45772806002465c35bef0797ead2 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com>
This commit is contained in:
parent
4c542ab592
commit
dfd6fc7bce
@ -52,7 +52,7 @@ public:
|
||||
void interruptEventLoopExec();
|
||||
|
||||
private:
|
||||
uint m_processEventCallsAfterExec;
|
||||
uint m_processEventLevel;
|
||||
RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver;
|
||||
};
|
||||
|
||||
|
@ -422,7 +422,7 @@ QT_USE_NAMESPACE
|
||||
|
||||
QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
|
||||
: QEventDispatcherCoreFoundation(parent)
|
||||
, m_processEventCallsAfterExec(0)
|
||||
, m_processEventLevel(0)
|
||||
, m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit)
|
||||
{
|
||||
}
|
||||
@ -439,8 +439,8 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_processEventCallsAfterExec && (flags & QEventLoop::EventLoopExec)) {
|
||||
++m_processEventCallsAfterExec;
|
||||
if (!m_processEventLevel && (flags & QEventLoop::EventLoopExec)) {
|
||||
++m_processEventLevel;
|
||||
|
||||
m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes);
|
||||
|
||||
@ -465,13 +465,9 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
if (m_processEventCallsAfterExec)
|
||||
++m_processEventCallsAfterExec;
|
||||
|
||||
++m_processEventLevel;
|
||||
bool processedEvents = QEventDispatcherCoreFoundation::processEvents(flags);
|
||||
|
||||
if (m_processEventCallsAfterExec)
|
||||
--m_processEventCallsAfterExec;
|
||||
--m_processEventLevel;
|
||||
|
||||
return processedEvents;
|
||||
}
|
||||
@ -481,7 +477,7 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
||||
Q_UNUSED(activity);
|
||||
Q_ASSERT(activity == kCFRunLoopExit);
|
||||
|
||||
if (m_processEventCallsAfterExec == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) {
|
||||
if (m_processEventLevel == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) {
|
||||
qEventDispatcherDebug() << "Root runloop level exited";
|
||||
interruptEventLoopExec();
|
||||
}
|
||||
@ -489,9 +485,9 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
||||
|
||||
void QIOSEventDispatcher::interruptEventLoopExec()
|
||||
{
|
||||
Q_ASSERT(m_processEventCallsAfterExec == 1);
|
||||
Q_ASSERT(m_processEventLevel == 1);
|
||||
|
||||
--m_processEventCallsAfterExec;
|
||||
--m_processEventLevel;
|
||||
|
||||
m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user