]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/app.cpp
Don't include <CoreFoundation/CFBase.h> because it in turn includes MacTypes.h which...
[wxWidgets.git] / src / mac / carbon / app.cpp
index 21288925118a8dca777cb65f851d862228b8d5f7..a48440d002189e6f3782ff805efdae77290f3a8a 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 )
@@ -850,6 +885,8 @@ bool wxApp::Initialize(int& argc, wxChar **argv)
     event_posted_context.perform = macPostedEventCallback;
     m_macEventPosted = CFRunLoopSourceCreate(NULL,0,&event_posted_context);
     CFRunLoopAddSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
+       // run loop takes ownership
+       CFRelease(m_macEventPosted);
 #endif
 
     UMAShowArrowCursor() ;
@@ -858,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 ;
@@ -880,6 +918,7 @@ bool wxApp::OnInitGui()
     if (!sm_isEmbedded)
     {
         sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ;
+        sGURLHandler = NewAEEventHandlerUPP(AEHandleGURL) ;
         sOAppHandler = NewAEEventHandlerUPP(AEHandleOApp) ;
         sPDocHandler = NewAEEventHandlerUPP(AEHandlePDoc) ;
         sRAppHandler = NewAEEventHandlerUPP(AEHandleRApp) ;
@@ -887,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 ,
@@ -908,8 +949,10 @@ void wxApp::CleanUp()
 
 #ifdef __WXMAC_OSX__
     if (m_macEventPosted)
-        CFRelease(m_macEventPosted);
-    m_macEventPosted = NULL;
+       {
+               CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
+               m_macEventPosted = NULL;
+       }
 #endif
 
     // One last chance for pending objects to be cleaned up
@@ -933,6 +976,8 @@ void wxApp::CleanUp()
     {
         AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments ,
                                sODocHandler , FALSE ) ;
+        AERemoveEventHandler( kInternetEventClass, kAEGetURL,
+                               sGURLHandler , FALSE ) ;
         AERemoveEventHandler( kCoreEventClass , kAEOpenApplication ,
                                sOAppHandler , FALSE ) ;
         AERemoveEventHandler( kCoreEventClass , kAEPrintDocuments ,
@@ -943,6 +988,7 @@ void wxApp::CleanUp()
                                sQuitHandler , FALSE ) ;
 
         DisposeAEEventHandlerUPP( sODocHandler ) ;
+        DisposeAEEventHandlerUPP( sGURLHandler ) ;
         DisposeAEEventHandlerUPP( sOAppHandler ) ;
         DisposeAEEventHandlerUPP( sPDocHandler ) ;
         DisposeAEEventHandlerUPP( sRAppHandler ) ;
@@ -1150,6 +1196,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
@@ -1227,6 +1282,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;
@@ -1242,6 +1305,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)
@@ -1480,8 +1550,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;
             }
 
@@ -1567,7 +1647,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() )