]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/app.cpp
process pending wx events before sending idle events
[wxWidgets.git] / src / mac / carbon / app.cpp
index e997cc3e1b15c2c447fe1035c176c85f1ccac924..d833bb02d7991dd3ae80f69dc13cc3cddf3aa80f 100644 (file)
@@ -133,6 +133,12 @@ pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon
     return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
 }
 
+pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+    return wxTheApp->MacHandleAEGURL((WXEVENTREF *)event , reply) ;
+}
+
+
 // AEODoc Calls MacOpenFile on each of the files passed
 
 short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
@@ -174,6 +180,31 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
     return noErr;
 }
 
+// AEODoc Calls MacOpenURL on the url passed
+
+short wxApp::MacHandleAEGURL(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
+{
+    DescType returnedType;
+    Size actualSize;
+    char url[255];
+    OSErr err = AEGetParamPtr((AppleEvent *)event, keyDirectObject, typeChar,
+                              &returnedType, url, sizeof(url)-1,
+                              &actualSize);
+    if (err != noErr)
+        return err;
+
+    url[actualSize] = '\0';    // Terminate the C string 
+
+    ProcessSerialNumber PSN ;
+    PSN.highLongOfPSN = 0 ;
+    PSN.lowLongOfPSN = kCurrentProcess ;
+    SetFrontProcess( &PSN ) ;
+
+    MacOpenURL(wxString(url, wxConvUTF8));
+
+    return noErr;
+}
+
 // AEPDoc Calls MacPrintFile on each of the files passed
 
 short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
@@ -264,6 +295,9 @@ void wxApp::MacOpenFile(const wxString & fileName )
 #endif
 }
 
+void wxApp::MacOpenURL(const wxString & url )
+{
+}
 
 void wxApp::MacPrintFile(const wxString & fileName )
 {
@@ -451,16 +485,17 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item )
         id = wxMacCommandToId( command.commandID ) ;
         // make sure it is one of our own menus, or of the 'synthetic' apple and help menus , otherwise don't touch
         MenuItemIndex firstUserHelpMenuItem ;
-        static MenuHandle mh = NULL ;
-        if ( mh == NULL )
+        static MenuHandle helpMenuHandle = NULL ;
+        if ( helpMenuHandle == NULL )
         {
-            if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) != noErr )
-                mh = NULL ;
+            if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) != noErr )
+                helpMenuHandle = NULL ;
         }
 
         // is it part of the application or the Help menu, then look for the id directly
         if ( ( GetMenuHandle( kwxMacAppleMenuId ) != NULL && command.menu.menuRef == GetMenuHandle( kwxMacAppleMenuId ) ) ||
-             ( mh != NULL && command.menu.menuRef == mh ) )
+             ( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) || 
+             wxMenuBar::MacGetWindowMenuHMenu() != NULL && command.menu.menuRef == wxMenuBar::MacGetWindowMenuHMenu() )
         {
             wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
             if ( mbar )
@@ -860,6 +895,7 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
 }
 
 AEEventHandlerUPP sODocHandler = NULL ;
+AEEventHandlerUPP sGURLHandler = NULL ;
 AEEventHandlerUPP sOAppHandler = NULL ;
 AEEventHandlerUPP sPDocHandler = NULL ;
 AEEventHandlerUPP sRAppHandler = NULL ;
@@ -882,6 +918,7 @@ bool wxApp::OnInitGui()
     if (!sm_isEmbedded)
     {
         sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ;
+        sGURLHandler = NewAEEventHandlerUPP(AEHandleGURL) ;
         sOAppHandler = NewAEEventHandlerUPP(AEHandleOApp) ;
         sPDocHandler = NewAEEventHandlerUPP(AEHandlePDoc) ;
         sRAppHandler = NewAEEventHandlerUPP(AEHandleRApp) ;
@@ -889,6 +926,8 @@ bool wxApp::OnInitGui()
 
         AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
                                sODocHandler , 0 , FALSE ) ;
+        AEInstallEventHandler( kInternetEventClass, kAEGetURL,
+                               sGURLHandler , 0 , FALSE ) ;
         AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
                                sOAppHandler , 0 , FALSE ) ;
         AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
@@ -937,6 +976,8 @@ void wxApp::CleanUp()
     {
         AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments ,
                                sODocHandler , FALSE ) ;
+        AERemoveEventHandler( kInternetEventClass, kAEGetURL,
+                               sGURLHandler , FALSE ) ;
         AERemoveEventHandler( kCoreEventClass , kAEOpenApplication ,
                                sOAppHandler , FALSE ) ;
         AERemoveEventHandler( kCoreEventClass , kAEPrintDocuments ,
@@ -947,6 +988,7 @@ void wxApp::CleanUp()
                                sQuitHandler , FALSE ) ;
 
         DisposeAEEventHandlerUPP( sODocHandler ) ;
+        DisposeAEEventHandlerUPP( sGURLHandler ) ;
         DisposeAEEventHandlerUPP( sOAppHandler ) ;
         DisposeAEEventHandlerUPP( sPDocHandler ) ;
         DisposeAEEventHandlerUPP( sRAppHandler ) ;
@@ -1094,12 +1136,7 @@ wxApp::wxApp()
 
 void wxApp::OnIdle(wxIdleEvent& event)
 {
-    wxAppBase::OnIdle(event);
-
-    // If they are pending events, we must process them: pending events are
-    // either events to the threads other than main or events posted with
-    // wxPostEvent() functions
-    wxMacProcessNotifierAndPendingEvents();
+    wxMacProcessNotifierEvents();
 
   if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
     wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
@@ -1154,6 +1191,15 @@ bool wxApp::Yield(bool onlyIfNeeded)
         return false;
     }
 
+#if wxUSE_THREADS
+    // Yielding from a non-gui thread needs to bail out, otherwise we end up
+    // possibly sending events in the thread too.
+    if ( !wxThread::IsMain() )
+    {
+        return true;
+    }
+#endif // wxUSE_THREADS
+
     s_inYield = true;
 
     // by definition yield should handle all non-processed events
@@ -1231,6 +1277,14 @@ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
     // Override to process unhandled events as you please
 }
 
+CFMutableArrayRef GetAutoReleaseArray()
+{
+    static CFMutableArrayRef array = 0;
+    if ( array == 0)
+        array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
+    return array;
+}
+
 void wxApp::MacHandleOneEvent( WXEVENTREF evr )
 {
     EventTargetRef theTarget;
@@ -1246,6 +1300,13 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr )
 #if wxUSE_THREADS
     wxMutexGuiLeaveOrEnter();
 #endif // wxUSE_THREADS
+
+    CFArrayRemoveAllValues( GetAutoReleaseArray() );
+}
+
+void wxApp::MacAddToAutorelease( void* cfrefobj )
+{
+    CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
 }
 
 long wxMacTranslateKey(unsigned char key, unsigned char code)
@@ -1484,8 +1545,18 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi
             int command = ancestor->GetAcceleratorTable()->GetCommand( event );
             if (command != -1)
             {
+                wxEvtHandler * const handler = ancestor->GetEventHandler();
+
                 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
-                handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
+                handled = handler->ProcessEvent( command_event );
+
+                if ( !handled )
+                {
+                    // accelerators can also be used with buttons, try them too
+                    command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
+                    handled = handler->ProcessEvent( command_event );
+                }
+
                 break;
             }
 
@@ -1571,7 +1642,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers
         wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
         if ( focus )
         {
-            if ( keyval == WXK_RETURN )
+            if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER )
             {
                 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(focus), wxTopLevelWindow);
                 if ( tlw && tlw->GetDefaultItem() )