X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6da991dbf0b611c2fb5f337b334037f2641a896b..ec2df34e27ba41f202ecbf096cdfed082a9ddb8f:/src/osx/carbon/app.cpp diff --git a/src/osx/carbon/app.cpp b/src/osx/carbon/app.cpp index 14c97c2f85..f33ac195cc 100644 --- a/src/osx/carbon/app.cpp +++ b/src/osx/carbon/app.cpp @@ -79,7 +79,7 @@ wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ; bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin -#if wxOSX_USE_COCOA_OR_CARBON +#if wxOSX_USE_CARBON //---------------------------------------------------------------------- // Core Apple Event Support @@ -130,7 +130,7 @@ pascal OSErr AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon } -// AEODoc Calls MacOpenFile on each of the files passed +// AEODoc Calls MacOpenFiles with all of the files passed short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) { @@ -158,16 +158,23 @@ short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) wxString fName ; FSRef theRef ; + wxArrayString fileNames; for (i = 1; i <= itemsInList; i++) { - AEGetNthPtr( + err = AEGetNthPtr( &docList, i, typeFSRef, &keywd, &returnedType, (Ptr)&theRef, sizeof(theRef), &actualSize); + + if ( err != noErr) + return err; + fName = wxMacFSRefToPath( &theRef ) ; - MacOpenFile(fName); + fileNames.Add(fName); } + MacOpenFiles(fileNames); + return noErr; } @@ -184,7 +191,7 @@ short wxApp::MacHandleAEGURL(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply)) if (err != noErr) return err; - url[actualSize] = '\0'; // Terminate the C string + url[actualSize] = '\0'; // Terminate the C string ProcessSerialNumber PSN ; PSN.highLongOfPSN = 0 ; @@ -226,9 +233,13 @@ short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply) for (i = 1; i <= itemsInList; i++) { - AEGetNthPtr( + err = AEGetNthPtr( &docList, i, typeFSRef, &keywd, &returnedType, (Ptr)&theRef, sizeof(theRef), &actualSize); + + if ( err != noErr) + return err; + fName = wxMacFSRefToPath( &theRef ) ; MacPrintFile(fName); @@ -249,18 +260,13 @@ short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply)) { - wxWindow* win = GetTopWindow() ; - if ( win ) + wxCloseEvent event; + wxTheApp->OnQueryEndSession(event); + if ( !event.GetVeto() ) { - wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId); - if (!win->ProcessEvent(exitEvent)) - win->Close(true) ; + wxCloseEvent event; + wxTheApp->OnEndSession(event); } - else - { - ExitMainLoop() ; - } - return noErr ; } @@ -279,6 +285,16 @@ short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNU // Support Routines linking the Mac...File Calls to the Document Manager //---------------------------------------------------------------------- +void wxApp::MacOpenFiles(const wxArrayString & fileNames ) +{ + size_t i; + const size_t fileCount = fileNames.GetCount(); + for (i = 0; i < fileCount; i++) + { + MacOpenFile(fileNames[i]); + } +} + void wxApp::MacOpenFile(const wxString & fileName ) { #if wxUSE_DOC_VIEW_ARCHITECTURE @@ -341,7 +357,7 @@ void wxApp::MacReopenApp() // if some windows are not hidden -> do nothing wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); - if ( node == NULL ) + if ( !node ) { MacNewFile() ; } @@ -357,9 +373,9 @@ void wxApp::MacReopenApp() // 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 ; } @@ -374,8 +390,14 @@ void wxApp::MacReopenApp() if ( firstIconized ) firstIconized->Iconize( false ) ; + + // showing hidden windows is not really always a good solution, also non-modal dialogs when closed end up + // as hidden tlws, we don't want to reshow those, so let's just reopen the minimized a.k.a. iconized tlws + // unless we find a regression ... +#if 0 else if ( firstHidden ) firstHidden->Show( true ); +#endif } } @@ -499,7 +521,7 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) // 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 ) ) || - ( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) || + ( helpMenuHandle != NULL && command.menu.menuRef == helpMenuHandle ) || wxMenuBar::MacGetWindowMenuHMenu() != NULL && command.menu.menuRef == wxMenuBar::MacGetWindowMenuHMenu() ) { wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; @@ -508,12 +530,12 @@ wxMenu* wxFindMenuFromMacCommand( const HICommand &command , wxMenuItem* &item ) } else { - URefCon refCon = NULL ; + URefCon refCon = 0 ; GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ; itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ; if ( itemMenu != NULL && refCon != 0) - item = ((wxMenuItemImpl*) refCon)->GetWXPeer() ; + item = (wxMenuItem*) refCon; } } #endif @@ -576,7 +598,7 @@ wxMacAppMenuEventHandler( EventHandlerCallRef WXUNUSED(handler), case kEventMenuTargetItem: { HICommand command ; - + command.menu.menuRef = menuRef; command.menu.menuItemIndex = cEvent.GetParameter(kEventParamMenuItemIndex,typeMenuItemIndex) ; command.commandID = cEvent.GetParameter(kEventParamMenuCommand,typeMenuCommand) ; @@ -702,22 +724,7 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve break ; #endif case kEventClassAppleEvent : - { -#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 ) ; - } -#endif - } + result = AEProcessEvent(event); break ; default : @@ -732,7 +739,7 @@ pascal OSStatus wxMacAppEventHandler( EventHandlerCallRef handler , EventRef eve DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler ) #endif -#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON +#if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON pascal static void wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature), @@ -778,18 +785,13 @@ wxMacAssertOutputHandler(OSType WXUNUSED(componentSignature), #endif } -#endif //__WXDEBUG__ - -extern "C" void macPostedEventCallback(void *WXUNUSED(unused)) -{ - wxTheApp->ProcessPendingEvents(); -} +#endif // wxDEBUG_LEVEL bool wxApp::Initialize(int& argc, wxChar **argv) { // Mac-specific -#if defined( __WXDEBUG__ ) && wxOSX_USE_COCOA_OR_CARBON +#if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) ); #endif @@ -799,12 +801,42 @@ bool wxApp::Initialize(int& argc, wxChar **argv) // application (otherwise applications would need to handle it) if ( argc > 1 ) { - static const wxChar *ARG_PSN = _T("-psn_"); + static const wxChar *ARG_PSN = wxT("-psn_"); if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 ) { // remove this argument --argc; - memmove(argv + 1, argv + 2, argc * sizeof(char *)); + memmove(argv + 1, argv + 2, argc * sizeof(wxChar*)); + } + } + + /* + Cocoa supports -Key value options which set the user defaults key "Key" + to the value "value" Some of them are very handy for debugging like + -NSShowAllViews YES. Cocoa picks these up from the real argv so + our removal of them from the wx copy of it does not affect Cocoa's + ability to see them. + + We basically just assume that any "-NS" option and its following + argument needs to be removed from argv. We hope that user code does + not expect to see -NS options and indeed it's probably a safe bet + since most user code accepting options is probably using the + double-dash GNU-style syntax. + */ + for(int i=1; i < argc; ++i) + { + static const wxChar *ARG_NS = wxT("-NS"); + if( wxStrncmp(argv[i], ARG_NS, wxStrlen(ARG_NS)) == 0 ) + { + // Only eat this option if it has an argument + if( (i + 1) < argc ) + { + memmove(argv + i, argv + i + 2, (argc-i-1)*sizeof(wxChar*)); + argc -= 2; + // drop back one position so the next run through the loop + // reprocesses the argument at our current index. + --i; + } } } @@ -828,24 +860,16 @@ bool wxApp::Initialize(int& argc, wxChar **argv) wxSetWorkingDirectory( cwd ) ; } - /* 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); - // run loop takes ownership - CFRelease(m_macEventPosted); - */ return true; } +#if wxOSX_USE_COCOA_OR_CARBON bool wxApp::CallOnInit() { wxMacAutoreleasePool autoreleasepool; return OnInit(); } +#endif bool wxApp::OnInitGui() { @@ -864,6 +888,12 @@ bool wxApp::ProcessIdle() return wxAppBase::ProcessIdle(); } +int wxApp::OnRun() +{ + wxMacAutoreleasePool pool; + return wxAppBase::OnRun(); +} + #if wxOSX_USE_CARBON bool wxApp::DoInitGui() { @@ -900,7 +930,7 @@ bool wxApp::DoInitGui() if ( !wxMacInitCocoa() ) return false; - + return true; } @@ -937,16 +967,11 @@ void wxApp::DoCleanUp() void wxApp::CleanUp() { + wxMacAutoreleasePool autoreleasepool; #if wxUSE_TOOLTIPS wxToolTip::RemoveToolTips() ; #endif - if (m_macEventPosted) - { - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes); - m_macEventPosted = NULL; - } - DoCleanUp(); wxAppBase::CleanUp(); @@ -956,105 +981,19 @@ void wxApp::CleanUp() // misc initialization stuff //---------------------------------------------------------------------- -#if wxOSX_USE_CARBON && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) -{ - OSStatus err = noErr ; - bool converted = ConvertEventRefToEventRecord( event, rec) ; - - 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, modifiers; - unsigned char charCode ; - 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 ; - - default : - break ; - } - } - - return converted ; -} -#endif - wxApp::wxApp() { m_printMode = wxPRINT_WINDOWS; m_macCurrentEvent = NULL ; m_macCurrentEventHandlerCallRef = NULL ; - m_macEventPosted = NULL ; + m_macPool = new wxMacAutoreleasePool(); +} + +wxApp::~wxApp() +{ + if (m_macPool) + delete m_macPool; } CFMutableArrayRef GetAutoReleaseArray() @@ -1070,6 +1009,13 @@ void wxApp::MacAddToAutorelease( void* cfrefobj ) CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj ); } +void wxApp::MacReleaseAutoreleasePool() +{ + if (m_macPool) + delete m_macPool; + m_macPool = new wxMacAutoreleasePool(); +} + void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event)) { // If they are pending events, we must process them: pending events are @@ -1086,12 +1032,10 @@ void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event)) void wxApp::WakeUpIdle() { - if (m_macEventPosted) - { - CFRunLoopSourceSignal(m_macEventPosted); - } + wxEventLoopBase * const loop = wxEventLoopBase::GetActive(); - wxMacWakeUp() ; + if ( loop ) + loop->WakeUp(); } void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event)) @@ -1104,10 +1048,17 @@ void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event)) // user can veto the close, and therefore the end session. void wxApp::OnQueryEndSession(wxCloseEvent& event) { - if (GetTopWindow()) + if ( !wxDialog::OSXHasModalDialogsOpen() ) + { + if (GetTopWindow()) + { + if (!GetTopWindow()->Close(!event.CanVeto())) + event.Veto(true); + } + } + else { - if (!GetTopWindow()->Close(!event.CanVeto())) - event.Veto(true); + event.Veto(true); } } @@ -1117,69 +1068,144 @@ void wxCYield() wxYield() ; } -// Yield to other processes - -bool wxApp::Yield(bool onlyIfNeeded) +// virtual +void wxApp::MacHandleUnhandledEvent( WXEVENTREF WXUNUSED(evr) ) { -#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 - - static bool s_inYield = false; - - if (s_inYield) - { - if ( !onlyIfNeeded ) - { - wxFAIL_MSG( wxT("wxYield called recursively" ) ); - } - - return false; - } - - s_inYield = true; + // Override to process unhandled events as you please +} -#if wxUSE_LOG - // disable log flushing from here because a call to wxYield() shouldn't - // normally result in message boxes popping up &c - wxLog::Suspend(); -#endif // wxUSE_LOG +#if wxOSX_USE_COCOA_OR_CARBON - wxEventLoop * const - loop = wx_static_cast(wxEventLoop *, wxEventLoop::GetActive()); - if ( loop ) +CGKeyCode wxCharCodeWXToOSX(wxKeyCode code) +{ + CGKeyCode keycode; + + switch (code) { - // process all pending events: - while ( loop->Pending() ) - loop->Dispatch(); + // Clang warns about switch values not of the same type as (enumerated) + // switch controlling expression. This is generally useful but here we + // really want to be able to use letters and digits without making them + // part of wxKeyCode enum. +#ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wswitch" +#endif // __clang__ + + case 'a': case 'A': keycode = kVK_ANSI_A; break; + case 'b': case 'B': keycode = kVK_ANSI_B; break; + case 'c': case 'C': keycode = kVK_ANSI_C; break; + case 'd': case 'D': keycode = kVK_ANSI_D; break; + case 'e': case 'E': keycode = kVK_ANSI_E; break; + case 'f': case 'F': keycode = kVK_ANSI_F; break; + case 'g': case 'G': keycode = kVK_ANSI_G; break; + case 'h': case 'H': keycode = kVK_ANSI_H; break; + case 'i': case 'I': keycode = kVK_ANSI_I; break; + case 'j': case 'J': keycode = kVK_ANSI_J; break; + case 'k': case 'K': keycode = kVK_ANSI_K; break; + case 'l': case 'L': keycode = kVK_ANSI_L; break; + case 'm': case 'M': keycode = kVK_ANSI_M; break; + case 'n': case 'N': keycode = kVK_ANSI_N; break; + case 'o': case 'O': keycode = kVK_ANSI_O; break; + case 'p': case 'P': keycode = kVK_ANSI_P; break; + case 'q': case 'Q': keycode = kVK_ANSI_Q; break; + case 'r': case 'R': keycode = kVK_ANSI_R; break; + case 's': case 'S': keycode = kVK_ANSI_S; break; + case 't': case 'T': keycode = kVK_ANSI_T; break; + case 'u': case 'U': keycode = kVK_ANSI_U; break; + case 'v': case 'V': keycode = kVK_ANSI_V; break; + case 'w': case 'W': keycode = kVK_ANSI_W; break; + case 'x': case 'X': keycode = kVK_ANSI_X; break; + case 'y': case 'Y': keycode = kVK_ANSI_Y; break; + case 'z': case 'Z': keycode = kVK_ANSI_Z; break; + + case '0': keycode = kVK_ANSI_0; break; + case '1': keycode = kVK_ANSI_1; break; + case '2': keycode = kVK_ANSI_2; break; + case '3': keycode = kVK_ANSI_3; break; + case '4': keycode = kVK_ANSI_4; break; + case '5': keycode = kVK_ANSI_5; break; + case '6': keycode = kVK_ANSI_6; break; + case '7': keycode = kVK_ANSI_7; break; + case '8': keycode = kVK_ANSI_8; break; + case '9': keycode = kVK_ANSI_9; break; + +#ifdef __clang__ + #pragma clang diagnostic pop +#endif // __clang__ + + case WXK_BACK: keycode = kVK_Delete; break; + case WXK_TAB: keycode = kVK_Tab; break; + case WXK_RETURN: keycode = kVK_Return; break; + case WXK_ESCAPE: keycode = kVK_Escape; break; + case WXK_SPACE: keycode = kVK_Space; break; + case WXK_DELETE: keycode = kVK_ForwardDelete; break; + + case WXK_SHIFT: keycode = kVK_Shift; break; + case WXK_ALT: keycode = kVK_Option; break; + case WXK_RAW_CONTROL: keycode = kVK_Control; break; + case WXK_CONTROL: keycode = kVK_Command; break; + + case WXK_CAPITAL: keycode = kVK_CapsLock; break; + case WXK_END: keycode = kVK_End; break; + case WXK_HOME: keycode = kVK_Home; break; + case WXK_LEFT: keycode = kVK_LeftArrow; break; + case WXK_UP: keycode = kVK_UpArrow; break; + case WXK_RIGHT: keycode = kVK_RightArrow; break; + case WXK_DOWN: keycode = kVK_DownArrow; break; + + case WXK_HELP: keycode = kVK_Help; break; + + + case WXK_NUMPAD0: keycode = kVK_ANSI_Keypad0; break; + case WXK_NUMPAD1: keycode = kVK_ANSI_Keypad1; break; + case WXK_NUMPAD2: keycode = kVK_ANSI_Keypad2; break; + case WXK_NUMPAD3: keycode = kVK_ANSI_Keypad3; break; + case WXK_NUMPAD4: keycode = kVK_ANSI_Keypad4; break; + case WXK_NUMPAD5: keycode = kVK_ANSI_Keypad5; break; + case WXK_NUMPAD6: keycode = kVK_ANSI_Keypad6; break; + case WXK_NUMPAD7: keycode = kVK_ANSI_Keypad7; break; + case WXK_NUMPAD8: keycode = kVK_ANSI_Keypad8; break; + case WXK_NUMPAD9: keycode = kVK_ANSI_Keypad9; break; + case WXK_F1: keycode = kVK_F1; break; + case WXK_F2: keycode = kVK_F2; break; + case WXK_F3: keycode = kVK_F3; break; + case WXK_F4: keycode = kVK_F4; break; + case WXK_F5: keycode = kVK_F5; break; + case WXK_F6: keycode = kVK_F6; break; + case WXK_F7: keycode = kVK_F7; break; + case WXK_F8: keycode = kVK_F8; break; + case WXK_F9: keycode = kVK_F9; break; + case WXK_F10: keycode = kVK_F10; break; + case WXK_F11: keycode = kVK_F11; break; + case WXK_F12: keycode = kVK_F12; break; + case WXK_F13: keycode = kVK_F13; break; + case WXK_F14: keycode = kVK_F14; break; + case WXK_F15: keycode = kVK_F15; break; + case WXK_F16: keycode = kVK_F16; break; + case WXK_F17: keycode = kVK_F17; break; + case WXK_F18: keycode = kVK_F18; break; + case WXK_F19: keycode = kVK_F19; break; + case WXK_F20: keycode = kVK_F20; break; + + case WXK_PAGEUP: keycode = kVK_PageUp; break; + case WXK_PAGEDOWN: keycode = kVK_PageDown; break; + + case WXK_NUMPAD_DELETE: keycode = kVK_ANSI_KeypadClear; break; + case WXK_NUMPAD_EQUAL: keycode = kVK_ANSI_KeypadEquals; break; + case WXK_NUMPAD_MULTIPLY: keycode = kVK_ANSI_KeypadMultiply; break; + case WXK_NUMPAD_ADD: keycode = kVK_ANSI_KeypadPlus; break; + case WXK_NUMPAD_SUBTRACT: keycode = kVK_ANSI_KeypadMinus; break; + case WXK_NUMPAD_DECIMAL: keycode = kVK_ANSI_KeypadDecimal; break; + case WXK_NUMPAD_DIVIDE: keycode = kVK_ANSI_KeypadDivide; break; + + default: + wxLogDebug( "Unrecognised keycode %d", code ); + keycode = static_cast(-1); } - // it's necessary to call ProcessIdle() to update the frames sizes which - // might have been changed (it also will update other things set from - // OnUpdateUI() which is a nice (and desired) side effect) - while ( ProcessIdle() ) {} - -#if wxUSE_LOG - wxLog::Resume(); -#endif // wxUSE_LOG - s_inYield = false; - - return true; + return keycode; } -// virtual -void wxApp::MacHandleUnhandledEvent( WXEVENTREF WXUNUSED(evr) ) -{ - // Override to process unhandled events as you please -} - -#if wxOSX_USE_CARBON - long wxMacTranslateKey(unsigned char key, unsigned char code) { long retval = key ; @@ -1327,6 +1353,7 @@ int wxMacKeyCodeToModifier(wxKeyCode key) { case WXK_START: case WXK_MENU: + case WXK_COMMAND: return cmdKey; case WXK_SHIFT: @@ -1338,7 +1365,7 @@ int wxMacKeyCodeToModifier(wxKeyCode key) case WXK_ALT: return optionKey; - case WXK_CONTROL: + case WXK_RAW_CONTROL: return controlKey; default: @@ -1347,6 +1374,12 @@ int wxMacKeyCodeToModifier(wxKeyCode key) } #endif +#if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 + +// defined in utils.mm + +#elif wxOSX_USE_COCOA_OR_CARBON + wxMouseState wxGetMouseState() { wxMouseState ms; @@ -1355,111 +1388,67 @@ wxMouseState wxGetMouseState() ms.SetX(pt.x); ms.SetY(pt.y); -#if wxOSX_USE_CARBON UInt32 buttons = GetCurrentButtonState(); ms.SetLeftDown( (buttons & 0x01) != 0 ); ms.SetMiddleDown( (buttons & 0x04) != 0 ); ms.SetRightDown( (buttons & 0x02) != 0 ); UInt32 modifiers = GetCurrentKeyModifiers(); - ms.SetControlDown(modifiers & controlKey); + ms.SetRawControlDown(modifiers & controlKey); ms.SetShiftDown(modifiers & shiftKey); ms.SetAltDown(modifiers & optionKey); - ms.SetMetaDown(modifiers & cmdKey); -#else - // TODO -#endif + ms.SetControlDown(modifiers & cmdKey); + return ms; } +#endif + // 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 ) +bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) { if ( !focus ) return false ; - bool handled; wxKeyEvent event(wxEVT_KEY_DOWN) ; - MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - - handled = focus->HandleWindowEvent( event ) ; - if ( handled && event.GetSkipped() ) - handled = false ; - -#if wxUSE_ACCEL - if ( !handled ) - { - wxWindow *ancestor = focus; - while (ancestor) - { - int command = ancestor->GetAcceleratorTable()->GetCommand( event ); - if (command != -1) - { - wxEvtHandler * const handler = ancestor->GetEventHandler(); - - wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); - 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; - } + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ; - if (ancestor->IsTopLevel()) - break; - - ancestor = ancestor->GetParent(); - } - } -#endif // wxUSE_ACCEL - - return handled ; + return focus->OSXHandleKeyEvent(event); } -bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) { if ( !focus ) return false ; - bool handled; wxKeyEvent event( wxEVT_KEY_UP ) ; - MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - handled = focus->HandleWindowEvent( event ) ; + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ; - return handled ; + return focus->OSXHandleKeyEvent(event) ; } -bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar ) +bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) { if ( !focus ) return false ; wxKeyEvent event(wxEVT_CHAR) ; - MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ; - long keyval = event.m_keyCode ; + MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ; bool handled = false ; #if wxOSX_USE_CARBON - wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ; + long keyval = event.m_keyCode ; - if (tlw) { - event.SetEventType( wxEVT_CHAR_HOOK ); - handled = tlw->HandleWindowEvent( event ); - if ( handled && event.GetSkipped() ) + wxKeyEvent eventCharHook(wxEVT_CHAR_HOOK, event); + handled = focus->HandleWindowEvent( eventCharHook ); + if ( handled && eventCharHook.IsNextEventAllowed() ) handled = false ; } if ( !handled ) { - event.SetEventType( wxEVT_CHAR ); - event.Skip( false ) ; handled = focus->HandleWindowEvent( event ) ; } @@ -1502,7 +1491,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers wxButton *def = wxDynamicCast(tlw->GetDefaultItem(), wxButton); if ( def && def->IsEnabled() ) { - wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() ); + wxCommandEvent event(wxEVT_BUTTON, def->GetId() ); event.SetEventObject(def); def->Command(event); @@ -1513,7 +1502,7 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) ) { // generate wxID_CANCEL if command-. or has been pressed (typically in dialogs) - wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); + wxCommandEvent new_event(wxEVT_BUTTON,wxID_CANCEL); new_event.SetEventObject( focus ); handled = focus->HandleWindowEvent( new_event ); } @@ -1525,9 +1514,10 @@ bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers } // 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 ) +void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymessage , long modifiers , long when , wxChar uniChar ) { -#if wxOSX_USE_CARBON +#if wxOSX_USE_COCOA_OR_CARBON + short keycode, keychar ; keychar = short(keymessage & charCodeMask); @@ -1537,7 +1527,7 @@ 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 + // TODO new implementation using TextInputSources #else UInt32 state = 0; UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey | shiftKey | optionKey))) | keycode, &state); @@ -1558,34 +1548,34 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess { keyval = (keyval - '0') + WXK_NUMPAD0; } - else if (keycode >= 65 && keycode <= 81) + 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; @@ -1594,11 +1584,11 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess } } } - + event.m_shiftDown = modifiers & shiftKey; - event.m_controlDown = modifiers & controlKey; + event.m_rawControlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; - event.m_metaDown = modifiers & cmdKey; + event.m_controlDown = modifiers & cmdKey; event.m_keyCode = keyval ; #if wxUSE_UNICODE event.m_uniChar = uniChar ; @@ -1606,10 +1596,15 @@ void wxApp::MacCreateKeyEvent( wxKeyEvent& event, wxWindow* focus , long keymess event.m_rawCode = keymessage; event.m_rawFlags = modifiers; - event.m_x = wherex; - event.m_y = wherey; event.SetTimestamp(when); event.SetEventObject(focus); +#else + wxUnusedVar(event); + wxUnusedVar(focus); + wxUnusedVar(keymessage); + wxUnusedVar(modifiers); + wxUnusedVar(when); + wxUnusedVar(uniChar); #endif } @@ -1621,7 +1616,7 @@ void wxApp::MacHideApp() HICommand command; memset( &command, 0 , sizeof(command) ); command.commandID = kHICommandHide ; - event.SetParameter(kEventParamDirectObject, command ); + event.SetParameter(kEventParamDirectObject, command ); SendEventToApplication( event ); #endif }