X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/524c47aa3adf2af11a3069fd5da035a604f08f66..038809c2f657f03d8688d7a75ca416878dfa0de7:/src/osx/carbon/evtloop.cpp diff --git a/src/osx/carbon/evtloop.cpp b/src/osx/carbon/evtloop.cpp index ec51ee972b..d263effec7 100644 --- a/src/osx/carbon/evtloop.cpp +++ b/src/osx/carbon/evtloop.cpp @@ -28,8 +28,13 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/log.h" #endif // WX_PRECOMP +#if wxUSE_GUI +#include "wx/nonownedwnd.h" +#endif + #include "wx/osx/private.h" // ============================================================================ @@ -38,74 +43,130 @@ wxGUIEventLoop::wxGUIEventLoop() { - m_sleepTime = kEventDurationNoWait; +} + +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 ); +} + +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; + } } void wxGUIEventLoop::WakeUp() { - extern void wxMacWakeUp(); + OSStatus err = noErr; + wxMacCarbonEvent wakeupEvent; + wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), + kEventAttributeNone ); + err = PostEventToQueue(GetMainEventQueue(), wakeupEvent, + kEventPriorityHigh ); +} + +void wxGUIEventLoop::DoRun() +{ + wxMacAutoreleasePool autoreleasepool; + RunApplicationEventLoop(); +} + +void wxGUIEventLoop::DoStop() +{ + QuitApplicationEventLoop(); +} - wxMacWakeUp(); +CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const +{ + return wxCFEventLoop::CFGetCurrentRunLoop(); } -bool wxGUIEventLoop::Pending() const +// TODO move into a evtloop_osx.cpp + +wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow) { - 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; + 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(); } -bool wxGUIEventLoop::Dispatch() +wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow) { - if ( !wxTheApp ) - return false; + m_modalWindow = NULL; + wxASSERT_MSG( modalNativeWindow != NULL, "must pass in a toplevel window for modal event loop" ); + m_modalNativeWindow = modalNativeWindow; +} + +// END move into a evtloop_osx.cpp +void wxModalEventLoop::DoRun() +{ + wxWindowDisabler disabler(m_modalWindow); wxMacAutoreleasePool autoreleasepool; - EventRef theEvent; + bool resetGroupParent = false; - OSStatus status = ReceiveNextEvent(0, NULL, m_sleepTime, true, &theEvent) ; + WindowGroupRef windowGroup = NULL; + WindowGroupRef formerParentGroup = NULL; - switch (status) + // make sure modal dialogs are in the right layer so that they are not covered + if ( m_modalWindow != NULL ) { - case eventLoopTimedOutErr : - if ( wxTheApp->ProcessIdle() ) - m_sleepTime = kEventDurationNoWait ; - else + if ( m_modalWindow->GetParent() == NULL ) + { + windowGroup = GetWindowGroup(m_modalNativeWindow) ; + if ( windowGroup != GetWindowGroupOfClass( kMovableModalWindowClass ) ) { - m_sleepTime = kEventDurationSecond; -#if wxUSE_THREADS - wxMutexGuiLeave(); - wxMilliSleep(20); - wxMutexGuiEnter(); -#endif + formerParentGroup = GetWindowGroupParent( windowGroup ); + SetWindowGroupParent( windowGroup, GetWindowGroupOfClass( kMovableModalWindowClass ) ); + resetGroupParent = true; } - break; - - case eventLoopQuitErr : - // according to QA1061 this may also occur - // when a WakeUp Process is executed - break; + } + } - default: - if ( wxTheApp ) - wxTheApp->MacSetCurrentEvent( theEvent, NULL ); + m_modalWindow->SetFocus(); - OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget()); - if (status == eventNotHandledErr && wxTheApp) - wxTheApp->MacHandleUnhandledEvent(theEvent); + RunAppModalLoopForWindow(m_modalNativeWindow); - ReleaseEvent( theEvent ); - m_sleepTime = kEventDurationNoWait ; - break; + if ( resetGroupParent ) + { + SetWindowGroupParent( windowGroup , formerParentGroup ); } - return true; } + +void wxModalEventLoop::DoStop() +{ + wxMacAutoreleasePool autoreleasepool; + QuitAppModalLoopForWindow(m_modalNativeWindow); +} + +