///////////////////////////////////////////////////////////////////////////////
-// Name: src/mac/carbon/evtloop.cpp
+// Name: src/osx/carbon/evtloop.cpp
// Purpose: implementation of wxEventLoop for wxMac
// Author: Vadim Zeitlin
// Modified by:
#ifndef WX_PRECOMP
#include "wx/app.h"
+ #include "wx/log.h"
#endif // WX_PRECOMP
-#if wxOSX_USE_CARBON
- #include <Carbon/Carbon.h>
-#else
- #include <CoreFoundation/CoreFoundation.h>
+#if wxUSE_GUI
+#include "wx/nonownedwnd.h"
#endif
+
+#include "wx/osx/private.h"
+
// ============================================================================
// wxEventLoop implementation
// ============================================================================
-// ----------------------------------------------------------------------------
-// high level functions for RunApplicationEventLoop() case
-// ----------------------------------------------------------------------------
+wxGUIEventLoop::wxGUIEventLoop()
+{
+}
+
+static void DispatchAndReleaseEvent(EventRef theEvent)
+{
+ if ( wxTheApp )
+ wxTheApp->MacSetCurrentEvent( theEvent, NULL );
+ OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget());
+ if (status == eventNotHandledErr && wxTheApp)
+ wxTheApp->MacHandleUnhandledEvent(theEvent);
+ ReleaseEvent( theEvent );
+}
-#if wxOSX_USE_RUN_APP_EVENT_LOOP
+int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
+{
+ wxMacAutoreleasePool autoreleasepool;
+
+ EventRef event;
+ OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event);
+ switch ( status )
+ {
+ default:
+ wxFAIL_MSG( "unexpected ReceiveNextEvent() error" );
+ // fall through
+
+ case eventLoopTimedOutErr:
+ return -1;
+
+ case eventLoopQuitErr:
+ // according to QA1061 this may also occur
+ // when a WakeUp Process is executed
+ return 0;
+
+ case noErr:
+ DispatchAndReleaseEvent(event);
+ return 1;
+ }
+}
-int wxGUIEventLoop::Run()
+void wxGUIEventLoop::WakeUp()
{
- wxEventLoopActivator activate(this);
+ OSStatus err = noErr;
+ wxMacCarbonEvent wakeupEvent;
+ wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(),
+ kEventAttributeNone );
+ err = PostEventToQueue(GetMainEventQueue(), wakeupEvent,
+ kEventPriorityHigh );
+}
+void wxGUIEventLoop::DoRun()
+{
+ wxMacAutoreleasePool autoreleasepool;
RunApplicationEventLoop();
-
- return m_exitcode;
}
-void wxGUIEventLoop::Exit(int rc)
+void wxGUIEventLoop::DoStop()
{
- m_exitcode = rc;
-
QuitApplicationEventLoop();
-
- OnExit();
}
-#else // manual event loop
+CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
+{
+ return wxCFEventLoop::CFGetCurrentRunLoop();
+}
-// ----------------------------------------------------------------------------
-// functions only used by wxEventLoopManual-based implementation
-// ----------------------------------------------------------------------------
+// TODO move into a evtloop_osx.cpp
-void wxGUIEventLoop::WakeUp()
+wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow)
{
- extern void wxMacWakeUp();
-
- wxMacWakeUp();
+ m_modalWindow = wxDynamicCast(modalWindow, wxNonOwnedWindow);
+ wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
+ m_modalNativeWindow = m_modalWindow->GetWXWindow();
}
-#endif // high/low-level event loop
+wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow)
+{
+ m_modalWindow = NULL;
+ wxASSERT_MSG( modalNativeWindow != NULL, "must pass in a toplevel window for modal event loop" );
+ m_modalNativeWindow = modalNativeWindow;
+}
-// ----------------------------------------------------------------------------
-// low level functions used in both cases
-// ----------------------------------------------------------------------------
+// END move into a evtloop_osx.cpp
-bool wxGUIEventLoop::Pending() const
+void wxModalEventLoop::DoRun()
{
-#if wxOSX_USE_CARBON
- EventRef theEvent;
-
- return ReceiveNextEvent
- (
- 0, // we want any event at all so we don't specify neither
- NULL, // the number of event types nor the types themselves
- kEventDurationNoWait,
- false, // don't remove the event from queue
- &theEvent
- ) == noErr;
-#else
- return true; // TODO
-#endif
+ wxWindowDisabler disabler(m_modalWindow);
+ wxMacAutoreleasePool autoreleasepool;
+
+ bool resetGroupParent = false;
+
+ WindowGroupRef windowGroup = NULL;
+ WindowGroupRef formerParentGroup = NULL;
+
+ // make sure modal dialogs are in the right layer so that they are not covered
+ if ( m_modalWindow != NULL )
+ {
+ if ( m_modalWindow->GetParent() == NULL )
+ {
+ windowGroup = GetWindowGroup(m_modalNativeWindow) ;
+ if ( windowGroup != GetWindowGroupOfClass( kMovableModalWindowClass ) )
+ {
+ formerParentGroup = GetWindowGroupParent( windowGroup );
+ SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) );
+ resetGroupParent = true;
+ }
+ }
+ }
+
+ m_modalWindow->SetFocus();
+
+ RunAppModalLoopForWindow(m_modalNativeWindow);
+
+ if ( resetGroupParent )
+ {
+ SetWindowGroupParent( windowGroup , formerParentGroup );
+ }
+
}
-bool wxGUIEventLoop::Dispatch()
+void wxModalEventLoop::DoStop()
{
- if ( !wxTheApp )
- return false;
-
-#if wxOSX_USE_CARBON
- // TODO: we probably should do the dispatching directly from here but for
- // now it's easier to forward to wxApp which has all the code to do
- // it
- wxTheApp->MacDoOneEvent();
-#else
- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0);
-#endif
- return true;
+ wxMacAutoreleasePool autoreleasepool;
+ QuitAppModalLoopForWindow(m_modalNativeWindow);
}
+
+