]> git.saurik.com Git - wxWidgets.git/commitdiff
streamlining OSX event support second step, moving pending and idle event handling...
authorStefan Csomor <csomor@advancedconcepts.ch>
Mon, 15 Mar 2010 19:31:57 +0000 (19:31 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Mon, 15 Mar 2010 19:31:57 +0000 (19:31 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63689 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/osx/evtloop.h
src/osx/core/evtloop_cf.cpp

index 5ddb819d5533117b648d1daab5200492e178ad65..100804ae2aea992d9344fb32358756fe1f26ff17 100644 (file)
@@ -13,7 +13,8 @@
 #ifndef _WX_OSX_EVTLOOP_H_
 #define _WX_OSX_EVTLOOP_H_
 
-typedef struct __CFRunLoop * CFRunLoopRef;
+DECLARE_WXOSX_OPAQUE_CFREF( CFRunLoop );
+DECLARE_WXOSX_OPAQUE_CFREF( CFRunLoopObserver );
 
 class WXDLLIMPEXP_BASE wxCFEventLoop : public wxEventLoopBase
 {
@@ -28,7 +29,7 @@ public:
     // sets the "should exit" flag and wakes up the loop so that it terminates
     // soon
     virtual void Exit(int rc = 0);
-
+    
     // return true if any events are available
     virtual bool Pending() const;
     
@@ -51,19 +52,22 @@ public:
       AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags);
 #endif // wxUSE_EVENTLOOP_SOURCE
 
+    void ObserverCallBack(CFRunLoopObserverRef observer, int activity);
+
 protected:
     // get the currently executing CFRunLoop
     virtual CFRunLoopRef CFGetCurrentRunLoop() const;
 
     virtual int DoDispatchTimeout(unsigned long timeout);
 
-    double m_sleepTime;
-
     // should we exit the loop?
     bool m_shouldExit;
 
     // the loop exit code
     int m_exitcode;
+    
+    // runloop observer
+    CFRunLoopObserverRef m_runLoopObserver;
 
 private:
     // process all already pending events and dispatch a new one (blocking
@@ -71,6 +75,7 @@ private:
     //
     // returns the return value of DoDispatchTimeout()
     int DoProcessEvents();
+
 };
 
 #if wxUSE_GUI
index 3bd0c3c73371514cfa48397a6117983e66fa75aa..d16ed3ea2e23af2ccc320f52a466ffa5ba8e2846 100644 (file)
@@ -142,10 +142,55 @@ wxCFEventLoop::AddSourceForFD(int WXUNUSED(fd),
 
 #endif // wxUSE_EVENTLOOP_SOURCE
 
+void wxObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
+{
+    wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
+    if ( eventloop )
+        eventloop->ObserverCallBack(observer, activity);
+}        
+
+void wxCFEventLoop::ObserverCallBack(CFRunLoopObserverRef observer, int activity)
+{
+    if ( activity & kCFRunLoopBeforeTimers )
+    {
+        // process pending wx events first as they correspond to low-level events
+        // which happened before, i.e. typically pending events were queued by a
+        // previous call to Dispatch() and if we didn't process them now the next
+        // call to it might enqueue them again (as happens with e.g. socket events
+        // which would be generated as long as there is input available on socket
+        // and this input is only removed from it when pending event handlers are
+        // executed)
+
+        if ( wxTheApp )
+            wxTheApp->ProcessPendingEvents();
+    }
+    
+    if ( activity & kCFRunLoopBeforeWaiting )
+    {
+        if ( ProcessIdle() )
+        {
+            WakeUp();
+        }
+        else
+        {
+#if wxUSE_THREADS
+            wxMutexGuiLeave();
+            wxMilliSleep(20);
+            wxMutexGuiEnter();
+#endif
+        }
+    }
+}
+
 wxCFEventLoop::wxCFEventLoop()
 {
     m_shouldExit = false;
-    m_sleepTime = 0.0;
+    CFRunLoopObserverContext ctxt;
+    bzero( &ctxt, sizeof(ctxt) );
+    ctxt.info = this;
+    m_runLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, 
+                                                wxObserverCallBack, &ctxt );
+    CFRunLoopAddObserver(CFGetCurrentRunLoop(), m_runLoopObserver, kCFRunLoopDefaultMode);
 }
 
 wxCFEventLoop::~wxCFEventLoop()
@@ -155,7 +200,7 @@ wxCFEventLoop::~wxCFEventLoop()
 
 CFRunLoopRef wxCFEventLoop::CFGetCurrentRunLoop() const
 {
-    return CFGetCurrentRunLoop();
+    return CFRunLoopGetCurrent();
 }
 
 void wxCFEventLoop::WakeUp()
@@ -214,22 +259,12 @@ bool wxCFEventLoop::Pending() const
 
 int wxCFEventLoop::DoProcessEvents()
 {
-    // process pending wx events first as they correspond to low-level events
-    // which happened before, i.e. typically pending events were queued by a
-    // previous call to Dispatch() and if we didn't process them now the next
-    // call to it might enqueue them again (as happens with e.g. socket events
-    // which would be generated as long as there is input available on socket
-    // and this input is only removed from it when pending event handlers are
-    // executed)
-    if ( wxTheApp )
-        wxTheApp->ProcessPendingEvents();
-    
-    return DispatchTimeout( (unsigned long)(m_sleepTime * 1000.0) );
+    return DispatchTimeout( 1000 );
 }
 
 bool wxCFEventLoop::Dispatch()
 {
-    return DispatchTimeout( (unsigned long)(m_sleepTime * 1000.0) ) != 0;
+    return DoProcessEvents() != 0;
 }
 
 int wxCFEventLoop::DispatchTimeout(unsigned long timeout)
@@ -249,20 +284,8 @@ int wxCFEventLoop::DispatchTimeout(unsigned long timeout)
             if ( m_shouldExit )
                 return 0;
             
-            if ( ProcessIdle() )
-                m_sleepTime = 0.0 ;
-            else
-            {
-                m_sleepTime = 1.0;
-#if wxUSE_THREADS
-                wxMutexGuiLeave();
-                wxMilliSleep(20);
-                wxMutexGuiEnter();
-#endif
-            }
             break;
         case 1:
-            m_sleepTime = 0;
             break;
     }
     
@@ -367,7 +390,6 @@ void wxCFEventLoop::Exit(int rc)
 {
     m_exitcode = rc;
     m_shouldExit = true;
-    m_sleepTime = 0;
 }