X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/559a723c1dcf8b3929ab3122fb04429d4abdda8e..6cef0db28018fd2644ee4e38af715872e5242459:/src/mac/carbon/app.cpp diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index 8521da8756..749119f1bf 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -25,53 +25,37 @@ #include "wx/pen.h" #include "wx/brush.h" #include "wx/palette.h" + #include "wx/icon.h" + #include "wx/cursor.h" + #include "wx/dialog.h" + #include "wx/msgdlg.h" + #include "wx/textctrl.h" + #include "wx/memory.h" + #include "wx/gdicmn.h" + #include "wx/module.h" #endif -#include "wx/gdicmn.h" -#include "wx/cursor.h" -#include "wx/icon.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" -#include "wx/module.h" -#include "wx/memory.h" #include "wx/tooltip.h" -#include "wx/textctrl.h" #include "wx/docview.h" #include "wx/filename.h" +#include "wx/link.h" +#include "wx/thread.h" #include // mac -#ifndef __DARWIN__ - #if __option(profile) - #include - #endif -#endif - -// #include "apprsrc.h" - #include "wx/mac/uma.h" -#include "wx/mac/macnotfy.h" #ifdef __DARWIN__ # include # if defined(WXMAKINGDLL_CORE) # include # endif -#else -# include -# include -# include -# include -# include #endif -extern wxList wxPendingDelete; - -#if wxUSE_THREADS -extern size_t g_numberOfThreads; -#endif +// Keep linker from discarding wxStockGDIMac +wxFORCE_LINK_MODULE(gdiobj) // statics for implementation static bool s_inYield = false; @@ -88,17 +72,11 @@ END_EVENT_TABLE() // platform specific static variables -const short kMacMinHeap = (29 * 1024) ; -const short kwxMacMenuBarResource = 1 ; -const short kwxMacAppleMenuId = 1 ; +static const short kwxMacAppleMenuId = 1 ; -WXHRGN wxApp::s_macCursorRgn = NULL; wxWindow* wxApp::s_captureWindow = NULL ; -int wxApp::s_lastMouseDown = 0 ; -long wxApp::sm_lastMessageTime = 0; long wxApp::s_lastModifiers = 0 ; -bool wxApp::s_macSupportPCMenuShortcuts = true ; long wxApp::s_macAboutMenuItemId = wxID_ABOUT ; long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ; long wxApp::s_macExitMenuItemId = wxID_EXIT ; @@ -110,37 +88,43 @@ bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin // Core Apple Event Support //---------------------------------------------------------------------- -pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ; +pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; +pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; +pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; +pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; +pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ; -pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) +pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ; } -pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) +pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) +pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) +pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ; } -pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) +pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) ) { return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ; } +pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon 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)) @@ -182,6 +166,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)) @@ -272,6 +281,9 @@ void wxApp::MacOpenFile(const wxString & fileName ) #endif } +void wxApp::MacOpenURL(const wxString & WXUNUSED(url) ) +{ +} void wxApp::MacPrintFile(const wxString & fileName ) { @@ -329,18 +341,25 @@ void wxApp::MacReopenApp() else { wxTopLevelWindow* firstIconized = NULL ; + wxTopLevelWindow* firstHidden = NULL ; while (node) { wxTopLevelWindow* win = (wxTopLevelWindow*) node->GetData(); - if ( !win->IsIconized() ) + if ( !win->IsShown() ) { - firstIconized = NULL ; - break ; + // make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow + if ( firstHidden == NULL && ( wxDynamicCast( win, wxFrame ) || wxDynamicCast( win, wxDialog ) ) ) + firstHidden = win ; + } + else if ( win->IsIconized() ) + { + if ( firstIconized == NULL ) + firstIconized = win ; } else { - if ( firstIconized == NULL ) - firstIconized = win ; + // we do have a visible, non-iconized toplevelwindow -> do nothing + return; } node = node->GetNext(); @@ -348,6 +367,8 @@ void wxApp::MacReopenApp() if ( firstIconized ) firstIconized->Iconize( false ) ; + else if ( firstHidden ) + firstHidden->Show( true ); } } @@ -443,6 +464,7 @@ UInt32 wxIdToMacCommand( int wxId ) wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) { wxMenu* itemMenu = NULL ; +#ifndef __WXUNIVERSAL__ int id = 0 ; // for 'standard' commands which don't have a wx-menu @@ -459,16 +481,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 ) @@ -476,7 +499,7 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) } else { - UInt32 refCon ; + URefCon refCon ; GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ; itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ; @@ -484,7 +507,7 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) item = (wxMenuItem*) refCon ; } } - +#endif return itemMenu ; } @@ -516,10 +539,13 @@ static const EventTypeSpec eventList[] = } ; static pascal OSStatus -wxMacAppMenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *WXUNUSED(data) ) { wxMacCarbonEvent cEvent( event ) ; MenuRef menuRef = cEvent.GetParameter(kEventParamDirectObject) ; +#ifndef __WXUNIVERSAL__ wxMenu* menu = wxFindMenuFromMacMenu( menuRef ) ; if ( menu ) @@ -561,15 +587,19 @@ wxMacAppMenuEventHandler( EventHandlerCallRef handler , EventRef event , void *d { wxWindow *win = menu->GetInvokingWindow(); if (win) - win->GetEventHandler()->ProcessEvent(wxevent); + win->HandleWindowEvent(wxevent); } } } - +#endif return eventNotHandledErr; } -static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +#ifndef __LP64__ +static pascal OSStatus +wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) , + EventRef event , + void *WXUNUSED(data) ) { OSStatus result = eventNotHandledErr ; @@ -589,60 +619,11 @@ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler switch ( cEvent.GetKind() ) { case kEventProcessCommand : - { - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; - - if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ) - result = noErr ; - } + result = itemMenu->MacHandleCommandProcess( item, id ); break ; case kEventCommandUpdateStatus: - { - wxUpdateUIEvent event(id); - event.SetEventObject( itemMenu ); - - bool processed = false; - - // Try the menu's event handler - { - wxEvtHandler *handler = itemMenu->GetEventHandler(); - if ( handler ) - processed = handler->ProcessEvent(event); - } - - // Try the window the menu was popped up from - // (and up through the hierarchy) - if ( !processed ) - { - const wxMenuBase *menu = itemMenu; - while ( menu ) - { - wxWindow *win = menu->GetInvokingWindow(); - if ( win ) - { - processed = win->GetEventHandler()->ProcessEvent(event); - break; - } - - menu = menu->GetParent(); - } - } - - if ( processed ) - { - // if anything changed, update the changed attribute - if (event.GetSetText()) - itemMenu->SetLabel(id, event.GetText()); - if (event.GetSetChecked()) - itemMenu->Check(id, event.GetChecked()); - if (event.GetSetEnabled()) - itemMenu->Enable(id, event.GetEnabled()); - - result = noErr ; - } - } + result = itemMenu->MacHandleCommandUpdateStatus( item, id ); break ; default : @@ -651,8 +632,12 @@ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler } return result ; } +#endif -static pascal OSStatus wxMacAppApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus +wxMacAppApplicationEventHandler( EventHandlerCallRef WXUNUSED(handler) , + EventRef event , + void *WXUNUSED(data) ) { OSStatus result = eventNotHandledErr ; switch ( GetEventKind( event ) ) @@ -685,14 +670,15 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve OSStatus result = eventNotHandledErr ; switch ( GetEventClass( event ) ) { +#ifndef __LP64__ case kEventClassCommand : result = wxMacAppCommandEventHandler( handler , event , data ) ; break ; - +#endif case kEventClassApplication : result = wxMacAppApplicationEventHandler( handler , event , data ) ; break ; - +#ifndef __LP64__ case kEventClassMenu : result = wxMacAppMenuEventHandler( handler , event , data ) ; break ; @@ -710,13 +696,23 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve result = wxMacTopLevelMouseEventHandler( handler , event , NULL ) ; } break ; - +#endif case kEventClassAppleEvent : { - EventRecord rec ; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if ( AEProcessEvent != NULL ) + { + result = AEProcessEvent(event); + } +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + { + EventRecord rec ; - wxMacConvertEventToRecord( event , &rec ) ; - result = AEProcessAppleEvent( &rec ) ; + wxMacConvertEventToRecord( event , &rec ) ; + result = AEProcessAppleEvent( &rec ) ; + } +#endif } break ; @@ -733,9 +729,16 @@ DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler ) #ifdef __WXDEBUG__ -pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 options, - const char *assertionString, const char *exceptionLabelString, - const char *errorString, const char *fileName, long lineNumber, void *value, ConstStr255Param outputMsg) +pascal static void +wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature), + UInt32 WXUNUSED(options), + const char *assertionString, + const char *exceptionLabelString, + const char *errorString, + const char *fileName, + long lineNumber, + void *value, + ConstStr255Param WXUNUSED(outputMsg)) { // flow into assert handling wxString fileNameStr ; @@ -772,18 +775,10 @@ pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 op #endif //__WXDEBUG__ -#ifdef __WXMAC_OSX__ -extern "C" -{ - // m_macEventPosted run loop source callback: - void macPostedEventCallback(void *unused); -} - -void macPostedEventCallback(void *unused) +extern "C" void macPostedEventCallback(void *WXUNUSED(unused)) { wxTheApp->ProcessPendingEvents(); } -#endif bool wxApp::Initialize(int& argc, wxChar **argv) { @@ -794,25 +789,7 @@ bool wxApp::Initialize(int& argc, wxChar **argv) #endif UMAInitToolbox( 4, sm_isEmbedded ) ; - SetEventMask( everyEvent ) ; - UMAShowWatchCursor() ; - -#ifndef __DARWIN__ -# if __option(profile) - ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ; -# endif -#endif - -#ifndef __DARWIN__ - // now avoid exceptions thrown for new (bad_alloc) - // FIXME CS for some changes outside wxMac does not compile anymore -#if 0 - std::__throws_bad_alloc = 0 ; -#endif - -#endif - - s_macCursorRgn = ::NewRgn() ; +// TODO CHECK Can Be Removed SetEventMask( everyEvent ) ; // Mac OS X passes a process serial number command line argument when // the application is launched from the Finder. This argument must be @@ -836,7 +813,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv) wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); #endif -#if TARGET_API_MAC_OSX // these might be the startup dirs, set them to the 'usual' dir containing the app bundle wxString startupCwd = wxGetCwd() ; if ( startupCwd == wxT("/") || startupCwd.Right(15) == wxT("/Contents/MacOS") ) @@ -846,28 +822,24 @@ bool wxApp::Initialize(int& argc, wxChar **argv) CFRelease( url ) ; CFStringRef path = CFURLCopyFileSystemPath ( urlParent , kCFURLPOSIXPathStyle ) ; CFRelease( urlParent ) ; - wxString cwd = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding()); + wxString cwd = wxCFStringRef(path).AsString(wxLocale::GetSystemEncoding()); wxSetWorkingDirectory( cwd ) ; } -#endif - - wxMacCreateNotifierTable() ; -#ifdef __WXMAC_OSX__ /* connect posted events to common-mode run loop so that wxPostEvent events are handled even while we're in the menu or on a scrollbar */ CFRunLoopSourceContext event_posted_context = {0}; event_posted_context.perform = macPostedEventCallback; m_macEventPosted = CFRunLoopSourceCreate(NULL,0,&event_posted_context); CFRunLoopAddSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes); -#endif - - UMAShowArrowCursor() ; + // run loop takes ownership + CFRelease(m_macEventPosted); return true; } AEEventHandlerUPP sODocHandler = NULL ; +AEEventHandlerUPP sGURLHandler = NULL ; AEEventHandlerUPP sOAppHandler = NULL ; AEEventHandlerUPP sPDocHandler = NULL ; AEEventHandlerUPP sRAppHandler = NULL ; @@ -877,19 +849,20 @@ bool wxApp::OnInitGui() { if ( !wxAppBase::OnInitGui() ) return false ; - +#ifndef __LP64__ InstallStandardEventHandler( GetApplicationEventTarget() ) ; - if (!sm_isEmbedded) { InstallApplicationEventHandler( GetwxMacAppEventHandlerUPP(), GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler)); } +#endif if (!sm_isEmbedded) { sODocHandler = NewAEEventHandlerUPP(AEHandleODoc) ; + sGURLHandler = NewAEEventHandlerUPP(AEHandleGURL) ; sOAppHandler = NewAEEventHandlerUPP(AEHandleOApp) ; sPDocHandler = NewAEEventHandlerUPP(AEHandlePDoc) ; sRAppHandler = NewAEEventHandlerUPP(AEHandleRApp) ; @@ -897,6 +870,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 , @@ -907,6 +882,9 @@ bool wxApp::OnInitGui() sQuitHandler , 0 , FALSE ) ; } + if ( !wxMacInitCocoa() ) + return false; + return true ; } @@ -916,28 +894,15 @@ void wxApp::CleanUp() wxToolTip::RemoveToolTips() ; #endif -#ifdef __WXMAC_OSX__ if (m_macEventPosted) - CFRelease(m_macEventPosted); - m_macEventPosted = NULL; -#endif + { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes); + m_macEventPosted = NULL; + } // One last chance for pending objects to be cleaned up wxTheApp->DeletePendingObjects(); - wxMacDestroyNotifierTable() ; - -#ifndef __DARWIN__ -# if __option(profile) - ProfilerDump( (StringPtr)"\papp.prof" ) ; - ProfilerTerm() ; -# endif -#endif - - UMACleanupToolbox() ; - if (s_macCursorRgn) - ::DisposeRgn((RgnHandle)s_macCursorRgn); - if (!sm_isEmbedded) RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) ); @@ -945,6 +910,8 @@ void wxApp::CleanUp() { AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments , sODocHandler , FALSE ) ; + AERemoveEventHandler( kInternetEventClass, kAEGetURL, + sGURLHandler , FALSE ) ; AERemoveEventHandler( kCoreEventClass , kAEOpenApplication , sOAppHandler , FALSE ) ; AERemoveEventHandler( kCoreEventClass , kAEPrintDocuments , @@ -955,6 +922,7 @@ void wxApp::CleanUp() sQuitHandler , FALSE ) ; DisposeAEEventHandlerUPP( sODocHandler ) ; + DisposeAEEventHandlerUPP( sGURLHandler ) ; DisposeAEEventHandlerUPP( sOAppHandler ) ; DisposeAEEventHandlerUPP( sPDocHandler ) ; DisposeAEEventHandlerUPP( sRAppHandler ) ; @@ -968,31 +936,7 @@ void wxApp::CleanUp() // misc initialization stuff //---------------------------------------------------------------------- -#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__) - -// for shared libraries we have to manually get the correct resource -// ref num upon initializing and releasing when terminating, therefore -// the __wxinitialize and __wxterminate must be used - -extern "C" -{ - void __sinit(void); // (generated by linker) - pascal OSErr __initialize(const CFragInitBlock *theInitBlock); - pascal void __terminate(void); -} - -pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock) -{ - return __initialize( theInitBlock ) ; -} - -pascal void __wxterminate(void) -{ - __terminate() ; -} - -#endif /* WXMAKINGDLL_CORE && !__DARWIN__ */ - +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) { OSStatus err = noErr ; @@ -1034,7 +978,6 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) unsigned char charCode ; UInt32 modifiers ; GetMouse( &rec->where) ; - err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode); err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode); @@ -1059,7 +1002,6 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) { UInt32 keyCode, modifiers; unsigned char charCode ; - GetMouse( &rec->where) ; rec->what = keyDown ; err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); @@ -1084,6 +1026,7 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) return converted ; } +#endif wxApp::wxApp() { @@ -1091,33 +1034,26 @@ wxApp::wxApp() m_macCurrentEvent = NULL ; m_macCurrentEventHandlerCallRef = NULL ; - -#ifdef __WXMAC_OSX__ m_macEventPosted = NULL ; -#endif } -void wxApp::OnIdle(wxIdleEvent& event) +void wxApp::OnIdle(wxIdleEvent& WXUNUSED(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(); - +#ifndef __WXUNIVERSAL__ if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar()) wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar(); +#endif } void wxApp::WakeUpIdle() { -#ifdef __WXMAC_OSX__ if (m_macEventPosted) { CFRunLoopSourceSignal(m_macEventPosted); } -#endif wxMacWakeUp() ; } @@ -1159,6 +1095,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 @@ -1190,7 +1135,6 @@ bool wxApp::Yield(bool onlyIfNeeded) } } - wxMacProcessNotifierAndPendingEvents() ; s_inYield = false; return true; @@ -1198,6 +1142,7 @@ bool wxApp::Yield(bool onlyIfNeeded) void wxApp::MacDoOneEvent() { + wxMacAutoreleasePool autoreleasepool; EventRef theEvent; s_inReceiveEvent = true ; @@ -1227,15 +1172,22 @@ void wxApp::MacDoOneEvent() // repeaters DeletePendingObjects() ; - wxMacProcessNotifierAndPendingEvents() ; } // virtual -void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr ) +void wxApp::MacHandleUnhandledEvent( WXEVENTREF WXUNUSED(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,11 +1198,16 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr ) if (status == eventNotHandledErr) MacHandleUnhandledEvent(evr); - wxMacProcessNotifierAndPendingEvents() ; - #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) @@ -1419,24 +1376,6 @@ int wxMacKeyCodeToModifier(wxKeyCode key) } } -#ifndef __DARWIN__ -bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below -{ - wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != - WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); - -//if OS X > 10.2 (i.e. 10.2.x) -//a known apple bug prevents the system from determining led -//states with GetKeys... can only determine caps lock led - return !!(GetCurrentKeyModifiers() & wxMacKeyCodeToModifier(key)); -//else -// KeyMapByteArray keymap; -// GetKeys((BigEndianLong*)keymap); -// return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey)); -} -#endif - - wxMouseState wxGetMouseState() { wxMouseState ms; @@ -1445,16 +1384,10 @@ wxMouseState wxGetMouseState() ms.SetX(pt.x); ms.SetY(pt.y); -#if TARGET_API_MAC_OSX UInt32 buttons = GetCurrentButtonState(); ms.SetLeftDown( (buttons & 0x01) != 0 ); ms.SetMiddleDown( (buttons & 0x04) != 0 ); ms.SetRightDown( (buttons & 0x02) != 0 ); -#else - ms.SetLeftDown( Button() ); - ms.SetMiddleDown( 0 ); - ms.SetRightDown( 0 ); -#endif UInt32 modifiers = GetCurrentKeyModifiers(); ms.SetControlDown(modifiers & controlKey); @@ -1476,7 +1409,7 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi wxKeyEvent event(wxEVT_KEY_DOWN) ; MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - handled = focus->GetEventHandler()->ProcessEvent( event ) ; + handled = focus->HandleWindowEvent( event ) ; if ( handled && event.GetSkipped() ) handled = false ; @@ -1489,8 +1422,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; } @@ -1513,7 +1456,7 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier bool handled; wxKeyEvent event( wxEVT_KEY_UP ) ; MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - handled = focus->GetEventHandler()->ProcessEvent( event ) ; + handled = focus->HandleWindowEvent( event ) ; return handled ; } @@ -1534,7 +1477,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers if (tlw) { event.SetEventType( wxEVT_CHAR_HOOK ); - handled = tlw->GetEventHandler()->ProcessEvent( event ); + handled = tlw->HandleWindowEvent( event ); if ( handled && event.GetSkipped() ) handled = false ; } @@ -1543,7 +1486,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers { event.SetEventType( wxEVT_CHAR ); event.Skip( false ) ; - handled = focus->GetEventHandler()->ProcessEvent( event ) ; + handled = focus->HandleWindowEvent( event ) ; } if ( !handled && (keyval == WXK_TAB) ) @@ -1559,7 +1502,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ new_event.SetWindowChange( event.ControlDown() ); new_event.SetCurrentFocus( focus ); - handled = focus->GetParent()->GetEventHandler()->ProcessEvent( new_event ); + handled = focus->GetParent()->HandleWindowEvent( new_event ); if ( handled && new_event.GetSkipped() ) handled = false ; } @@ -1573,19 +1516,24 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers { // if window is not having a focus still testing for default enter or cancel // TODO: add the UMA version for ActiveNonFloatingWindow +#ifndef __LP64__ wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; if ( focus ) { - if ( keyval == WXK_RETURN ) + if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER ) { - wxButton *def = wxDynamicCast(focus->GetDefaultItem(), wxButton); - if ( def && def->IsEnabled() ) + wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(focus), wxTopLevelWindow); + if ( tlw && tlw->GetDefaultItem() ) { - wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); - event.SetEventObject(def); - def->Command(event); + wxButton *def = wxDynamicCast(tlw->GetDefaultItem(), wxButton); + if ( def && def->IsEnabled() ) + { + wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); + event.SetEventObject(def); + def->Command(event); - return true ; + return true ; + } } } else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) @@ -1593,9 +1541,10 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers // generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); new_event.SetEventObject( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); + handled = focus->HandleWindowEvent( new_event ); } } +#endif } return handled ; } @@ -1611,57 +1560,65 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after +#ifdef __LP64__ + // TODO new implementation using TextInputSources +#else UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); +#endif } long keyval = wxMacTranslateKey(keychar, keycode) ; if ( keyval == keychar && ( event.GetEventType() == wxEVT_KEY_UP || event.GetEventType() == wxEVT_KEY_DOWN ) ) keyval = wxToupper( keyval ) ; - // Check for NUMPAD keys - if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) + // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the + // WXK_NUMPAD constants, but for the CHAR event we want to use the + // standard ascii values + if ( event.GetEventType() != wxEVT_CHAR ) { - keyval = (keyval - '0') + WXK_NUMPAD0; - } - else if (keycode >= 67 && keycode <= 81) - { - switch (keycode) + if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) { - case 76 : - keyval = WXK_NUMPAD_ENTER; - break; - - case 81: - keyval = WXK_NUMPAD_EQUAL; - break; - - case 67: - keyval = WXK_NUMPAD_MULTIPLY; - break; - - case 75: - keyval = WXK_NUMPAD_DIVIDE; - break; - - case 78: - keyval = WXK_NUMPAD_SUBTRACT; - break; - - case 69: - keyval = WXK_NUMPAD_ADD; - break; - - case 65: - keyval = WXK_NUMPAD_DECIMAL; - break; - - default: - break; - } // end switch + keyval = (keyval - '0') + WXK_NUMPAD0; + } + else if (keycode >= 65 && keycode <= 81) + { + switch (keycode) + { + case 76 : + keyval = WXK_NUMPAD_ENTER; + break; + + case 81: + keyval = WXK_NUMPAD_EQUAL; + break; + + case 67: + keyval = WXK_NUMPAD_MULTIPLY; + break; + + case 75: + keyval = WXK_NUMPAD_DIVIDE; + break; + + case 78: + keyval = WXK_NUMPAD_SUBTRACT; + break; + + case 69: + keyval = WXK_NUMPAD_ADD; + break; + + case 65: + keyval = WXK_NUMPAD_DECIMAL; + break; + default: + break; + } + } } - + event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; @@ -1678,3 +1635,14 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess event.SetTimestamp(when); event.SetEventObject(focus); } + + +void wxApp::MacHideApp() +{ + wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ); + HICommand command; + memset( &command, 0 , sizeof(command) ); + command.commandID = kHICommandHide ; + event.SetParameter(kEventParamDirectObject, command ); + SendEventToApplication( event ); +}