]> git.saurik.com Git - wxWidgets.git/commitdiff
streamlining OSX event support third step, using platform specific native run methods...
authorStefan Csomor <csomor@advancedconcepts.ch>
Wed, 17 Mar 2010 07:14:03 +0000 (07:14 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Wed, 17 Mar 2010 07:14:03 +0000 (07:14 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63697 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/evtloop.h
include/wx/osx/carbon/evtloop.h
include/wx/osx/cocoa/evtloop.h
include/wx/osx/evtloop.h
include/wx/unix/evtloop.h
src/common/evtloopcmn.cpp
src/osx/carbon/evtloop.cpp
src/osx/cocoa/evtloop.mm
src/osx/core/evtloop_cf.cpp
src/osx/iphone/evtloop.mm

index 6da21416a5cb258fe560d0db00cad52b29b49620..642cc128f0a2d6621a8acd01ab74a2021b3c91e4 100644 (file)
@@ -185,7 +185,7 @@ protected:
     wxDECLARE_NO_COPY_CLASS(wxEventLoopBase);
 };
 
-#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || defined(__UNIX__)
+#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || (defined(__UNIX__) && !defined(__WXOSX__))
 
 // this class can be used to implement a standard event loop logic using
 // Pending() and Dispatch()
@@ -318,7 +318,7 @@ protected:
 
 inline bool wxEventLoopBase::IsRunning() const { return GetActive() == this; }
 
-#if wxUSE_GUI
+#if wxUSE_GUI && !defined(__WXOSX__)
 // ----------------------------------------------------------------------------
 // wxModalEventLoop
 // ----------------------------------------------------------------------------
index 0824ca263696b7b982fcd74f885fad682822b977..3ebda2efa8e0851d146de1738ed83ae634a3010f 100644 (file)
@@ -23,6 +23,9 @@ public:
 protected:
     virtual int DoDispatchTimeout(unsigned long timeout);
 
+    virtual void DoRun();
+    
+    virtual void DoStop();
 };
 
 #endif // _WX_MAC_CARBON_EVTLOOP_H_
index be4e788bbb0fb778c5eefc60daa488314393d699..79c25c2b00f9494583d0160f859c11c6bdb75905 100644 (file)
@@ -19,6 +19,9 @@ public:
 protected:
     virtual int DoDispatchTimeout(unsigned long timeout);
     
+    virtual void DoRun();
+
+    virtual void DoStop();
 };
 
 #endif // _WX_OSX_COCOA_EVTLOOP_H_
index 100804ae2aea992d9344fb32358756fe1f26ff17..bc6b5fddfe9a51502c3d9db9eb2f6defb10c5f04 100644 (file)
@@ -59,7 +59,11 @@ protected:
     virtual CFRunLoopRef CFGetCurrentRunLoop() const;
 
     virtual int DoDispatchTimeout(unsigned long timeout);
+    
+    virtual void DoRun();
 
+    virtual void DoStop();
+    
     // should we exit the loop?
     bool m_shouldExit;
 
@@ -68,22 +72,40 @@ protected:
     
     // runloop observer
     CFRunLoopObserverRef m_runLoopObserver;
-
+    
 private:
     // process all already pending events and dispatch a new one (blocking
     // until it appears in the event queue if necessary)
     //
     // returns the return value of DoDispatchTimeout()
     int DoProcessEvents();
-
 };
 
 #if wxUSE_GUI
-    #ifdef __WXOSX_COCOA__
-        #include "wx/osx/cocoa/evtloop.h"
-    #else
-        #include "wx/osx/carbon/evtloop.h"
-    #endif
+
+#ifdef __WXOSX_COCOA__
+    #include "wx/osx/cocoa/evtloop.h"
+#else
+    #include "wx/osx/carbon/evtloop.h"
+#endif
+
+class WXDLLIMPEXP_FWD_CORE wxWindow;
+class WXDLLIMPEXP_FWD_CORE wxNonOwnedWindow;
+
+class WXDLLIMPEXP_CORE wxModalEventLoop : public wxGUIEventLoop
+{
+public:
+    wxModalEventLoop(wxWindow *winModal);
+    
+protected:
+    virtual void DoRun();
+    
+    virtual void DoStop();
+    
+    // (in case) the modal window for this event loop
+    wxNonOwnedWindow* m_modalWindow;
+};
+
 #endif // wxUSE_GUI
 
 #endif // _WX_OSX_EVTLOOP_H_
index 40d30077874b5e3a96032ea070611e95b85213a2..1c47c5cd55c6b033c3e8dc98da61d5f679cd8270 100644 (file)
@@ -25,7 +25,12 @@ namespace wxPrivate
     class PipeIOHandler;
 }
 
-class WXDLLIMPEXP_BASE wxConsoleEventLoop : public wxEventLoopManual
+class WXDLLIMPEXP_BASE wxConsoleEventLoop 
+#ifdef __WXOSX__
+: public wxEventLoopBase
+#else
+: public wxEventLoopManual
+#endif
 {
 public:
     // initialize the event loop, use IsOk() to check if we were successful
index 5f9894d12501b99563129bcd4b3a1d8005627106..300a1885d1904eeb1d506a2d84d15a99b73cf07f 100644 (file)
@@ -82,7 +82,7 @@ bool wxEventLoopBase::Yield(bool onlyIfNeeded)
 }
 
 // wxEventLoopManual is unused in the other ports
-#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__WXDFB__) || (defined(__UNIX__) && wxUSE_BASE)
+#if defined(__WXMSW__) || defined(__WXDFB__) || ( ( defined(__UNIX__) && !defined(__WXOSX__) ) && wxUSE_BASE)
 
 // ============================================================================
 // wxEventLoopManual implementation
index abaafd3181f7d4a72946575c58c656aee273ef54..218b945b413d5cce666dd0361fea184330a1c5ab 100644 (file)
@@ -55,6 +55,8 @@ static void DispatchAndReleaseEvent(EventRef theEvent)
 
 int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
 {
+    wxMacAutoreleasePool autoreleasepool;
+    
     EventRef event;
     OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
     switch ( status )
@@ -76,3 +78,56 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
             return 1;
     }
 }
+
+void wxGUIEventLoop::DoRun()
+{
+    wxMacAutoreleasePool autoreleasepool;
+    RunApplicationEventLoop();
+}
+
+void wxGUIEventLoop::DoStop()
+{
+    QuitApplicationEventLoop();
+}
+
+void wxModalEventLoop::DoRun()
+{
+    wxMacAutoreleasePool autoreleasepool;
+    WindowRef windowRef = m_modalWindow->GetWXWindow();
+
+    WindowGroupRef windowGroup = NULL;
+    WindowGroupRef formerParentGroup = NULL;
+    bool resetGroupParent = false;
+    
+    // make sure modal dialogs are in the right layer so that they are not covered
+    
+    if ( m_modalWindow->GetParent() == NULL )
+    {
+        windowGroup = GetWindowGroup(windowRef) ;
+        if ( windowGroup != GetWindowGroupOfClass( kMovableModalWindowClass ) )
+        {
+            formerParentGroup = GetWindowGroupParent( windowGroup );
+            SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) );
+            resetGroupParent = true;
+        }
+    }
+
+    m_modalWindow->SetFocus();
+    
+    RunAppModalLoopForWindow(windowRef);
+
+    if ( resetGroupParent )
+    {
+        SetWindowGroupParent( windowGroup , formerParentGroup );
+    }
+
+}
+
+void wxModalEventLoop::DoStop()
+{
+    wxMacAutoreleasePool autoreleasepool;
+    WindowRef theWindow = m_modalWindow->GetWXWindow();
+    QuitAppModalLoopForWindow(theWindow);
+}
+
+
index 69c550b6d05cbe8c7e40b83291acf0c401203e7f..97a3b763300e8c36850c5d190db2773fce21b97c 100644 (file)
@@ -162,3 +162,40 @@ int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
 
     return 1;
 }
+
+void wxGUIEventLoop::DoRun()
+{
+    wxMacAutoreleasePool autoreleasepool;
+    [NSApp run];
+}
+
+void wxGUIEventLoop::DoStop()
+{
+    [NSApp stop:0];
+}
+
+void wxModalEventLoop::DoRun()
+{
+    wxMacAutoreleasePool pool;
+
+    // If the app hasn't started, flush the event queue
+    // If we don't do this, the Dock doesn't get the message that
+    // the app has started so will refuse to activate it.
+    [NSApplication sharedApplication];
+    if (![NSApp isRunning])
+    {
+        while(NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
+        {
+            [NSApp sendEvent:event];
+        }
+    }
+    
+    NSWindow* theWindow = m_modalWindow->GetWXWindow();
+    [NSApp runModalForWindow:theWindow];
+}
+
+void wxModalEventLoop::DoStop()
+{
+    [NSApp stopModal];
+}
+
index d16ed3ea2e23af2ccc320f52a466ffa5ba8e2846..429312ac8871b2c570a716bfb6808859e0047ed4 100644 (file)
@@ -185,6 +185,7 @@ void wxCFEventLoop::ObserverCallBack(CFRunLoopObserverRef observer, int activity
 wxCFEventLoop::wxCFEventLoop()
 {
     m_shouldExit = false;
+    
     CFRunLoopObserverContext ctxt;
     bzero( &ctxt, sizeof(ctxt) );
     ctxt.info = this;
@@ -272,8 +273,6 @@ int wxCFEventLoop::DispatchTimeout(unsigned long timeout)
     if ( !wxTheApp )
         return 0;
 
-    wxMacAutoreleasePool autoreleasepool;
-    
     int status = DoDispatchTimeout(timeout);
     
     switch( status )
@@ -313,6 +312,32 @@ int wxCFEventLoop::DoDispatchTimeout(unsigned long timeout)
     return 1;
 }
 
+void wxCFEventLoop::DoRun()
+{
+    for ( ;; )
+    {
+        // generate and process idle events for as long as we don't
+        // have anything else to do
+        DoProcessEvents();
+        
+        // if the "should exit" flag is set, the loop should terminate
+        // but not before processing any remaining messages so while
+        // Pending() returns true, do process them
+        if ( m_shouldExit )
+        {
+            while ( DoProcessEvents() == 1 )
+                ;
+            
+            break;
+        }
+    }
+}
+
+void wxCFEventLoop::DoStop()
+{
+    CFRunLoopStop(CFGetCurrentRunLoop());
+}
+
 // enters a loop calling OnNextIteration(), Pending() and Dispatch() and
 // terminating when Exit() is called
 int wxCFEventLoop::Run()
@@ -336,23 +361,8 @@ int wxCFEventLoop::Run()
         try
         {
 #endif // wxUSE_EXCEPTIONS
-            for ( ;; )
-            {
-                // generate and process idle events for as long as we don't
-                // have anything else to do
-                DoProcessEvents();
             
-                // if the "should exit" flag is set, the loop should terminate
-                // but not before processing any remaining messages so while
-                // Pending() returns true, do process them
-                if ( m_shouldExit )
-                {
-                    while ( DoProcessEvents() == 1 )
-                        ;
-                    
-                    break;
-                }
-            }
+            DoRun();
             
 #if wxUSE_EXCEPTIONS
             // exit the outer loop as well
@@ -390,6 +400,29 @@ void wxCFEventLoop::Exit(int rc)
 {
     m_exitcode = rc;
     m_shouldExit = true;
+    DoStop();
+}
+
+#if wxUSE_GUI
+
+wxModalEventLoop::wxModalEventLoop(wxWindow *winModal)
+{
+    m_modalWindow = dynamic_cast<wxNonOwnedWindow*> (winModal);
+    wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
 }
 
+#ifdef __WXOSX_IPHONE__
 
+void wxModalEventLoop::DoRun()
+{
+    // presentModalViewController:animated:
+}
+
+void wxModalEventLoop::DoStop()
+{
+    // (void)dismissModalViewControllerAnimated:(BOOL)animated
+}
+
+#endif // wxUSE_GUI
+
+#endif
index 67e4784965945b5d4c733fae2c0df6ccff7cc2c9..ca463a6dcf5bcf205a88232a783d491e32069c7f 100644 (file)
@@ -75,26 +75,43 @@ static int CalculateUIEventMaskFromEventCategory(wxEventCategory cat)
 }
 */
 
-wxGUIEventLoop::wxGUIEventLoop()
-{
-    m_sleepTime = 0.0;
+@interface wxAppDelegate : NSObject <UIApplicationDelegate> {
 }
 
-int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
-{
-    wxMacAutoreleasePool autoreleasepool;
+@end
 
-/*
-    UIEvent *event = [[UIApplication sharedApplication]
-                nextEventMatchingMask:NSAnyEventMask
-                untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
-                inMode:NSDefaultRunLoopMode
-                dequeue: YES];
+@implementation wxAppDelegate
 
-    if ( event == nil )
-        return -1;
+- (void)applicationDidFinishLaunching:(UIApplication *)application {   
+       wxTheApp->OnInit();
+}
 
-    [NSApp sendEvent: event];
-*/
-    return 1;
+- (void)applicationWillTerminate:(UIApplication *)application { 
+    wxCloseEvent event;
+    wxTheApp->OnEndSession(event);
+}
+
+- (void)dealloc {
+       [super dealloc];
 }
+
+@end
+
+wxGUIEventLoop::wxGUIEventLoop()
+{
+}
+
+void wxGUIEventLoop::DoRun()
+{
+    if ( IsMain() )
+    {
+        wxMacAutoreleasePool pool;
+        const char* appname = "app";
+        UIApplicationMain( 1, (char**) &appname, nil, @"wxAppDelegate" );
+    }
+    else 
+    {
+        wxCFEventLoop::DoRun();
+    }
+}
+