X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ed581ee2b8d53d0780b5d8d06c1325295121fc06..b8c140b89f5e01564b79c0a779b0b4aba2542351:/src/mac/app.cpp diff --git a/src/mac/app.cpp b/src/mac/app.cpp index 272f8f5f3f..3828e3612f 100644 --- a/src/mac/app.cpp +++ b/src/mac/app.cpp @@ -91,15 +91,15 @@ const short kMacMinHeap = (29 * 1024) ; 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; +WXHRGN wxApp::s_macCursorRgn = NULL; +wxWindow* wxApp::s_captureWindow = NULL ; +int wxApp::s_lastMouseDown = 0 ; +long wxApp::sm_lastMessageTime = 0; -bool wxApp::s_macDefaultEncodingIsPC = true ; -bool wxApp::s_macSupportPCMenuShortcuts = true ; -long wxApp::s_macAboutMenuItemId = wxID_ABOUT ; -wxString wxApp::s_macHelpMenuTitleName = "&Help" ; +bool wxApp::s_macDefaultEncodingIsPC = true ; +bool wxApp::s_macSupportPCMenuShortcuts = true ; +long wxApp::s_macAboutMenuItemId = wxID_ABOUT ; +wxString wxApp::s_macHelpMenuTitleName = "&Help" ; pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ; pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ; @@ -107,31 +107,31 @@ pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long re pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ; -pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ; } -pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ; } -pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) +pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) ) { // GD: UNUSED wxApp* app = (wxApp*) refcon ; return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ; } -short wxApp::MacHandleAEODoc(const WXEVENTREF event , WXEVENTREF reply) +short wxApp::MacHandleAEODoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { SysBeep(40) ; ProcessSerialNumber PSN ; @@ -141,17 +141,17 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event , WXEVENTREF reply) return noErr ; } -short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF reply) +short wxApp::MacHandleAEPDoc(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { return noErr ; } -short wxApp::MacHandleAEOApp(const WXEVENTREF event , WXEVENTREF reply) +short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { return noErr ; } -short wxApp::MacHandleAEQuit(const WXEVENTREF event , WXEVENTREF reply) +short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { wxWindow* win = GetTopWindow() ; if ( win ) @@ -384,39 +384,52 @@ WXIMPORT char std::__throws_bad_alloc ; bool wxApp::Initialize() { - int error = 0 ; + int error = 0 ; - // Mac-specific + // Mac-specific - UMAInitToolbox( 4 ) ; - SetEventMask( everyEvent ) ; + UMAInitToolbox( 4 ) ; + SetEventMask( everyEvent ) ; UMAShowWatchCursor() ; +#if defined(WXMAKINGDLL) && defined(__DARWIN__) + // open shared library resources from here since we don't have + // __wxinitialize in Mach-O shared libraries + wxStAppResource::OpenSharedLibraryResource(NULL); +#endif + #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340) - AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerUPP(AEHandleODoc) , + AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , + NewAEEventHandlerUPP(AEHandleODoc) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerUPP(AEHandleOApp) , + AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , + NewAEEventHandlerUPP(AEHandleOApp) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerUPP(AEHandlePDoc) , + AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , + NewAEEventHandlerUPP(AEHandlePDoc) , (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerUPP(AEHandleQuit) , + AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , + NewAEEventHandlerUPP(AEHandleQuit) , (long) wxTheApp , FALSE ) ; #else - AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerProc(AEHandleODoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , NewAEEventHandlerProc(AEHandleOApp) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , NewAEEventHandlerProc(AEHandlePDoc) , - (long) wxTheApp , FALSE ) ; - AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , NewAEEventHandlerProc(AEHandleQuit) , - (long) wxTheApp , FALSE ) ; + AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , + NewAEEventHandlerProc(AEHandleODoc) , + (long) wxTheApp , FALSE ) ; + AEInstallEventHandler( kCoreEventClass , kAEOpenApplication , + NewAEEventHandlerProc(AEHandleOApp) , + (long) wxTheApp , FALSE ) ; + AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments , + NewAEEventHandlerProc(AEHandlePDoc) , + (long) wxTheApp , FALSE ) ; + AEInstallEventHandler( kCoreEventClass , kAEQuitApplication , + NewAEEventHandlerProc(AEHandleQuit) , + (long) wxTheApp , FALSE ) ; #endif - #ifndef __DARWIN__ - // test the minimal configuration necessary + // test the minimal configuration necessary - #if !TARGET_CARBON +# if !TARGET_CARBON long theSystem ; long theMachine; @@ -440,7 +453,7 @@ bool wxApp::Initialize() { error = kMacSTRSmallSize; } - #endif +# endif /* else { @@ -468,9 +481,9 @@ bool wxApp::Initialize() } #ifndef __DARWIN__ - #if __option(profile) +# if __option(profile) ProfilerInit( collectDetailed, bestTimeBase , 20000 , 40 ) ; - #endif +# endif #endif #ifndef __DARWIN__ @@ -527,6 +540,7 @@ bool wxApp::Initialize() wxMacCreateNotifierTable() ; + UMAShowArrowCursor() ; return TRUE; @@ -549,50 +563,51 @@ void wxApp::CleanUp() // One last chance for pending objects to be cleaned up wxTheApp->DeletePendingObjects(); - wxModule::CleanUpModules(); + wxModule::CleanUpModules(); #if wxUSE_WX_RESOURCES - wxCleanUpResourceSystem(); + wxCleanUpResourceSystem(); #endif - wxDeleteStockObjects() ; + wxDeleteStockObjects() ; // Destroy all GDI lists, etc. wxDeleteStockLists(); - delete wxTheColourDatabase; - wxTheColourDatabase = NULL; - - wxBitmap::CleanUpHandlers(); + delete wxTheColourDatabase; + wxTheColourDatabase = NULL; - delete[] wxBuffer; - wxBuffer = NULL; + wxBitmap::CleanUpHandlers(); - wxMacDestroyNotifierTable() ; - if (wxWinMacWindowList) - delete wxWinMacWindowList ; - - if (wxWinMacControlList) - delete wxWinMacControlList ; + delete[] wxBuffer; + wxBuffer = NULL; + wxMacDestroyNotifierTable() ; + if (wxWinMacWindowList) { + delete wxWinMacWindowList ; + } + if (wxWinMacControlList) { + delete wxWinMacControlList ; + } delete wxPendingEvents; + #if wxUSE_THREADS delete wxPendingEventsLocker; // If we don't do the following, we get an apparent memory leak. ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker(); #endif - wxClassInfo::CleanUpClasses(); + wxClassInfo::CleanUpClasses(); #ifndef __DARWIN__ - #if __option(profile) - ProfilerDump( "\papp.prof" ) ; - ProfilerTerm() ; - #endif +# if __option(profile) + ProfilerDump( "\papp.prof" ) ; + ProfilerTerm() ; +# endif #endif - delete wxTheApp; - wxTheApp = NULL; + delete wxTheApp; + wxTheApp = NULL; #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT // At this point we want to check if there are any memory @@ -613,10 +628,17 @@ void wxApp::CleanUp() delete wxLog::SetActiveTarget(NULL); #endif // wxUSE_LOG +#if defined(WXMAKINGDLL) && defined(__DARWIN__) + // close shared library resources from here since we don't have + // __wxterminate in Mach-O shared libraries + wxStAppResource::CloseSharedLibraryResource(); +#endif + UMACleanupToolbox() ; - if (s_macCursorRgn) + if (s_macCursorRgn) { ::DisposeRgn((RgnHandle)s_macCursorRgn); - + } + #if 0 TerminateAE() ; #endif @@ -626,26 +648,64 @@ void wxApp::CleanUp() // wxEntry //---------------------------------------------------------------------- -short gCurrentResource = -1 ; +// extern variable for shared library resource id +// need to be able to find it with NSLookupAndBindSymbol +short gSharedLibraryResource = kResFileNotOpened ; + #if defined(WXMAKINGDLL) && defined(__DARWIN__) -CFBundleRef gDylibBundle = NULL; +CFBundleRef gSharedLibraryBundle = NULL; #endif /* WXMAKINGDLL && __DARWIN__ */ wxStAppResource::wxStAppResource() { -#if defined(WXMAKINGDLL) && defined(__DARWIN__) - // Open the shared library resource file if it is not yet open - if (gCurrentResource == -1) { + m_currentRefNum = CurResFile() ; + if ( gSharedLibraryResource != kResFileNotOpened ) + { + UseResFile( gSharedLibraryResource ) ; + } +} + +wxStAppResource::~wxStAppResource() +{ + if ( m_currentRefNum != kResFileNotOpened ) + { + UseResFile( m_currentRefNum ) ; + } +} + +void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) +{ + gSharedLibraryResource = kResFileNotOpened; + +#ifdef WXMAKINGDLL + if ( initBlock != NULL ) { + const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock; + FSSpec *fileSpec = NULL; + + if (theInitBlock->fragLocator.where == kDataForkCFragLocator) { + fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec; + } + else if (theInitBlock->fragLocator.where == kResourceCFragLocator) { + fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec; + } + + if (fileSpec != NULL) { + gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm); + } + } + else { +#ifdef __DARWIN__ + // Open the shared library resource file if it is not yet open NSSymbol theSymbol; NSModule theModule; const char *theLibPath; - gDylibBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows")); - if (gDylibBundle != NULL) { + gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows")); + if (gSharedLibraryBundle != NULL) { // wxWindows has been bundled into a framework // load the framework resources - gCurrentResource = CFBundleOpenBundleResourceMap(gDylibBundle); + gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle); } else { // wxWindows is a simple dynamic shared library @@ -657,11 +717,9 @@ wxStAppResource::wxStAppResource() OSErr theErr = noErr; // get the library path - theSymbol = NSLookupAndBindSymbol("_gCurrentResource"); + theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource"); theModule = NSModuleForSymbol(theSymbol); theLibPath = NSLibraryNameForModule(theModule); - - wxLogDebug( theLibPath ); // allocate copy to replace .dylib.* extension with .rsrc theResPath = strdup(theLibPath); @@ -690,54 +748,34 @@ wxStAppResource::wxStAppResource() // open the resource file if (theErr == noErr) { theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm, - &gCurrentResource); + &gSharedLibraryResource); } } } - - /* - char *path; - int i, len; - - if( i++ > 0 ) { - len = i + strlen(rPath); - path = (char*) malloc(len+1); - } - else { - // try current directory - myerr = FSPathMakeRef((UInt8 *) rPath, &myref, false); - } - */ - } -#endif /* WXMAKINGDLL && __DARWIN__ */ - - m_currentRefNum = CurResFile() ; - if ( gCurrentResource != -1 ) - { - UseResFile( gCurrentResource ) ; +#endif /* __DARWIN__ */ } +#endif /* WXMAKINGDLL */ } -wxStAppResource::~wxStAppResource() +void wxStAppResource::CloseSharedLibraryResource() { - if ( m_currentRefNum != -1 ) - { - UseResFile( m_currentRefNum ) ; - } - -#if defined(WXMAKINGDLL) && defined(__DARWIN__) +#ifdef WXMAKINGDLL // Close the shared library resource file - if (gCurrentResource != -1) { - if (gDylibBundle != NULL) { - CFBundleCloseBundleResourceMap(gDylibBundle, gCurrentResource); - gDylibBundle = NULL; + if (gSharedLibraryResource != kResFileNotOpened) { +#ifdef __DARWIN__ + if (gSharedLibraryBundle != NULL) { + CFBundleCloseBundleResourceMap(gSharedLibraryBundle, + gSharedLibraryResource); + gSharedLibraryBundle = NULL; } - else { - CloseResFile(gCurrentResource); + else +#endif /* __DARWIN__ */ + { + CloseResFile(gSharedLibraryResource); } - gCurrentResource = -1; - } -#endif /* WXMAKINGDLL && __DARWIN__ */ + gSharedLibraryResource = kResFileNotOpened; + } +#endif /* WXMAKINGDLL */ } #if defined(WXMAKINGDLL) && !defined(__DARWIN__) @@ -746,40 +784,27 @@ wxStAppResource::~wxStAppResource() // ref num upon initializing and releasing when terminating, therefore // the __wxinitialize and __wxterminate must be used -#ifdef __cplusplus extern "C" { -#endif - -void __sinit(void); /* (generated by linker) */ -pascal OSErr __initialize(const CFragInitBlock *theInitBlock); -pascal void __terminate(void); - -#ifdef __cplusplus + void __sinit(void); /* (generated by linker) */ + pascal OSErr __initialize(const CFragInitBlock *theInitBlock); + pascal void __terminate(void); } -#endif pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock) { - gCurrentResource = -1; - - if (theInitBlock->fragLocator.where == kDataForkCFragLocator) { - gCurrentResource = - FSpOpenResFile(theInitBlock->fragLocator.u.onDisk.fileSpec, - fsRdPerm); - } - return __initialize( theInitBlock ) ; + wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ; + return __initialize( theInitBlock ) ; } pascal void __wxterminate(void) { - if (gCurrentResource != -1) - CloseResFile(gCurrentResource); + wxStAppResource::CloseSharedLibraryResource() ; __terminate() ; } #endif /* WXMAKINGDLL && !__DARWIN__ */ -int WXDLLEXPORT wxEntryStart( int argc, char *argv[] ) +int WXDLLEXPORT wxEntryStart( int WXUNUSED(argc), char *WXUNUSED(argv)[] ) { return wxApp::Initialize(); } @@ -796,10 +821,6 @@ void WXDLLEXPORT wxEntryCleanup() int wxEntry( int argc, char *argv[] , bool enterLoop ) { -#if !(defined(WXMAKINGDLL) && defined(__DARWIN__)) - gCurrentResource = CurResFile() ; -#endif - #ifdef __MWERKS__ #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT // This seems to be necessary since there are 'rogue' @@ -896,6 +917,136 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) return retValue; } +#if TARGET_CARBON + +bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) +{ + bool converted = ConvertEventRefToEventRecord( event,rec) ; + OSStatus err = noErr ; + if ( !converted ) + { + switch( GetEventClass( event ) ) + { + case kEventClassKeyboard : + { + converted = true ; + 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 ; + 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); + rec->modifiers = modifiers ; + rec->message = (keyCode << 8 ) + charCode ; + } + } + break ; + case kEventClassTextInput : + { + switch( GetEventKind( event ) ) + { + case kEventTextInputUnicodeForKeyEvent : + { + EventRef rawEvent ; + err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ; + converted = true ; + { + UInt32 keyCode ; + unsigned char charCode ; + UInt32 modifiers ; + GetMouse( &rec->where) ; + rec->what = keyDown ; + err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers); + err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode); + err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode); + rec->modifiers = modifiers ; + rec->message = (keyCode << 8 ) + charCode ; + } + } + break ; + default : + break ; + } + } + break ; + } + } + + return converted ; +} + +pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + OSStatus result = eventNotHandledErr ; + + EventRecord rec ; + switch ( GetEventClass( event ) ) + { + case kEventClassKeyboard : + if ( wxMacConvertEventToRecord( event , &rec ) ) + { + wxTheApp->MacHandleOneEvent( &rec ) ; + result = noErr ; + } + break ; + case kEventClassTextInput : + if ( wxMacConvertEventToRecord( event , &rec ) ) + { + wxTheApp->MacHandleOneEvent( &rec ) ; + result = noErr ; + } + break ; + default : + break ; + } + return result ; +} + +#endif + +bool wxApp::OnInit() +{ + if ( ! wxAppBase::OnInit() ) + return FALSE ; + +#if 0 // TARGET_CARBON + static const EventTypeSpec eventList[] = + { + { kEventClassKeyboard, kEventRawKeyDown } , + { kEventClassKeyboard, kEventRawKeyRepeat } , + { kEventClassKeyboard, kEventRawKeyUp } , + { kEventClassKeyboard, kEventRawKeyModifiersChanged } , + + { kEventClassTextInput , kEventTextInputUnicodeForKeyEvent } , + } ; + + InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler) + , WXSIZEOF(eventList), eventList, this, NULL); +#endif + return TRUE ; +} // Static member initialization wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; @@ -1145,25 +1296,38 @@ void wxApp::MacSuspend( bool convertClipboard ) node = node->Next(); } - - s_lastMouseDown = 0 ; - if( convertClipboard ) - { - MacConvertPrivateToPublicScrap() ; - } - - ::HideFloatingWindows() ; + + s_lastMouseDown = 0 ; + if( convertClipboard ) + { + MacConvertPrivateToPublicScrap() ; + } + + ::HideFloatingWindows() ; } +extern wxList wxModalDialogs; + void wxApp::MacResume( bool convertClipboard ) { - s_lastMouseDown = 0 ; - if( convertClipboard ) - { - MacConvertPublicToPrivateScrap() ; - } + s_lastMouseDown = 0 ; + if( convertClipboard ) + { + MacConvertPublicToPrivateScrap() ; + } + + ::ShowFloatingWindows() ; + + // raise modal dialogs in case a non modal window was selected to activate the app - ::ShowFloatingWindows() ; + wxNode* node = wxModalDialogs.First(); + while (node) + { + wxDialog* dialog = (wxDialog *) node->Data(); + dialog->Raise(); + + node = node->Next(); + } } void wxApp::MacConvertPrivateToPublicScrap() @@ -1567,7 +1731,7 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) if ( HiWord( menuresult ) ) { if ( !s_macIsInModalLoop ) - MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ; + MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ; } else { @@ -1576,80 +1740,101 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) keychar = short(ev->message & charCodeMask); keycode = short(ev->message & keyCodeMask) >> 8 ; long keyval = wxMacTranslateKey(keychar, keycode) ; - bool handled = false ; wxWindow* focus = wxWindow::FindFocus() ; - if ( focus ) - { - wxKeyEvent event(wxEVT_KEY_DOWN); - event.m_shiftDown = ev->modifiers & shiftKey; - event.m_controlDown = ev->modifiers & controlKey; - event.m_altDown = ev->modifiers & optionKey; - event.m_metaDown = ev->modifiers & cmdKey; - event.m_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - handled = focus->GetEventHandler()->ProcessEvent( event ) ; - if ( !handled ) + if ( MacSendKeyDownEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false ) + { + // has not been handled -> perform default + wxControl* control = wxDynamicCast( focus , wxControl ) ; + if ( control && control->GetMacControl() != NULL ) { + ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ; + } + } + } +} + +bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey ) +{ + bool handled = false ; + // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value + if ( modifiers & controlKey && keyval >= 0 && keyval < 0x20 ) + { + keyval += 0x40 ; + } + wxKeyEvent event(wxEVT_KEY_DOWN); + event.m_shiftDown = modifiers & shiftKey; + event.m_controlDown = modifiers & controlKey; + event.m_altDown = modifiers & optionKey; + event.m_metaDown = modifiers & cmdKey; + event.m_keyCode = keyval; + + event.m_x = wherex; + event.m_y = wherey; + event.m_timeStamp = when; + event.SetEventObject(focus); + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + if ( !handled ) + { #if wxUSE_ACCEL - if (!handled) + if (!handled) + { + wxWindow *ancestor = focus; + while (ancestor) + { + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) { - /* - wxWindow *ancestor = focus; - while (ancestor) - { - 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->m_isFrame) - break; - ancestor = ancestor->GetParent(); - } - */ + wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + handled = ancestor->GetEventHandler()->ProcessEvent( command_event ); + break; } -#endif // wxUSE_ACCEL - } - if (!handled) - { - wxKeyEvent event(wxEVT_CHAR); - event.m_shiftDown = ev->modifiers & shiftKey; - event.m_controlDown = ev->modifiers & controlKey; - event.m_altDown = ev->modifiers & optionKey; - event.m_metaDown = ev->modifiers & cmdKey; - event.m_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - handled = focus->GetEventHandler()->ProcessEvent( event ) ; - } - if ( !handled && - (keyval == WXK_TAB) && - (!focus->HasFlag(wxTE_PROCESS_TAB)) && - (focus->GetParent()) && - (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) - { - wxNavigationKeyEvent new_event; - new_event.SetEventObject( focus ); - new_event.SetDirection( !event.ShiftDown() ); - /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ - new_event.SetWindowChange( event.ControlDown() ); - new_event.SetCurrentFocus( focus ); - handled = focus->GetEventHandler()->ProcessEvent( new_event ); + if (ancestor->IsTopLevel()) + break; + ancestor = ancestor->GetParent(); } } - if ( !handled ) - { - // if window is not having a focus still testing for default enter or cancel - // TODO add the UMA version for ActiveNonFloatingWindow - focus = wxFindWinFromMacWindow( FrontWindow() ) ; +#endif // wxUSE_ACCEL + } + if (!handled) + { + event.Skip( FALSE ) ; + event.SetEventType( wxEVT_CHAR ) ; + + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + } + if ( !handled && + (keyval == WXK_TAB) && +// CS: copied the change below from wxGTK +// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may +// have this style, yet choose not to process this particular TAB in which +// case TAB must still work as a navigational character +#if 0 + (!focus->HasFlag(wxTE_PROCESS_TAB)) && +#endif + (focus->GetParent()) && + (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) + { + wxNavigationKeyEvent new_event; + new_event.SetEventObject( focus ); + new_event.SetDirection( !event.ShiftDown() ); + /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + new_event.SetWindowChange( event.ControlDown() ); + new_event.SetCurrentFocus( focus ); + handled = focus->GetEventHandler()->ProcessEvent( new_event ); + if ( handled && new_event.GetSkipped() ) + handled = false ; + } + // 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 ( keyval == WXK_RETURN ) @@ -1661,21 +1846,22 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); event.SetEventObject(def); def->Command(event); - return ; + return true ; } } /* generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) */ - else if (keyval == WXK_ESCAPE || (keyval == '.' && ev->modifiers & cmdKey ) ) + 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 ); } } - } } + return handled ; } + void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1691,27 +1877,39 @@ void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) short keychar ; keychar = short(ev->message & charCodeMask); keycode = short(ev->message & keyCodeMask) >> 8 ; + long keyval = wxMacTranslateKey(keychar, keycode) ; wxWindow* focus = wxWindow::FindFocus() ; - if ( focus ) - { - long keyval = wxMacTranslateKey(keychar, keycode) ; - - wxKeyEvent event(wxEVT_KEY_UP); - event.m_shiftDown = ev->modifiers & shiftKey; - event.m_controlDown = ev->modifiers & controlKey; - event.m_altDown = ev->modifiers & optionKey; - event.m_metaDown = ev->modifiers & cmdKey; - event.m_keyCode = keyval; - event.m_x = ev->where.h; - event.m_y = ev->where.v; - event.m_timeStamp = ev->when; - event.SetEventObject(focus); - bool handled = focus->GetEventHandler()->ProcessEvent( event ) ; - } + bool handled = MacSendKeyUpEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; + // we don't have to do anything under classic here } } +bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keyval , long modifiers , long when , short wherex , short wherey ) +{ + bool handled = false ; + // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value + if ( modifiers & controlKey && keyval >= 0 && keyval < 0x20 ) + { + keyval += 0x40 ; + } + if ( focus ) + { + wxKeyEvent event(wxEVT_KEY_UP); + event.m_shiftDown = modifiers & shiftKey; + event.m_controlDown = modifiers & controlKey; + event.m_altDown = modifiers & optionKey; + event.m_metaDown = modifiers & cmdKey; + event.m_keyCode = keyval; + + event.m_x = wherex; + event.m_y = wherey; + event.m_timeStamp = when; + event.SetEventObject(focus); + handled = focus->GetEventHandler()->ProcessEvent( event ) ; + } + return handled ; +} void wxApp::MacHandleActivateEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ;