X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9b58521dc97c069e4e3fc283a6d90497e1bcc80c..9611686694f0449c7f7ced2e0badad9f04a22ea5:/src/mac/carbon/app.cpp diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index 356c2b2ecc..8c52e9f221 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: app.cpp +// Name: src/mac/carbon/app.cpp // Purpose: wxApp // Author: Stefan Csomor // Modified by: @@ -9,44 +9,45 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "app.h" -#endif - #include "wx/wxprec.h" -#include "wx/window.h" -#include "wx/frame.h" -#include "wx/button.h" #include "wx/app.h" -#include "wx/utils.h" -#include "wx/gdicmn.h" -#include "wx/pen.h" -#include "wx/brush.h" -#include "wx/cursor.h" -#include "wx/intl.h" -#include "wx/icon.h" -#include "wx/palette.h" -#include "wx/dc.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" -#include "wx/log.h" -#include "wx/module.h" -#include "wx/memory.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/window.h" + #include "wx/frame.h" + #include "wx/dc.h" + #include "wx/button.h" + #include "wx/menu.h" + #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/tooltip.h" -#include "wx/textctrl.h" -#include "wx/menu.h" #include "wx/docview.h" #include "wx/filename.h" +#include "wx/link.h" #include // mac #ifndef __DARWIN__ - #if __option(profile) - #include - #endif + #if __option(profile) + #include + #endif #endif // #include "apprsrc.h" @@ -67,29 +68,15 @@ # include #endif -extern wxList wxPendingDelete; - -// set wxMAC_USE_RAEL to 1 if RunApplicationEventLoop should be used -// if 0 the lower level CarbonEventLoop will be used -// on the long run RAEL should replace the low level event loop -// we will have to clean up event handling to make sure we don't -// miss handling of things like pending events etc -// perhaps we will also have to pipe events through an ueber-event-handler -// to make sure we have one place to do all these house-keeping functions - -#define wxMAC_USE_RAEL 0 - -#if wxUSE_THREADS -extern size_t g_numberOfThreads; -#endif // wxUSE_THREADS +// Keep linker from discarding wxStockGDIMac +wxFORCE_LINK_MODULE(gdiobj) // statics for implementation - -static bool s_inYield = FALSE; - -static bool s_inReceiveEvent = FALSE ; +static bool s_inYield = false; +static bool s_inReceiveEvent = false ; static EventTime sleepTime = kEventDurationNoWait ; + IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) EVT_IDLE(wxApp::OnIdle) @@ -98,58 +85,50 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) END_EVENT_TABLE() -const short kMacMinHeap = (29 * 1024) ; // platform specific static variables +static const short kwxMacAppleMenuId = 1 ; -const short kwxMacMenuBarResource = 1 ; -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 ; wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ; -// Normally we're not a plugin -bool wxApp::sm_isEmbedded = false; +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) ; } @@ -165,6 +144,7 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) long itemsInList; OSErr err; short i; + err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); if (err != noErr) return err; @@ -178,17 +158,19 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) PSN.lowLongOfPSN = kCurrentProcess ; SetFrontProcess( &PSN ) ; - for (i = 1; i <= itemsInList; i++) - { - wxString fName ; + wxString fName ; + FSRef theRef ; - FSRef theRef ; - AEGetNthPtr(&docList, i, typeFSRef, &keywd, &returnedType, - (Ptr) & theRef, sizeof(theRef), &actualSize); + for (i = 1; i <= itemsInList; i++) + { + AEGetNthPtr( + &docList, i, typeFSRef, &keywd, &returnedType, + (Ptr)&theRef, sizeof(theRef), &actualSize); fName = wxMacFSRefToPath( &theRef ) ; MacOpenFile(fName); } + return noErr; } @@ -203,6 +185,7 @@ short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply) long itemsInList; OSErr err; short i; + err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList); if (err != noErr) return err; @@ -216,16 +199,19 @@ short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply) PSN.lowLongOfPSN = kCurrentProcess ; SetFrontProcess( &PSN ) ; - for (i = 1; i <= itemsInList; i++) { - wxString fName ; + wxString fName ; + FSRef theRef ; - FSRef theRef ; - AEGetNthPtr(&docList, i, typeFSRef, &keywd, &returnedType, - (Ptr) & theRef, sizeof(theRef), &actualSize); + for (i = 1; i <= itemsInList; i++) + { + AEGetNthPtr( + &docList, i, typeFSRef, &keywd, &returnedType, + (Ptr)&theRef, sizeof(theRef), &actualSize); fName = wxMacFSRefToPath( &theRef ) ; MacPrintFile(fName); } + return noErr; } @@ -246,12 +232,13 @@ short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU { wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId); if (!win->ProcessEvent(exitEvent)) - win->Close(TRUE ) ; + win->Close(true) ; } else { ExitMainLoop() ; } + return noErr ; } @@ -260,11 +247,10 @@ short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { MacReopenApp() ; + return noErr ; } - - //---------------------------------------------------------------------- // Support Routines linking the Mac...File Calls to the Document Manager //---------------------------------------------------------------------- @@ -291,16 +277,17 @@ void wxApp::MacPrintFile(const wxString & fileName ) if ( doc ) { wxView* view = doc->GetFirstView() ; - if( view ) + if ( view ) { wxPrintout *printout = view->OnCreatePrintout(); if (printout) { wxPrinter printer; - printer.Print(view->GetFrame(), printout, TRUE); + printer.Print(view->GetFrame(), printout, true); delete printout; } } + if (doc->Close()) { doc->DeleteAllViews(); @@ -325,10 +312,10 @@ void wxApp::MacReopenApp() // if there is no open window -> create a new one // if all windows are hidden -> show the first // if some windows are not hidden -> do nothing - + wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); if ( node == NULL ) - { + { MacNewFile() ; } else @@ -337,7 +324,7 @@ void wxApp::MacReopenApp() while (node) { wxTopLevelWindow* win = (wxTopLevelWindow*) node->GetData(); - if ( win->IsIconized() == false ) + if ( !win->IsIconized() ) { firstIconized = NULL ; break ; @@ -347,13 +334,152 @@ void wxApp::MacReopenApp() if ( firstIconized == NULL ) firstIconized = win ; } + node = node->GetNext(); } + if ( firstIconized ) firstIconized->Iconize( false ) ; } } +//---------------------------------------------------------------------- +// Macintosh CommandID support - converting between native and wx IDs +//---------------------------------------------------------------------- + +// if no native match they just return the passed-in id + +struct IdPair +{ + UInt32 macId ; + int wxId ; +} ; + +IdPair gCommandIds [] = +{ + { kHICommandCut , wxID_CUT } , + { kHICommandCopy , wxID_COPY } , + { kHICommandPaste , wxID_PASTE } , + { kHICommandSelectAll , wxID_SELECTALL } , + { kHICommandClear , wxID_CLEAR } , + { kHICommandUndo , wxID_UNDO } , + { kHICommandRedo , wxID_REDO } , +} ; + +int wxMacCommandToId( UInt32 macCommandId ) +{ + int wxid = 0 ; + + switch ( macCommandId ) + { + case kHICommandPreferences : + wxid = wxApp::s_macPreferencesMenuItemId ; + break ; + + case kHICommandQuit : + wxid = wxApp::s_macExitMenuItemId ; + break ; + + case kHICommandAbout : + wxid = wxApp::s_macAboutMenuItemId ; + break ; + + default : + { + for ( size_t i = 0 ; i < WXSIZEOF(gCommandIds) ; ++i ) + { + if ( gCommandIds[i].macId == macCommandId ) + { + wxid = gCommandIds[i].wxId ; + break ; + } + } + } + break ; + } + + if ( wxid == 0 ) + wxid = (int) macCommandId ; + + return wxid ; +} + +UInt32 wxIdToMacCommand( int wxId ) +{ + UInt32 macId = 0 ; + + if ( wxId == wxApp::s_macPreferencesMenuItemId ) + macId = kHICommandPreferences ; + else if (wxId == wxApp::s_macExitMenuItemId) + macId = kHICommandQuit ; + else if (wxId == wxApp::s_macAboutMenuItemId) + macId = kHICommandAbout ; + else + { + for ( size_t i = 0 ; i < WXSIZEOF(gCommandIds) ; ++i ) + { + if ( gCommandIds[i].wxId == wxId ) + { + macId = gCommandIds[i].macId ; + break ; + } + } + } + + if ( macId == 0 ) + macId = (int) wxId ; + + return macId ; +} + +wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) +{ + wxMenu* itemMenu = NULL ; + int id = 0 ; + + // for 'standard' commands which don't have a wx-menu + if ( command.commandID == kHICommandPreferences || command.commandID == kHICommandQuit || command.commandID == kHICommandAbout ) + { + id = wxMacCommandToId( command.commandID ) ; + + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + if ( mbar ) + item = mbar->FindItem( id , &itemMenu ) ; + } + else if ( command.commandID != 0 && command.menu.menuRef != 0 && command.menu.menuItemIndex != 0 ) + { + 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 ) + { + if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) != noErr ) + mh = 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 ) ) + { + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; + if ( mbar ) + item = mbar->FindItem( id , &itemMenu ) ; + } + else + { + URefCon refCon ; + + GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ; + itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ; + if ( itemMenu != NULL ) + item = (wxMenuItem*) refCon ; + } + } + + return itemMenu ; +} + //---------------------------------------------------------------------- // Carbon Event Handler //---------------------------------------------------------------------- @@ -383,28 +509,31 @@ static const EventTypeSpec eventList[] = static pascal OSStatus wxMacAppMenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) -{ +{ wxMacCarbonEvent cEvent( event ) ; MenuRef menuRef = cEvent.GetParameter(kEventParamDirectObject) ; wxMenu* menu = wxFindMenuFromMacMenu( menuRef ) ; - + if ( menu ) { - wxEventType type=0; + wxEventType type=0; MenuCommand cmd=0; switch (GetEventKind(event)) { case kEventMenuOpening: type = wxEVT_MENU_OPEN; break; + case kEventMenuClosed: type = wxEVT_MENU_CLOSE; break; + case kEventMenuTargetItem: cmd = cEvent.GetParameter(kEventParamMenuCommand,typeMenuCommand) ; - if (cmd != 0) + if (cmd != 0) type = wxEVT_MENU_HIGHLIGHT; break; + default: wxFAIL_MSG(wxT("Unexpected menu event kind")); break; @@ -423,12 +552,12 @@ wxMacAppMenuEventHandler( EventHandlerCallRef handler , EventRef event , void *d else { wxWindow *win = menu->GetInvokingWindow(); - if (win) + if (win) win->GetEventHandler()->ProcessEvent(wxevent); } } } - + return eventNotHandledErr; } @@ -440,45 +569,74 @@ static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler wxMacCarbonEvent cEvent( event ) ; cEvent.GetParameter(kEventParamDirectObject,typeHICommand,&command) ; - + wxMenuItem* item = NULL ; - MenuCommand id = command.commandID ; - // for items we don't really control - if ( id == kHICommandPreferences ) - { - id = wxApp::s_macPreferencesMenuItemId ; - - wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; - if ( mbar ) - { - wxMenu* menu = NULL ; - item = mbar->FindItem( id , &menu ) ; - } - } - else if ( id != 0 && command.menu.menuRef != 0 && command.menu.menuItemIndex != 0 ) - { - GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , (UInt32*) &item ) ; - } - + wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; + int id = wxMacCommandToId( command.commandID ) ; + if ( item ) { - switch( cEvent.GetKind() ) - { - case kEventProcessCommand : - { + wxASSERT( itemMenu != NULL ) ; + + switch ( cEvent.GetKind() ) + { + case kEventProcessCommand : + { if (item->IsCheckable()) - { item->Check( !item->IsChecked() ) ; - } - item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; - result = noErr ; + if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ) + result = noErr ; } break ; + case kEventCommandUpdateStatus: - // eventually trigger an updateui round - result = noErr ; + { + 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 ; + } + } break ; + default : break ; } @@ -492,22 +650,21 @@ static pascal OSStatus wxMacAppApplicationEventHandler( EventHandlerCallRef hand switch ( GetEventKind( event ) ) { case kEventAppActivated : - { - if ( wxTheApp ) - wxTheApp->SetActive( true , NULL ) ; - result = noErr ; - } + if ( wxTheApp ) + wxTheApp->SetActive( true , NULL ) ; + result = noErr ; break ; + case kEventAppDeactivated : - { - if ( wxTheApp ) - wxTheApp->SetActive( false , NULL ) ; - result = noErr ; - } + if ( wxTheApp ) + wxTheApp->SetActive( false , NULL ) ; + result = noErr ; break ; + default : break ; } + return result ; } @@ -518,21 +675,24 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve wxTheApp->MacSetCurrentEvent( event , handler ) ; OSStatus result = eventNotHandledErr ; - switch( GetEventClass( event ) ) + switch ( GetEventClass( event ) ) { case kEventClassCommand : result = wxMacAppCommandEventHandler( handler , event , data ) ; break ; + case kEventClassApplication : result = wxMacAppApplicationEventHandler( handler , event , data ) ; break ; + case kEventClassMenu : result = wxMacAppMenuEventHandler( handler , event , data ) ; break ; + case kEventClassMouse : { wxMacCarbonEvent cEvent( event ) ; - + WindowRef window ; Point screenMouseLocation = cEvent.GetParameter(kEventParamMouseLocation) ; ::FindWindow(screenMouseLocation, &window); @@ -542,13 +702,16 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve result = wxMacTopLevelMouseEventHandler( handler , event , NULL ) ; } break ; + case kEventClassAppleEvent : { EventRecord rec ; + wxMacConvertEventToRecord( event , &rec ) ; result = AEProcessAppleEvent( &rec ) ; } break ; + default : break ; } @@ -560,15 +723,10 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler ) -#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__) -// we know it's there ;-) -WXIMPORT char std::__throws_bad_alloc ; -#endif - -#if __WXDEBUG__ +#ifdef __WXDEBUG__ -pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 options, - const char *assertionString, const char *exceptionLabelString, +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) { // flow into assert handling @@ -576,6 +734,7 @@ pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 op wxString assertionStr ; wxString exceptionStr ; wxString errorStr ; + #if wxUSE_UNICODE fileNameStr = wxString(fileName, wxConvLocal); assertionStr = wxString(assertionString, wxConvLocal); @@ -590,38 +749,42 @@ pascal static void wxMacAssertOutputHandler(OSType componentSignature, UInt32 op #if 1 // flow into log - wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"), - assertionStr.c_str() , - exceptionStr.c_str() , - errorStr.c_str(), + wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"), + assertionStr.c_str() , + exceptionStr.c_str() , + errorStr.c_str(), fileNameStr.c_str(), lineNumber , value ) ; #else wxOnAssert(fileNameStr, lineNumber , assertionStr , - wxString::Format( wxT("%s %s value (%p)") ,exceptionStr, errorStr , value ) ) ; + wxString::Format( wxT("%s %s value (%p)") , exceptionStr, errorStr , value ) ) ; #endif } #endif //__WXDEBUG__ #ifdef __WXMAC_OSX__ -extern "C" { - /* m_macEventPosted run loop source callback: */ +extern "C" +{ + // m_macEventPosted run loop source callback: void macPostedEventCallback(void *unused); } -void macPostedEventCallback(void *unused) { - wxTheApp->ProcessPendingEvents(); } +void macPostedEventCallback(void *unused) +{ + wxTheApp->ProcessPendingEvents(); +} #endif bool wxApp::Initialize(int& argc, wxChar **argv) { // Mac-specific -#if __WXDEBUG__ - InstallDebugAssertOutputHandler ( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) ); +#ifdef __WXDEBUG__ + InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) ); #endif + UMAInitToolbox( 4, sm_isEmbedded ) ; SetEventMask( everyEvent ) ; UMAShowWatchCursor() ; @@ -641,8 +804,6 @@ bool wxApp::Initialize(int& argc, wxChar **argv) #endif - s_macCursorRgn = ::NewRgn() ; - // Mac OS X passes a process serial number command line argument when // the application is launched from the Finder. This argument must be // removed from the command line arguments before being handled by the @@ -675,7 +836,7 @@ 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 = wxMacCFStringHolder(path).AsString(wxLocale::GetSystemEncoding()); wxSetWorkingDirectory( cwd ) ; } #endif @@ -689,6 +850,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() ; @@ -704,7 +867,7 @@ AEEventHandlerUPP sQuitHandler = NULL ; bool wxApp::OnInitGui() { - if( !wxAppBase::OnInitGui() ) + if ( !wxAppBase::OnInitGui() ) return false ; InstallStandardEventHandler( GetApplicationEventTarget() ) ; @@ -736,7 +899,7 @@ bool wxApp::OnInitGui() sQuitHandler , 0 , FALSE ) ; } - return TRUE ; + return true ; } void wxApp::CleanUp() @@ -747,10 +910,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 @@ -766,15 +929,10 @@ void wxApp::CleanUp() #endif UMACleanupToolbox() ; - if (s_macCursorRgn) { - ::DisposeRgn((RgnHandle)s_macCursorRgn); - } if (!sm_isEmbedded) - { RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) ); - } - + if (!sm_isEmbedded) { AERemoveEventHandler( kCoreEventClass , kAEOpenDocuments , @@ -787,7 +945,7 @@ void wxApp::CleanUp() sRAppHandler , FALSE ) ; AERemoveEventHandler( kCoreEventClass , kAEQuitApplication , sQuitHandler , FALSE ) ; - + DisposeAEEventHandlerUPP( sODocHandler ) ; DisposeAEEventHandlerUPP( sOAppHandler ) ; DisposeAEEventHandlerUPP( sPDocHandler ) ; @@ -808,8 +966,9 @@ void wxApp::CleanUp() // ref num upon initializing and releasing when terminating, therefore // the __wxinitialize and __wxterminate must be used -extern "C" { - void __sinit(void); /* (generated by linker) */ +extern "C" +{ + void __sinit(void); // (generated by linker) pascal OSErr __initialize(const CFragInitBlock *theInitBlock); pascal void __terminate(void); } @@ -828,40 +987,47 @@ pascal void __wxterminate(void) bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) { - bool converted = ConvertEventRefToEventRecord( event,rec) ; OSStatus err = noErr ; + bool converted = ConvertEventRefToEventRecord( event, rec) ; + if ( !converted ) { - switch( GetEventClass( event ) ) + switch ( GetEventClass( event ) ) { case kEventClassKeyboard : { converted = true ; - switch( GetEventKind(event) ) + switch ( GetEventKind(event) ) { case kEventRawKeyDown : rec->what = keyDown ; break ; + case kEventRawKeyRepeat : rec->what = autoKey ; break ; + case kEventRawKeyUp : rec->what = keyUp ; break ; + case kEventRawKeyModifiersChanged : rec->what = nullEvent ; break ; + default : converted = false ; break ; } + if ( converted ) { UInt32 keyCode ; unsigned char charCode ; UInt32 modifiers ; +#ifndef __LP64__ GetMouse( &rec->where) ; - +#endif 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); @@ -870,20 +1036,26 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) } } break ; + case kEventClassTextInput : { - switch( GetEventKind( event ) ) + switch ( GetEventKind( event ) ) { case kEventTextInputUnicodeForKeyEvent : { EventRef rawEvent ; - err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ; + err = GetEventParameter( + event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, + sizeof(rawEvent), NULL, &rawEvent ) ; converted = true ; + { - UInt32 keyCode ; + UInt32 keyCode, modifiers; unsigned char charCode ; - UInt32 modifiers ; +#ifndef __LP64__ + GetMouse( &rec->where) ; +#endif rec->what = keyDown ; err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode); @@ -892,12 +1064,16 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) rec->message = (keyCode << 8 ) + charCode ; } } - break ; + break ; + default : break ; } } break ; + + default : + break ; } } @@ -910,50 +1086,12 @@ wxApp::wxApp() m_macCurrentEvent = NULL ; m_macCurrentEventHandlerCallRef = NULL ; + #ifdef __WXMAC_OSX__ m_macEventPosted = NULL ; #endif } -int wxApp::MainLoop() -{ - m_keepGoing = TRUE; -#if wxMAC_USE_RAEL - RunApplicationEventLoop() ; -#else - while (m_keepGoing) - { - MacDoOneEvent() ; - } -#endif - return 0; -} - -void wxApp::ExitMainLoop() -{ - m_keepGoing = FALSE; -#if wxMAC_USE_RAEL - QuitApplicationEventLoop() ; -#endif -} - -// Is a message/event pending? -bool wxApp::Pending() -{ - // without the receive event (with pull param = false ) nothing is ever reported - EventRef theEvent; - ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent); - return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ; -} - -// Dispatch a message. -bool wxApp::Dispatch() -{ - MacDoOneEvent() ; - - return true; -} - void wxApp::OnIdle(wxIdleEvent& event) { wxAppBase::OnIdle(event); @@ -963,7 +1101,7 @@ void wxApp::OnIdle(wxIdleEvent& event) // wxPostEvent() functions wxMacProcessNotifierAndPendingEvents(); - if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar()) + if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar()) wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar(); } @@ -975,19 +1113,14 @@ void wxApp::WakeUpIdle() CFRunLoopSourceSignal(m_macEventPosted); } #endif - wxMacWakeUp() ; -} -void wxApp::Exit() -{ - wxApp::CleanUp(); - ::ExitToShell() ; + wxMacWakeUp() ; } void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event)) { if (GetTopWindow()) - GetTopWindow()->Close(TRUE); + GetTopWindow()->Close(true); } // Default behaviour: close the application with prompts. The @@ -997,7 +1130,7 @@ void wxApp::OnQueryEndSession(wxCloseEvent& event) if (GetTopWindow()) { if (!GetTopWindow()->Close(!event.CanVeto())) - event.Veto(TRUE); + event.Veto(true); } } @@ -1018,17 +1151,18 @@ bool wxApp::Yield(bool onlyIfNeeded) wxFAIL_MSG( wxT("wxYield called recursively" ) ); } - return FALSE; + return false; } - s_inYield = TRUE; + s_inYield = true; // by definition yield should handle all non-processed events EventRef theEvent; OSStatus status = noErr ; - do + + while ( status == noErr ) { s_inReceiveEvent = true ; status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ; @@ -1049,12 +1183,12 @@ bool wxApp::Yield(bool onlyIfNeeded) MacHandleOneEvent( theEvent ) ; ReleaseEvent(theEvent); } - } while( status == noErr ) ; + } wxMacProcessNotifierAndPendingEvents() ; - s_inYield = FALSE; + s_inYield = false; - return TRUE; + return true; } void wxApp::MacDoOneEvent() @@ -1062,25 +1196,28 @@ void wxApp::MacDoOneEvent() EventRef theEvent; s_inReceiveEvent = true ; - OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ; + OSStatus status = ReceiveNextEvent(0, NULL, sleepTime, true, &theEvent) ; s_inReceiveEvent = false ; - if ( status == eventLoopTimedOutErr ) + + switch (status) { - if ( wxTheApp->ProcessIdle() ) + case eventLoopTimedOutErr : + if ( wxTheApp->ProcessIdle() ) + sleepTime = kEventDurationNoWait ; + else + sleepTime = kEventDurationSecond; + break; + + case eventLoopQuitErr : + // according to QA1061 this may also occur + // when a WakeUp Process is executed + break; + + default: + MacHandleOneEvent( theEvent ) ; + ReleaseEvent( theEvent ); sleepTime = kEventDurationNoWait ; - else - sleepTime = kEventDurationSecond; - } - else if ( status == eventLoopQuitErr ) - { - // according to QA1061 this may also occur when a WakeUp Process - // is executed - } - else - { - MacHandleOneEvent( theEvent ) ; - ReleaseEvent(theEvent); - sleepTime = kEventDurationNoWait ; + break; } // repeaters @@ -1088,9 +1225,18 @@ void wxApp::MacDoOneEvent() wxMacProcessNotifierAndPendingEvents() ; } -/*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr ) +// virtual +void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr ) { - // Override to process unhandled events as you please + // 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 ) @@ -1098,120 +1244,160 @@ void wxApp::MacHandleOneEvent( WXEVENTREF evr ) EventTargetRef theTarget; theTarget = GetEventDispatcherTarget(); m_macCurrentEvent = evr ; - OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget); - if(status == eventNotHandledErr) - { + + OSStatus status = SendEventToEventTarget((EventRef) evr , theTarget); + 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) ; long wxMacTranslateKey(unsigned char key, unsigned char code) { long retval = key ; switch (key) { case kHomeCharCode : - retval = WXK_HOME; - break; + retval = WXK_HOME; + break; + case kEnterCharCode : - retval = WXK_RETURN; - break; + retval = WXK_RETURN; + break; case kEndCharCode : - retval = WXK_END; - break; + retval = WXK_END; + break; + case kHelpCharCode : - retval = WXK_HELP; - break; + retval = WXK_HELP; + break; + case kBackspaceCharCode : - retval = WXK_BACK; - break; + retval = WXK_BACK; + break; + case kTabCharCode : - retval = WXK_TAB; - break; + retval = WXK_TAB; + break; + case kPageUpCharCode : - retval = WXK_PAGEUP; - break; + retval = WXK_PAGEUP; + break; + case kPageDownCharCode : - retval = WXK_PAGEDOWN; - break; + retval = WXK_PAGEDOWN; + break; + case kReturnCharCode : - retval = WXK_RETURN; - break; - case kFunctionKeyCharCode : + retval = WXK_RETURN; + break; + + case kFunctionKeyCharCode : + { + switch ( code ) { - switch( code ) - { - case 0x7a : - retval = WXK_F1 ; - break; - case 0x78 : - retval = WXK_F2 ; - break; - case 0x63 : - retval = WXK_F3 ; - break; - case 0x76 : - retval = WXK_F4 ; - break; - case 0x60 : - retval = WXK_F5 ; - break; - case 0x61 : - retval = WXK_F6 ; - break; - case 0x62: - retval = WXK_F7 ; - break; - case 0x64 : - retval = WXK_F8 ; - break; - case 0x65 : - retval = WXK_F9 ; - break; - case 0x6D : - retval = WXK_F10 ; - break; - case 0x67 : - retval = WXK_F11 ; - break; - case 0x6F : - retval = WXK_F12 ; - break; - case 0x69 : - retval = WXK_F13 ; - break; - case 0x6B : - retval = WXK_F14 ; - break; - case 0x71 : - retval = WXK_F15 ; - break; - } + case 0x7a : + retval = WXK_F1 ; + break; + + case 0x78 : + retval = WXK_F2 ; + break; + + case 0x63 : + retval = WXK_F3 ; + break; + + case 0x76 : + retval = WXK_F4 ; + break; + + case 0x60 : + retval = WXK_F5 ; + break; + + case 0x61 : + retval = WXK_F6 ; + break; + + case 0x62: + retval = WXK_F7 ; + break; + + case 0x64 : + retval = WXK_F8 ; + break; + + case 0x65 : + retval = WXK_F9 ; + break; + + case 0x6D : + retval = WXK_F10 ; + break; + + case 0x67 : + retval = WXK_F11 ; + break; + + case 0x6F : + retval = WXK_F12 ; + break; + + case 0x69 : + retval = WXK_F13 ; + break; + + case 0x6B : + retval = WXK_F14 ; + break; + + case 0x71 : + retval = WXK_F15 ; + break; + + default: + break; } + } + break ; + + case kEscapeCharCode : + retval = WXK_ESCAPE ; break ; - case kEscapeCharCode : - retval = WXK_ESCAPE ; + + case kLeftArrowCharCode : + retval = WXK_LEFT ; break ; - case kLeftArrowCharCode : - retval = WXK_LEFT ; + + case kRightArrowCharCode : + retval = WXK_RIGHT ; break ; - case kRightArrowCharCode : - retval = WXK_RIGHT ; + + case kUpArrowCharCode : + retval = WXK_UP ; break ; - case kUpArrowCharCode : - retval = WXK_UP ; + + case kDownArrowCharCode : + retval = WXK_DOWN ; break ; - case kDownArrowCharCode : - retval = WXK_DOWN ; + + case kDeleteCharCode : + retval = WXK_DELETE ; break ; - case kDeleteCharCode : - retval = WXK_DELETE ; - default: + + default: break ; } // end switch @@ -1252,148 +1438,128 @@ bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below //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)); + return !!(GetCurrentKeyModifiers() & wxMacKeyCodeToModifier(key)); //else -// KeyMapByteArray keymap; +// KeyMapByteArray keymap; // GetKeys((BigEndianLong*)keymap); // return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey)); } #endif -bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +wxMouseState wxGetMouseState() { - if ( !focus ) - return false ; + wxMouseState ms; - short keycode ; - short keychar ; - keychar = short(keymessage & charCodeMask); - keycode = short(keymessage & keyCodeMask) >> 8 ; + wxPoint pt = wxGetMousePosition(); + ms.SetX(pt.x); + ms.SetY(pt.y); - if ( modifiers & ( controlKey|shiftKey|optionKey ) ) - { - // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier - // and look at the character after - UInt32 state = 0; - UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); - keychar = short(keyInfo & charCodeMask); - } - long keyval = wxMacTranslateKey(keychar, keycode) ; - long realkeyval = keyval ; - if ( keyval == keychar ) - { - // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first) - realkeyval = short(keymessage & charCodeMask) ; - keyval = wxToupper( keyval ) ; - } +#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 - // Check for NUMPAD keys - if (keyval >= '0' && keyval <= '9' && keycode >= 82 && keycode <= 92) - { - keyval = keyval - '0' + WXK_NUMPAD0; - } - else if (keycode >= 67 && 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; - } // end switch - } + UInt32 modifiers = GetCurrentKeyModifiers(); + ms.SetControlDown(modifiers & controlKey); + ms.SetShiftDown(modifiers & shiftKey); + ms.SetAltDown(modifiers & optionKey); + ms.SetMetaDown(modifiers & cmdKey); + + return ms; +} + +// TODO : once the new key/char handling is tested, move all the code to wxWindow + +bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +{ + if ( !focus ) + return false ; + + bool handled; + wxKeyEvent event(wxEVT_KEY_DOWN) ; + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - wxKeyEvent event(wxEVT_KEY_DOWN); - bool handled = false ; - event.m_shiftDown = modifiers & shiftKey; - event.m_controlDown = modifiers & controlKey; - event.m_altDown = modifiers & optionKey; - event.m_metaDown = modifiers & cmdKey; - event.m_keyCode = keyval ; -#if wxUSE_UNICODE - event.m_uniChar = uniChar ; -#endif - event.m_rawCode = keymessage; - event.m_rawFlags = modifiers; - event.m_x = wherex; - event.m_y = wherey; - event.SetTimestamp(when); - event.SetEventObject(focus); handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) handled = false ; + +#if wxUSE_ACCEL if ( !handled ) { -#if wxUSE_ACCEL - if (!handled) + wxWindow *ancestor = focus; + while (ancestor) { - wxWindow *ancestor = focus; - while (ancestor) + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) { - int command = ancestor->GetAcceleratorTable()->GetCommand( event ); - if (command != -1) - { - wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); - handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); - break; - } - if (ancestor->IsTopLevel()) - break; - ancestor = ancestor->GetParent(); + wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); + break; } - } -#endif // wxUSE_ACCEL - } - if (!handled) - { - wxTopLevelWindowMac *tlw = focus->MacGetTopLevelWindow() ; - if (tlw) - { - event.Skip( FALSE ) ; - event.SetEventType( wxEVT_CHAR_HOOK ); - // raw value again - event.m_keyCode = realkeyval ; - - handled = tlw->GetEventHandler()->ProcessEvent( event ); - if ( handled && event.GetSkipped() ) - handled = false ; + if (ancestor->IsTopLevel()) + break; + + ancestor = ancestor->GetParent(); } } - - if ( !handled ) - { - event.Skip( FALSE ) ; - event.SetEventType( wxEVT_CHAR ) ; - // raw value again - event.m_keyCode = realkeyval ; +#endif // wxUSE_ACCEL - handled = focus->GetEventHandler()->ProcessEvent( event ) ; + return handled ; +} + +bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +{ + if ( !focus ) + return false ; + + bool handled; + wxKeyEvent event( wxEVT_KEY_UP ) ; + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + + return handled ; +} + +bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +{ + if ( !focus ) + return false ; + + wxKeyEvent event(wxEVT_CHAR) ; + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; + long keyval = event.m_keyCode ; + + bool handled = false ; + + wxTopLevelWindowMac *tlw = focus->MacGetTopLevelWindow() ; + + if (tlw) + { + event.SetEventType( wxEVT_CHAR_HOOK ); + handled = tlw->GetEventHandler()->ProcessEvent( event ); if ( handled && event.GetSkipped() ) handled = false ; } + + if ( !handled ) + { + event.SetEventType( wxEVT_CHAR ); + event.Skip( false ) ; + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + } + if ( !handled && (keyval == WXK_TAB) ) { wxWindow* iter = focus->GetParent() ; - while( iter && !handled ) + while ( iter && !handled ) { if ( iter->HasFlag( wxTAB_TRAVERSAL ) ) { @@ -1407,69 +1573,71 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifi if ( handled && new_event.GetSkipped() ) handled = false ; } + iter = iter->GetParent() ; } } + // backdoor handler for default return and command escape if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) ) { - // if window is not having a focus still testing for default enter or cancel - // TODO add the UMA version for ActiveNonFloatingWindow - wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; - if ( focus ) - { + // if window is not having a focus still testing for default enter or cancel + // TODO: add the UMA version for ActiveNonFloatingWindow + wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ; + if ( focus ) + { if ( keyval == WXK_RETURN ) { - wxButton *def = wxDynamicCast(focus->GetDefaultItem(), - wxButton); - if ( def && def->IsEnabled() ) - { - wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); - event.SetEventObject(def); - def->Command(event); - return true ; + wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(focus), wxTopLevelWindow); + if ( tlw && tlw->GetDefaultItem() ) + { + 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 ; + } } } - /* generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) */ else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) { - wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); - new_event.SetEventObject( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); + // 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 ); } - } + } } return handled ; } -bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +// This method handles common code for SendKeyDown, SendKeyUp, and SendChar events. +void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) { - if ( !focus ) - return false ; + short keycode, keychar ; - short keycode ; - short keychar ; keychar = short(keymessage & charCodeMask); keycode = short(keymessage & keyCodeMask) >> 8 ; - if ( modifiers & ( controlKey|shiftKey|optionKey ) ) + if ( !(event.GetEventType() == wxEVT_CHAR) && (modifiers & (controlKey | shiftKey | optionKey) ) ) { // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier // and look at the character after UInt32 state = 0; - UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state); + UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state); keychar = short(keyInfo & charCodeMask); } - long keyval = wxMacTranslateKey(keychar, keycode) ; - if ( keyval == keychar ) - { + 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) { - keyval = keyval - '0' + WXK_NUMPAD0; + keyval = (keyval - '0') + WXK_NUMPAD0; } else if (keycode >= 67 && keycode <= 81) { @@ -1478,30 +1646,36 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier 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 } - bool handled = false ; - - wxKeyEvent event(wxEVT_KEY_UP); event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; @@ -1517,7 +1691,4 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifier event.m_y = wherey; event.SetTimestamp(when); event.SetEventObject(focus); - handled = focus->GetEventHandler()->ProcessEvent( event ) ; - - return handled ; }