summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-08-15 12:53:16 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-12 12:32:14 +0200
commit1ec37184329afa1c76141a3663f6adb5536fd051 (patch)
treeaf566ead6ae12d0f7e8a8205e219a12fb022d796 /src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
parentfc538bce4a14a184f625208d8c06d1a874d8e0a2 (diff)
iOS: Rewrite CoreFoundation event-dispatcher
Instead of having separate code-paths for QEventLoop::EventLoopExec and the non-blocking processEvent() we now have a single Q_FOREVER loop where the logic can be shared. We make multiple loop-passes, each time calling CFRunLoopRunInMode with potentially different arguments, depending on the result of the previous run. For the EventLoopExec case we'll continue making loop-passes until the event-loop has been interrupted. For the non-EventLoopExec case, we respect interruption, but will continue making loop-passes only until we've processed all events in the queue, optionally waiting for the initial event if WaitForMoreEvents is set. Limitations in the CoreFoundation APIs unfortunately force us to keep some state on whether or not we've processed events and timers for a given processEvents() pass (with corresponding deferred scheduling of timers and event source signaling). The way we handle timers has also been rewritten to no longer defer the timer activation to a special timer source. The constraint of CoreFoundation timers is that they can not recurse (re-fire) in a callback, but that only applies per timer, so using multiple CF timers allows us to recurse. We still only use a single CF timer for all the Qt timers though, and only spawn a new CF timer if the user calls processEvents() inside a timer callback. This commit removes the logic related to dealing with UITrackingMode, as that logic was slighly problematic, but the feature will be added back in a follow-up commit, in line with the new approach. The result of this commit is that we're passing all event-loop, event-dispatcher, and timer auto-tests, both for the QtCore dispatcher and the GUI event-dispatcher. Change-Id: I3c56fbc7857a25110064681257abb47075b5bd2d Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h')
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
index e23b8f0ece..bd62927f09 100644
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
+++ b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
@@ -76,8 +76,11 @@
#ifndef QEVENTDISPATCHER_CF_P_H
#define QEVENTDISPATCHER_CF_P_H
+#define DEBUG_EVENT_DISPATCHER 0
+
#include <QtCore/qabstracteventdispatcher.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
+#include <QtCore/qdebug.h>
#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
#include <CoreFoundation/CoreFoundation.h>
@@ -200,29 +203,55 @@ public:
void flush();
private:
- bool m_interrupted;
-
RunLoopSource<> m_postedEventsRunLoopSource;
- RunLoopSource<> m_blockingTimerRunLoopSource;
-
- RunLoopObserver<> m_awakeAndBlockObserver;
+ RunLoopObserver<> m_runLoopActivityObserver;
QTimerInfoList m_timerInfoList;
- CFRunLoopTimerRef m_runLoopTimerRef;
+ CFRunLoopTimerRef m_runLoopTimer;
+ CFRunLoopTimerRef m_blockedRunLoopTimer;
+ bool m_overdueTimerScheduled;
QCFSocketNotifier m_cfSocketNotifier;
- void processPostedEvents();
- void processTimers();
+ struct ProcessEventsState
+ {
+ ProcessEventsState(QEventLoop::ProcessEventsFlags f)
+ : flags(f), wasInterrupted(false)
+ , processedPostedEvents(false), processedTimers(false)
+ , deferredWakeUp(false), deferredUpdateTimers(false) {}
- void maybeStartCFRunLoopTimer();
- void maybeStopCFRunLoopTimer();
+ QEventLoop::ProcessEventsFlags flags;
+ bool wasInterrupted;
+ bool processedPostedEvents;
+ bool processedTimers;
+ bool deferredWakeUp;
+ bool deferredUpdateTimers;
+ };
+
+ ProcessEventsState m_processEvents;
+
+ void processPostedEvents();
+ void processTimers(CFRunLoopTimerRef);
void handleRunLoopActivity(CFRunLoopActivity activity);
- static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info);
+ void updateTimers();
+ void invalidateTimer();
};
QT_END_NAMESPACE
+#if DEBUG_EVENT_DISPATCHER
+extern uint g_eventDispatcherIndentationLevel;
+#define qEventDispatcherDebug() qDebug().nospace() \
+ << qPrintable(QString(QLatin1String("| ")).repeated(g_eventDispatcherIndentationLevel)) \
+ << __FUNCTION__ << "(): "
+#define qIndent() ++g_eventDispatcherIndentationLevel
+#define qUnIndent() --g_eventDispatcherIndentationLevel
+#else
+#define qEventDispatcherDebug() QT_NO_QDEBUG_MACRO()
+#define qIndent()
+#define qUnIndent()
+#endif
+
#endif // QEVENTDISPATCHER_CF_P_H