From 06e7d61b688778c47d2a29093384801ce6c9d55e Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 24 Sep 2013 19:40:44 +0200 Subject: [PATCH] Cocoa: Allow widgets to receive events event when no app is running MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is necessary for QMacNativeWidget, where there exists a QApplication, but is never executed. This directly translates in calls to the event dispatcher's processEvents() function, whose calls we keep track. If no calls have been made, we always allow timer and posted events to be processed. Change-Id: Ia0062ee8c59a2572082f520a2eb85ed44a9856a7 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 1 + src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 93476ee1b4..33d7dcbcf4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -165,6 +165,7 @@ public: bool currentExecIsNSAppRun; bool nsAppRunCalledByQt; bool cleanupModalSessionsNeeded; + uint processEventsCalled; NSModalSession currentModalSessionCached; NSModalSession currentModalSession(); void updateChildrenWorksWhenModal(); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 8dfaacdf13..ee69cd7d86 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -118,7 +118,7 @@ static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) void QCocoaEventDispatcherPrivate::runLoopTimerCallback(CFRunLoopTimerRef, void *info) { QCocoaEventDispatcherPrivate *d = static_cast(info); - if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) { + if (d->processEventsCalled && (d->processEventsFlags & QEventLoop::EventLoopExec) == 0) { // processEvents() was called "manually," ignore this source for now d->maybeCancelWaitForMoreEvents(); return; @@ -364,6 +364,12 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) uint oldflags = d->processEventsFlags; d->processEventsFlags = flags; + + // Used to determine whether any eventloop has been exec'ed, and allow posted + // and timer events to be processed even if this function has never been called + // instead of being kept on hold for the next run of processEvents(). + ++d->processEventsCalled; + bool excludeUserEvents = d->processEventsFlags & QEventLoop::ExcludeUserInputEvents; bool retVal = false; forever { @@ -517,6 +523,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) } d->processEventsFlags = oldflags; + --d->processEventsCalled; // If we're interrupted, we need to interrupt the _current_ // recursion as well to check if it is still supposed to be @@ -770,6 +777,7 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() currentExecIsNSAppRun(false), nsAppRunCalledByQt(false), cleanupModalSessionsNeeded(false), + processEventsCalled(0), currentModalSessionCached(0), lastSerial(-1), interrupt(false) @@ -893,7 +901,7 @@ void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref, void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info) { QCocoaEventDispatcherPrivate *d = static_cast(info); - if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) { + if (d->processEventsCalled && (d->processEventsFlags & QEventLoop::EventLoopExec) == 0) { // processEvents() was called "manually," ignore this source for now d->maybeCancelWaitForMoreEvents(); return;