/////////////////////////////////////////////////////////////////////////////
-// Name: src/mac/carbon/app.cpp
+// Name: src/osx/carbon/app.cpp
// Purpose: wxApp
// Author: Stefan Csomor
// Modified by:
#include "wx/filename.h"
#include "wx/link.h"
#include "wx/thread.h"
+#include "wx/evtloop.h"
#include <string.h>
// mac
+#if wxOSX_USE_CARBON
+#include "wx/osx/uma.h"
+#else
+#include "wx/osx/private.h"
+#endif
-#include "wx/mac/uma.h"
-
-#ifdef __DARWIN__
-# include <CoreServices/CoreServices.h>
-# if defined(WXMAKINGDLL_CORE)
-# include <mach-o/dyld.h>
-# endif
+#if defined(WXMAKINGDLL_CORE)
+# include <mach-o/dyld.h>
#endif
// Keep linker from discarding wxStockGDIMac
wxFORCE_LINK_MODULE(gdiobj)
-// statics for implementation
-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)
bool wxApp::sm_isEmbedded = false; // Normally we're not a plugin
+#if wxOSX_USE_CARBON
+
//----------------------------------------------------------------------
// Core Apple Event Support
//----------------------------------------------------------------------
+AEEventHandlerUPP sODocHandler = NULL ;
+AEEventHandlerUPP sGURLHandler = NULL ;
+AEEventHandlerUPP sOAppHandler = NULL ;
+AEEventHandlerUPP sPDocHandler = NULL ;
+AEEventHandlerUPP sRAppHandler = NULL ;
+AEEventHandlerUPP sQuitHandler = NULL ;
+
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 AEHandleGURL( const AppleEvent *event , AppleEvent *reply , SRefCon refcon ) ;
pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , SRefCon WXUNUSED(refcon) )
{
}
-// 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))
{
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;
}
if (err != noErr)
return err;
- url[actualSize] = '\0'; // Terminate the C string
+ url[actualSize] = '\0'; // Terminate the C string
ProcessSerialNumber PSN ;
PSN.highLongOfPSN = 0 ;
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);
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 ;
}
return noErr ;
}
+#endif
+
//----------------------------------------------------------------------
// 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
// if some windows are not hidden -> do nothing
wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
- if ( node == NULL )
+ if ( !node )
{
MacNewFile() ;
}
// 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 ;
}
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
}
}
// if no native match they just return the passed-in id
+#if wxOSX_USE_CARBON
+
struct IdPair
{
UInt32 macId ;
// 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() ;
}
else
{
- URefCon refCon ;
+ URefCon refCon = 0 ;
GetMenuItemRefCon( command.menu.menuRef , command.menu.menuItemIndex , &refCon ) ;
itemMenu = wxFindMenuFromMacMenu( command.menu.menuRef ) ;
- if ( itemMenu != NULL )
- item = (wxMenuItem*) refCon ;
+ if ( itemMenu != NULL && refCon != 0)
+ item = (wxMenuItem*) refCon;
}
}
#endif
return itemMenu ;
}
+#endif
+
//----------------------------------------------------------------------
// Carbon Event Handler
//----------------------------------------------------------------------
+#if wxOSX_USE_CARBON
+
static const EventTypeSpec eventList[] =
{
{ kEventClassCommand, kEventProcessCommand } ,
if ( menu )
{
- wxEventType type=0;
- MenuCommand cmd=0;
switch (GetEventKind(event))
{
case kEventMenuOpening:
- type = wxEVT_MENU_OPEN;
+ menu->HandleMenuOpened();
break;
case kEventMenuClosed:
- type = wxEVT_MENU_CLOSE;
+ menu->HandleMenuClosed();
break;
case kEventMenuTargetItem:
- cmd = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
- if (cmd != 0)
- type = wxEVT_MENU_HIGHLIGHT;
+ {
+ HICommand command ;
+
+ command.menu.menuRef = menuRef;
+ command.menu.menuItemIndex = cEvent.GetParameter<MenuItemIndex>(kEventParamMenuItemIndex,typeMenuItemIndex) ;
+ command.commandID = cEvent.GetParameter<MenuCommand>(kEventParamMenuCommand,typeMenuCommand) ;
+ if (command.commandID != 0)
+ {
+ wxMenuItem* item = NULL ;
+ wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
+ if ( itemMenu && item )
+ itemMenu->HandleMenuItemHighlighted( item );
+ }
+ }
break;
default:
break;
}
- if ( type )
- {
- wxMenuEvent wxevent(type, cmd, menu);
- wxevent.SetEventObject(menu);
-
- wxEvtHandler* handler = menu->GetEventHandler();
- if (handler && handler->ProcessEvent(wxevent))
- {
- // handled
- }
- else
- {
- wxWindow *win = menu->GetInvokingWindow();
- if (win)
- win->HandleWindowEvent(wxevent);
- }
- }
}
#endif
return eventNotHandledErr;
}
-#ifndef __LP64__
static pascal OSStatus
wxMacAppCommandEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
EventRef event ,
wxMenuItem* item = NULL ;
wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
- int id = wxMacCommandToId( command.commandID ) ;
if ( item )
{
switch ( cEvent.GetKind() )
{
case kEventProcessCommand :
- result = itemMenu->MacHandleCommandProcess( item, id );
+ if ( itemMenu->HandleCommandProcess( item ) )
+ result = noErr;
break ;
case kEventCommandUpdateStatus:
- result = itemMenu->MacHandleCommandUpdateStatus( item, id );
+ if ( itemMenu->HandleCommandUpdateStatus( item ) )
+ result = noErr;
break ;
default :
}
return result ;
}
-#endif
static pascal OSStatus
wxMacAppApplicationEventHandler( EventHandlerCallRef WXUNUSED(handler) ,
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 :
}
DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler )
+#endif
-#ifdef __WXDEBUG__
+#if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
pascal static void
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
-#ifdef __WXDEBUG__
+#if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler ) );
#endif
- UMAInitToolbox( 4, sm_isEmbedded ) ;
-// TODO CHECK Can Be Removed SetEventMask( everyEvent ) ;
-
// Mac OS X passes a process serial number command line argument when
// the application is launched from the Finder. This argument must be
// removed from the command line arguments before being handled by the
// 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;
+ }
}
}
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;
}
-AEEventHandlerUPP sODocHandler = NULL ;
-AEEventHandlerUPP sGURLHandler = NULL ;
-AEEventHandlerUPP sOAppHandler = NULL ;
-AEEventHandlerUPP sPDocHandler = NULL ;
-AEEventHandlerUPP sRAppHandler = NULL ;
-AEEventHandlerUPP sQuitHandler = NULL ;
+#if wxOSX_USE_COCOA_OR_CARBON
+bool wxApp::CallOnInit()
+{
+ wxMacAutoreleasePool autoreleasepool;
+ return OnInit();
+}
+#endif
bool wxApp::OnInitGui()
{
if ( !wxAppBase::OnInitGui() )
return false ;
-#ifndef __LP64__
+
+ if ( !DoInitGui() )
+ return false;
+
+ return true ;
+}
+
+bool wxApp::ProcessIdle()
+{
+ wxMacAutoreleasePool autoreleasepool;
+ return wxAppBase::ProcessIdle();
+}
+
+int wxApp::OnRun()
+{
+ wxMacAutoreleasePool pool;
+ return wxAppBase::OnRun();
+}
+
+#if wxOSX_USE_CARBON
+bool wxApp::DoInitGui()
+{
InstallStandardEventHandler( GetApplicationEventTarget() ) ;
if (!sm_isEmbedded)
{
GetwxMacAppEventHandlerUPP(),
GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
}
-#endif
if (!sm_isEmbedded)
{
if ( !wxMacInitCocoa() )
return false;
- return true ;
+ return true;
}
-void wxApp::CleanUp()
+void wxApp::DoCleanUp()
{
-#if wxUSE_TOOLTIPS
- wxToolTip::RemoveToolTips() ;
-#endif
-
- if (m_macEventPosted)
- {
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_macEventPosted, kCFRunLoopCommonModes);
- m_macEventPosted = NULL;
- }
-
- // One last chance for pending objects to be cleaned up
- wxTheApp->DeletePendingObjects();
-
if (!sm_isEmbedded)
RemoveEventHandler( (EventHandlerRef)(wxTheApp->m_macEventHandler) );
DisposeAEEventHandlerUPP( sRAppHandler ) ;
DisposeAEEventHandlerUPP( sQuitHandler ) ;
}
+}
+
+#endif
+
+void wxApp::CleanUp()
+{
+ wxMacAutoreleasePool autoreleasepool;
+#if wxUSE_TOOLTIPS
+ wxToolTip::RemoveToolTips() ;
+#endif
+
+ DoCleanUp();
wxAppBase::CleanUp();
}
// misc initialization stuff
//----------------------------------------------------------------------
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
-bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
+wxApp::wxApp()
{
- 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 ;
+ m_printMode = wxPRINT_WINDOWS;
- 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 ;
+ m_macCurrentEvent = NULL ;
+ m_macCurrentEventHandlerCallRef = NULL ;
+ m_macPool = new wxMacAutoreleasePool();
+}
- default :
- break ;
- }
- }
+wxApp::~wxApp()
+{
+ if (m_macPool)
+ delete m_macPool;
+}
- return converted ;
+CFMutableArrayRef GetAutoReleaseArray()
+{
+ static CFMutableArrayRef array = 0;
+ if ( array == 0)
+ array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
+ return array;
}
-#endif
-wxApp::wxApp()
+void wxApp::MacAddToAutorelease( void* cfrefobj )
{
- m_printMode = wxPRINT_WINDOWS;
+ CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
+}
- m_macCurrentEvent = NULL ;
- m_macCurrentEventHandlerCallRef = NULL ;
- m_macEventPosted = NULL ;
+void wxApp::MacReleaseAutoreleasePool()
+{
+ if (m_macPool)
+ delete m_macPool;
+ m_macPool = new wxMacAutoreleasePool();
}
void wxApp::OnIdle(wxIdleEvent& WXUNUSED(event))
// either events to the threads other than main or events posted with
// wxPostEvent() functions
#ifndef __WXUNIVERSAL__
+#if wxUSE_MENUS
if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
#endif
+#endif
+ CFArrayRemoveAllValues( GetAutoReleaseArray() );
}
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))
// user can veto the close, and therefore the end session.
void wxApp::OnQueryEndSession(wxCloseEvent& event)
{
- if (GetTopWindow())
+ if ( !wxDialog::OSXHasModalDialogsOpen() )
{
- if (!GetTopWindow()->Close(!event.CanVeto()))
- event.Veto(true);
- }
-}
-
-extern "C" void wxCYield() ;
-void wxCYield()
-{
- wxYield() ;
-}
-
-// Yield to other processes
-
-bool wxApp::Yield(bool onlyIfNeeded)
-{
- if (s_inYield)
- {
- if ( !onlyIfNeeded )
+ if (GetTopWindow())
{
- wxFAIL_MSG( wxT("wxYield called recursively" ) );
+ if (!GetTopWindow()->Close(!event.CanVeto()))
+ event.Veto(true);
}
-
- return false;
}
-
-#if wxUSE_THREADS
- // Yielding from a non-gui thread needs to bail out, otherwise we end up
- // possibly sending events in the thread too.
- if ( !wxThread::IsMain() )
+ else
{
- return true;
+ event.Veto(true);
}
-#endif // wxUSE_THREADS
-
- s_inYield = true;
-
- // by definition yield should handle all non-processed events
-
- EventRef theEvent;
-
- OSStatus status = noErr ;
-
- while ( status == noErr )
- {
- s_inReceiveEvent = true ;
- status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
- s_inReceiveEvent = false ;
-
- if ( status == eventLoopTimedOutErr )
- {
- // make sure next time the event loop will trigger idle events
- sleepTime = kEventDurationNoWait ;
- }
- else if ( status == eventLoopQuitErr )
- {
- // according to QA1061 this may also occur when a WakeUp Process
- // is executed
- }
- else
- {
- MacHandleOneEvent( theEvent ) ;
- ReleaseEvent(theEvent);
- }
- }
-
- s_inYield = false;
-
- return true;
}
-void wxApp::MacDoOneEvent()
+extern "C" void wxCYield() ;
+void wxCYield()
{
- wxMacAutoreleasePool autoreleasepool;
- EventRef theEvent;
-
- s_inReceiveEvent = true ;
- OSStatus status = ReceiveNextEvent(0, NULL, sleepTime, true, &theEvent) ;
- s_inReceiveEvent = false ;
-
- switch (status)
- {
- 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 ;
- break;
- }
- // repeaters
-
- DeletePendingObjects() ;
+ wxYield() ;
}
// virtual
// Override to process unhandled events as you please
}
-CFMutableArrayRef GetAutoReleaseArray()
-{
- static CFMutableArrayRef array = 0;
- if ( array == 0)
- array= CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
- return array;
-}
-
-void wxApp::MacHandleOneEvent( WXEVENTREF evr )
-{
- EventTargetRef theTarget;
- theTarget = GetEventDispatcherTarget();
- m_macCurrentEvent = evr ;
-
- OSStatus status = SendEventToEventTarget((EventRef) evr , theTarget);
- if (status == eventNotHandledErr)
- MacHandleUnhandledEvent(evr);
+#if wxOSX_USE_COCOA_OR_CARBON
-#if wxUSE_THREADS
- wxMutexGuiLeaveOrEnter();
-#endif // wxUSE_THREADS
-
- CFArrayRemoveAllValues( GetAutoReleaseArray() );
-}
-
-void wxApp::MacAddToAutorelease( void* cfrefobj )
+CGKeyCode wxCharCodeWXToOSX(wxKeyCode code)
{
- CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj );
+ CGKeyCode keycode;
+
+ switch (code)
+ {
+ // 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<CGKeyCode>(-1);
+ }
+
+ return keycode;
}
long wxMacTranslateKey(unsigned char key, unsigned char code)
{
case WXK_START:
case WXK_MENU:
+ case WXK_COMMAND:
return cmdKey;
case WXK_SHIFT:
case WXK_ALT:
return optionKey;
- case WXK_CONTROL:
+ case WXK_RAW_CONTROL:
return controlKey;
default:
return 0;
}
}
+#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()
{
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);
+ 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 ;
+ MacCreateKeyEvent( event, focus , keymessage , modifiers , when , uniChar ) ;
-#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;
- }
-
- 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 ;
- wxNonOwnedWindow *tlw = focus->MacGetTopLevelWindow() ;
+#if wxOSX_USE_CARBON
+ 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 ) ;
}
}
// backdoor handler for default return and command escape
- if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
+ if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->AcceptsFocus() ) )
{
// if window is not having a focus still testing for default enter or cancel
// TODO: add the UMA version for ActiveNonFloatingWindow
#ifndef __LP64__
- wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
+ wxWindow* focus = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) FrontWindow() ) ;
if ( focus )
{
if ( keyval == WXK_RETURN || keyval == WXK_NUMPAD_ENTER )
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);
else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
{
// generate wxID_CANCEL if command-. or <esc> 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 );
}
}
#endif
}
+#endif
return handled ;
}
// 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_COCOA_OR_CARBON
+
short keycode, keychar ;
keychar = short(keymessage & charCodeMask);
// 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);
{
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;
}
}
}
-
+
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 ;
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
}
void wxApp::MacHideApp()
{
+#if wxOSX_USE_CARBON
wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess );
HICommand command;
memset( &command, 0 , sizeof(command) );
command.commandID = kHICommandHide ;
- event.SetParameter<HICommand>(kEventParamDirectObject, command );
+ event.SetParameter<HICommand>(kEventParamDirectObject, command );
SendEventToApplication( event );
+#endif
}