X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0f4930939e18a6c07ef303533329dd5334a65780..44ba8f0ea92f65d9893ce0780971745a5d8e80ea:/src/mac/carbon/app.cpp diff --git a/src/mac/carbon/app.cpp b/src/mac/carbon/app.cpp index 248cfa19d6..6da3392881 100644 --- a/src/mac/carbon/app.cpp +++ b/src/mac/carbon/app.cpp @@ -95,6 +95,8 @@ 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_macDefaultEncodingIsPC = true ; bool wxApp::s_macSupportPCMenuShortcuts = true ; @@ -397,7 +399,7 @@ bool wxApp::Initialize() // __wxinitialize in Mach-O shared libraries wxStAppResource::OpenSharedLibraryResource(NULL); #endif - + #if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340) AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments , NewAEEventHandlerUPP(AEHandleODoc) , @@ -494,7 +496,7 @@ bool wxApp::Initialize() s_macCursorRgn = ::NewRgn() ; wxBuffer = new char[BUFSIZ + 512]; - + wxClassInfo::InitializeClasses(); #if wxUSE_RESOURCES @@ -504,7 +506,7 @@ bool wxApp::Initialize() #if wxUSE_THREADS wxPendingEventsLocker = new wxCriticalSection; #endif - + wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); wxTheColourDatabase->Initialize(); @@ -590,7 +592,7 @@ void wxApp::CleanUp() delete wxWinMacControlList ; } delete wxPendingEvents; - + #if wxUSE_THREADS delete wxPendingEventsLocker; // If we don't do the following, we get an apparent memory leak. @@ -633,12 +635,12 @@ void wxApp::CleanUp() // __wxterminate in Mach-O shared libraries wxStAppResource::CloseSharedLibraryResource(); #endif - + UMACleanupToolbox() ; if (s_macCursorRgn) { ::DisposeRgn((RgnHandle)s_macCursorRgn); } - + #if 0 TerminateAE() ; #endif @@ -681,14 +683,14 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) 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); } @@ -699,12 +701,12 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) NSSymbol theSymbol; NSModule theModule; const char *theLibPath; - + gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows")); if (gSharedLibraryBundle != NULL) { // wxWindows has been bundled into a framework // load the framework resources - + gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle); } else { @@ -715,7 +717,7 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) char *theExt; FSRef theResRef; OSErr theErr = noErr; - + // get the library path theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource"); theModule = NSModuleForSymbol(theSymbol); @@ -733,7 +735,7 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) theExt = strstr(theName, ".dylib"); // overwrite extension with ".rsrc" strcpy(theExt, ".rsrc"); - + wxLogDebug( theResPath ); theErr = FSPathMakeRef((UInt8 *) theResPath, &theResRef, false); @@ -741,7 +743,7 @@ void wxStAppResource::OpenSharedLibraryResource(const void *initBlock) // try in current directory (using name only) theErr = FSPathMakeRef((UInt8 *) theName, &theResRef, false); } - + // free duplicated resource file path free(theResPath); @@ -774,7 +776,7 @@ void wxStAppResource::CloseSharedLibraryResource() CloseResFile(gSharedLibraryResource); } gSharedLibraryResource = kResFileNotOpened; - } + } #endif /* WXMAKINGDLL */ } @@ -858,12 +860,12 @@ int wxEntry( int argc, char *argv[] , bool enterLoop ) if (argc > 1) { char theArg[6] = ""; strncpy(theArg, argv[1], 5); - + if (strcmp(theArg, "-psn_") == 0) { // assume the argument is always the only one and remove it --argc; } - } + } #else argc = 0 ; // currently we don't support files as parameters #endif @@ -930,7 +932,7 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) case kEventClassKeyboard : { converted = true ; - switch( GetEventKind(event) ) + switch( GetEventKind(event) ) { case kEventRawKeyDown : rec->what = keyDown ; @@ -993,20 +995,21 @@ bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec) 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->MacHandleModifierEvents( &rec ) ; wxTheApp->MacHandleOneEvent( &rec ) ; result = noErr ; } @@ -1014,6 +1017,7 @@ pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , Even case kEventClassTextInput : if ( wxMacConvertEventToRecord( event , &rec ) ) { + wxTheApp->MacHandleModifierEvents( &rec ) ; wxTheApp->MacHandleOneEvent( &rec ) ; result = noErr ; } @@ -1030,20 +1034,20 @@ bool wxApp::OnInit() { if ( ! wxAppBase::OnInit() ) return FALSE ; - + #if 0 // TARGET_CARBON - static const EventTypeSpec eventList[] = + static const EventTypeSpec eventList[] = { { kEventClassKeyboard, kEventRawKeyDown } , { kEventClassKeyboard, kEventRawKeyRepeat } , { kEventClassKeyboard, kEventRawKeyUp } , { kEventClassKeyboard, kEventRawKeyModifiersChanged } , - + { kEventClassTextInput , kEventTextInputUnicodeForKeyEvent } , } ; - + InstallApplicationEventHandler(NewEventHandlerUPP(wxMacApplicationEventHandler) - , WXSIZEOF(eventList), eventList, this, NULL); + , WXSIZEOF(eventList), eventList, this, NULL); #endif return TRUE ; } @@ -1063,7 +1067,6 @@ wxApp::wxApp() argv = NULL; m_printMode = wxPRINT_WINDOWS; - m_exitOnFrameDelete = TRUE; m_auto3D = TRUE; } @@ -1270,10 +1273,12 @@ bool wxApp::Yield(bool onlyIfNeeded) while ( !wxTheApp->IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn)) { + wxTheApp->MacHandleModifierEvents( &event ) ; wxTheApp->MacHandleOneEvent( &event ); if ( event.what != kHighLevelEvent ) SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ; } + wxTheApp->MacHandleModifierEvents( &event ) ; wxMacProcessNotifierAndPendingEvents() ; @@ -1296,13 +1301,13 @@ void wxApp::MacSuspend( bool convertClipboard ) node = node->Next(); } - + s_lastMouseDown = 0 ; if( convertClipboard ) { MacConvertPrivateToPublicScrap() ; } - + ::HideFloatingWindows() ; } @@ -1315,9 +1320,9 @@ void wxApp::MacResume( bool convertClipboard ) { MacConvertPublicToPrivateScrap() ; } - + ::ShowFloatingWindows() ; - + // raise modal dialogs in case a non modal window was selected to activate the app wxNode* node = wxModalDialogs.First(); @@ -1325,7 +1330,7 @@ void wxApp::MacResume( bool convertClipboard ) { wxDialog* dialog = (wxDialog *) node->Data(); dialog->Raise(); - + node = node->Next(); } } @@ -1346,10 +1351,12 @@ void wxApp::MacDoOneEvent() if (WaitNextEvent(everyEvent, &event, sleepTime, (RgnHandle) s_macCursorRgn)) { + MacHandleModifierEvents( &event ) ; MacHandleOneEvent( &event ); } else { + MacHandleModifierEvents( &event ) ; // idlers WindowPtr window = ::FrontWindow() ; if ( window ) @@ -1366,6 +1373,61 @@ void wxApp::MacDoOneEvent() wxMacProcessNotifierAndPendingEvents() ; } +void wxApp::MacHandleModifierEvents( WXEVENTREF evr ) +{ + EventRecord* ev = (EventRecord*) evr ; +#if TARGET_CARBON + if ( ev->what == mouseDown || ev->what == mouseUp || ev->what == activateEvt || + ev->what == keyDown || ev->what == autoKey || ev->what == keyUp || ev->what == nullEvent ) + { + // in these cases the modifiers are already correctly setup by carbon + } + else + { + EventRecord nev ; + WaitNextEvent( 0 , &nev , 0 , NULL ) ; + ev->modifiers = nev.modifiers ; + // KeyModifiers unfortunately don't include btnState... +// ev->modifiers = GetCurrentKeyModifiers() ; + } +#endif + if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL ) + { + 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_x = ev->where.h; + event.m_y = ev->where.v; + event.m_timeStamp = ev->when; + wxWindow* focus = wxWindow::FindFocus() ; + event.SetEventObject(focus); + + if ( (ev->modifiers ^ s_lastModifiers ) & controlKey ) + { + event.m_keyCode = WXK_CONTROL ; + event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey ) + { + event.m_keyCode = WXK_SHIFT ; + event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + if ( (ev->modifiers ^ s_lastModifiers ) & optionKey ) + { + event.m_keyCode = WXK_ALT ; + event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; + focus->GetEventHandler()->ProcessEvent( event ) ; + } + s_lastModifiers = ev->modifiers ; + } +} + void wxApp::MacHandleOneEvent( WXEVENTREF evr ) { EventRecord* ev = (EventRecord*) evr ; @@ -1597,7 +1659,7 @@ void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr ) { window = (WindowRef) s_captureWindow->MacGetRootWindow() ; windowPart = inContent ; - } + } else { windowPart = ::FindWindow(ev->where, &window) ; @@ -1745,8 +1807,13 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) short keychar ; keychar = short(ev->message & charCodeMask); keycode = short(ev->message & keyCodeMask) >> 8 ; - long keyval = wxMacTranslateKey(keychar, keycode) ; wxWindow* focus = wxWindow::FindFocus() ; + // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value + if ( (ev->modifiers & controlKey) && keychar >= 0 && keychar < 0x20 ) + { + keychar += 0x40 ; + } + long keyval = wxMacTranslateKey(keychar, keycode) ; if ( MacSendKeyDownEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false ) { @@ -1762,18 +1829,13 @@ void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr ) 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); + 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; + event.m_keyCode = wxToupper(keyval ); event.m_x = wherex; event.m_y = wherey; @@ -1808,6 +1870,7 @@ bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keyval , long modifiers { event.Skip( FALSE ) ; event.SetEventType( wxEVT_CHAR ) ; + event.m_keyCode = keyval ; handled = focus->GetEventHandler()->ProcessEvent( event ) ; if ( handled && event.GetSkipped() ) @@ -1883,10 +1946,15 @@ void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) short keychar ; keychar = short(ev->message & charCodeMask); keycode = short(ev->message & keyCodeMask) >> 8 ; + // it is wxWindows Convention to have Ctrl Key Combinations at ASCII char value + if ( (ev->modifiers & controlKey) && keychar >= 0 && keychar < 0x20 ) + { + keychar += 0x40 ; + } long keyval = wxMacTranslateKey(keychar, keycode) ; wxWindow* focus = wxWindow::FindFocus() ; - bool handled = MacSendKeyUpEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; + MacSendKeyUpEvent( focus , keyval , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ; // we don't have to do anything under classic here } } @@ -1894,11 +1962,6 @@ void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr ) 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); @@ -1906,7 +1969,7 @@ bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keyval , long modifiers , event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; - event.m_keyCode = keyval; + event.m_keyCode = wxToupper(keyval ); event.m_x = wherex; event.m_y = wherey; @@ -2059,14 +2122,14 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) event.m_y = ev->where.v; event.m_timeStamp = ev->when; event.SetEventObject(this); - + if ( wxWindow::s_lastMouseWindow ) { wxMouseEvent eventleave(event); eventleave.SetEventType( wxEVT_LEAVE_WINDOW ); wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y ); eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ; - + wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave); } if ( currentMouseWindow ) @@ -2084,37 +2147,30 @@ void wxApp::MacHandleOSEvent( WXEVENTREF evr ) switch (windowPart) { - // fixes for setting the cursor back from dominic mazzoni - case inMenuBar : - UMAShowArrowCursor(); - break ; - case inSysWindow : - UMAShowArrowCursor(); - break ; - default: + case inContent : { - // if ( s_lastMouseDown == 0 ) - // ev->modifiers |= btnState ; - - // Calling GetNextEvent with a zero event mask will always - // pass back a null event. However, it fills the EventRecord - // with the state of the modifier keys. This is needed since - // the modifier state returned by WaitForNextEvent often is - // wrong mouse move events. The attempt above to correct this - // didn't always work (under OS X at least). - - EventRecord tmp; - ::GetNextEvent(0, &tmp); - ev->modifiers = tmp.modifiers; - wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ; if ( win ) win->MacMouseMoved( ev , windowPart ) ; else - UMAShowArrowCursor(); - + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } } break; + default : + { + if ( wxIsBusy() ) + { + } + else + UMAShowArrowCursor(); + } + break ; } } break ;