X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8d60daa8d3d4ff1df00129b679713809f91f6ec5..cdbd62d6ff290fd58acd1bc5574dfc79db3a6f70:/src/osx/carbon/evtloop.cpp diff --git a/src/osx/carbon/evtloop.cpp b/src/osx/carbon/evtloop.cpp index 1a2937afbc..4a8238baa0 100644 --- a/src/osx/carbon/evtloop.cpp +++ b/src/osx/carbon/evtloop.cpp @@ -4,7 +4,6 @@ // Author: Vadim Zeitlin // Modified by: // Created: 2006-01-12 -// RCS-ID: $Id$ // Copyright: (c) 2006 Vadim Zeitlin // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -28,8 +27,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,17 +42,9 @@ wxGUIEventLoop::wxGUIEventLoop() { - m_sleepTime = kEventDurationNoWait; } -void wxGUIEventLoop::WakeUp() -{ - extern void wxMacWakeUp(); - - wxMacWakeUp(); -} - -void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent) +static void DispatchAndReleaseEvent(EventRef theEvent) { if ( wxTheApp ) wxTheApp->MacSetCurrentEvent( theEvent, NULL ); @@ -60,63 +56,10 @@ void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent) ReleaseEvent( theEvent ); } -bool wxGUIEventLoop::Pending() const +int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout) { - 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; -} - -bool wxGUIEventLoop::Dispatch() -{ - if ( !wxTheApp ) - return false; - wxMacAutoreleasePool autoreleasepool; - EventRef theEvent; - - OSStatus status = ReceiveNextEvent(0, NULL, m_sleepTime, true, &theEvent) ; - - switch (status) - { - case eventLoopTimedOutErr : - if ( wxTheApp->ProcessIdle() ) - m_sleepTime = kEventDurationNoWait ; - else - { - m_sleepTime = kEventDurationSecond; -#if wxUSE_THREADS - wxMutexGuiLeave(); - wxMilliSleep(20); - wxMutexGuiEnter(); -#endif - } - break; - - case eventLoopQuitErr : - // according to QA1061 this may also occur - // when a WakeUp Process is executed - break; - - default: - DispatchAndReleaseEvent(theEvent); - m_sleepTime = kEventDurationNoWait ; - break; - } - - return true; -} - -int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) -{ EventRef event; OSStatus status = ReceiveNextEvent(0, NULL, timeout/1000, true, &event); switch ( status ) @@ -129,6 +72,8 @@ int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) return -1; case eventLoopQuitErr: + // according to QA1061 this may also occur + // when a WakeUp Process is executed return 0; case noErr: @@ -137,39 +82,98 @@ int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) } } -bool wxGUIEventLoop::YieldFor(long eventsToProcess) +void wxGUIEventLoop::WakeUp() +{ + OSStatus err = noErr; + wxMacCarbonEvent wakeupEvent; + wakeupEvent.Create( 'WXMC', 'WXMC', GetCurrentEventTime(), + kEventAttributeNone ); + err = PostEventToQueue(GetMainEventQueue(), wakeupEvent, + kEventPriorityHigh ); +} + +void wxGUIEventLoop::OSXDoRun() { -#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() ) + wxMacAutoreleasePool autoreleasepool; + + while (!m_shouldExit) { - return true; + RunApplicationEventLoop(); } -#endif // wxUSE_THREADS - m_isInsideYield = true; - m_eventsToProcessInsideYield = eventsToProcess; + // Force enclosing event loop to temporarily exit and check + // if it should be stopped. + QuitApplicationEventLoop(); +} -#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 +void wxGUIEventLoop::OSXDoStop() +{ + QuitApplicationEventLoop(); +} - // process all pending events: - while ( Pending() ) - Dispatch(); +CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const +{ + return wxCFEventLoop::CFGetCurrentRunLoop(); +} - // 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() ) {} +// TODO move into a evtloop_osx.cpp -#if wxUSE_LOG - wxLog::Resume(); -#endif // wxUSE_LOG - m_isInsideYield = false; +wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow) +{ + 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(); +} - return true; +wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow) +{ + 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::OSXDoRun() +{ + 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 ); + } + +} + +void wxModalEventLoop::OSXDoStop() +{ + wxMacAutoreleasePool autoreleasepool; + QuitAppModalLoopForWindow(m_modalNativeWindow); +} + +