+// CFRunLoopRef cfRunLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
+ CFRunLoopRef cfRunLoop = CFRunLoopGetCurrent();
+ wxCFRef<CFStringRef> cfRunLoopMode(CFRunLoopCopyCurrentMode(cfRunLoop));
+
+ /* If we have an observer and that observer is for the wrong run loop
+ mode then invalidate it and release it.
+ */
+ if(m_cfRunLoopIdleObserver != NULL && m_cfObservedRunLoopMode != cfRunLoopMode)
+ {
+ CFRunLoopObserverInvalidate(m_cfRunLoopIdleObserver);
+ m_cfRunLoopIdleObserver.reset();
+ }
+#if 0
+ ++sg_cApplicationWillUpdate;
+#endif
+ /* This will be true either on the first call or when the above code has
+ invalidated and released the exisiting observer.
+ */
+ if(m_cfRunLoopIdleObserver == NULL)
+ {
+ // Enable idle event handling
+ CFRunLoopObserverContext observerContext =
+ { 0
+ , this
+ , NULL
+ , NULL
+ , NULL
+ };
+ /* NOTE: I can't recall why we don't just let the observer repeat
+ instead of invalidating itself each time it fires thus requiring
+ it to be recreated for each shot but there was if I remember
+ some good (but very obscure) reason for it.
+
+ On the other hand, I could be wrong so don't take that as gospel.
+ */
+ m_cfRunLoopIdleObserver.reset(CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, /*repeats*/FALSE, /*priority*/0, ObserveMainRunLoopBeforeWaiting, &observerContext));
+ m_cfObservedRunLoopMode = cfRunLoopMode;
+ CFRunLoopAddObserver(cfRunLoop, m_cfRunLoopIdleObserver, m_cfObservedRunLoopMode);
+ }
+}
+
+static inline bool FakeNeedMoreIdle()
+{
+#if 0
+// Return true on every 10th call.
+ static int idleCount = 0;
+ return ++idleCount % 10;
+#else
+ return false;
+#endif
+}
+
+/*!
+ Called by CFRunLoop just before waiting. This is the appropriate time to
+ send idle events. Unlike other ports, we don't peek the queue for events
+ and stop idling if there is one. Instead, if the user requests more idle
+ events we tell Cocoa to send us an applicationWillUpdate notification
+ which will cause our observer of that notification to tell CFRunLoop to
+ call us before waiting which will cause us to be fired again but only
+ after exhausting the event queue.
+
+ The reason we do it this way is that peeking for an event causes CFRunLoop
+ to reenter and fire off its timers, observers, and sources which we're
+ better off avoiding. Doing it this way, we basically let CFRunLoop do the
+ work of peeking for the next event which is much nicer.
+ */
+void wxApp::CF_ObserveMainRunLoopBeforeWaiting(CFRunLoopObserverRef observer, int activity)
+{
+ // Ensure that CocoaDelegate_applicationWillUpdate will recreate us.
+ // We've already been invalidated by CFRunLoop because we are one-shot.
+ m_cfRunLoopIdleObserver.reset();
+#if 0
+ wxLogTrace(wxTRACE_COCOA,wxT("Idle BEGIN (%d)"), sg_cApplicationWillUpdate);
+ sg_cApplicationWillUpdate = 0;
+#else
+ wxLogTrace(wxTRACE_COCOA,wxT("Idle BEGIN"));
+#endif
+ if( ProcessIdle() || FakeNeedMoreIdle() )
+ {
+ wxLogTrace(wxTRACE_COCOA, wxT("Idle REQUEST MORE"));
+ [NSApp setWindowsNeedUpdate:YES];
+ }
+ else
+ {
+ wxLogTrace(wxTRACE_COCOA, wxT("Idle END"));