diff options
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 36 |
2 files changed, 28 insertions, 11 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index e842468c7b..a4a1286fab 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -149,6 +149,8 @@ class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate public: QCocoaEventDispatcherPrivate(); + uint processEventsFlags; + // timer handling QTimerInfoList timerInfoList; CFRunLoopTimerRef runLoopTimerRef; @@ -173,6 +175,7 @@ public: void beginModalSession(QWindow *widget); void endModalSession(QWindow *widget); void cancelWaitForMoreEvents(); + void maybeCancelWaitForMoreEvents(); void cleanupModalSessions(); void ensureNSAppInitialized(); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index dbb8625aeb..6de22cf58c 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -114,6 +114,7 @@ void QCocoaEventDispatcherPrivate::activateTimer(CFRunLoopTimerRef, void *info) QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info); (void) d->timerInfoList.activateTimers(); d->maybeStartCFRunLoopTimer(); + d->maybeCancelWaitForMoreEvents(); } void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer() @@ -275,6 +276,8 @@ void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CF if (socketInfo->writeNotifier) QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); } + + eventDispatcher->maybeCancelWaitForMoreEvents(); } /* @@ -508,13 +511,12 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) bool interruptLater = false; QtCocoaInterruptDispatcher::cancelInterruptLater(); - // In case we end up recursing while we now process events, make sure - // that we send remaining posted Qt events before this call returns: - wakeUp(); emit awake(); bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool retVal = false; + uint oldflags = d->processEventsFlags; + d->processEventsFlags = flags; forever { if (d->interrupt) break; @@ -567,6 +569,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } retVal = true; } else { + bool hadModalSession = d->currentModalSessionCached != 0; // We cannot block the thread (and run in a tight loop). // Instead we will process all current pending events and return. d->ensureNSAppInitialized(); @@ -628,17 +631,13 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } } while (!d->interrupt && event != nil); - // Be sure to flush the Qt posted events when not using exec mode - // (exec mode will always do this call from the event loop source): - if (!d->interrupt) - QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); - // Since the window that holds modality might have changed while processing // events, we we need to interrupt when we return back the previous process // event recursion to ensure that we spin the correct modal session. // We do the interruptLater at the end of the function to ensure that we don't // disturb the 'wait for more events' below (as deleteLater will post an event): - interruptLater = true; + if (hadModalSession && d->currentModalSessionCached == 0) + interruptLater = true; } bool canWait = (d->threadData->canWait && !retVal @@ -656,6 +655,8 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } } + d->processEventsFlags = oldflags; + // If we're interrupted, we need to interrupt the _current_ // recursion as well to check if it is still supposed to be // executing. This way we wind down the stack until we land @@ -878,7 +879,8 @@ void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window) } QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() - : runLoopTimerRef(0), + : processEventsFlags(0), + runLoopTimerRef(0), blockSendPostedEvents(false), currentExecIsNSAppRun(false), nsAppRunCalledByQt(false), @@ -1007,7 +1009,9 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref, void QCocoaEventDispatcherPrivate::postedEventsSourcePerformCallback(void *info) { - static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents(); + QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info); + d->processPostedEvents(); + d->maybeCancelWaitForMoreEvents(); } void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents() @@ -1020,6 +1024,16 @@ void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents() subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO]; } +void QCocoaEventDispatcherPrivate::maybeCancelWaitForMoreEvents() +{ + if ((processEventsFlags & (QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents)) == QEventLoop::WaitForMoreEvents) { + // RunLoop sources are not NSEvents, but they do generate Qt events. If + // WaitForMoreEvents was set, but EventLoopExec is not, processEvents() + // should return after a source has sent some Qt events. + cancelWaitForMoreEvents(); + } +} + void QCocoaEventDispatcher::interrupt() { Q_D(QCocoaEventDispatcher); |