X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b2680ced12cbbed16990007c5fa3ea7730700122..43c5b6e808f083617eb42cb48e77366844f8fb5c:/src/osx/carbon/evtloop.cpp diff --git a/src/osx/carbon/evtloop.cpp b/src/osx/carbon/evtloop.cpp index deee02fdce..4278ced196 100644 --- a/src/osx/carbon/evtloop.cpp +++ b/src/osx/carbon/evtloop.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/evtloop.cpp +// Name: src/osx/carbon/evtloop.cpp // Purpose: implementation of wxEventLoop for wxMac // Author: Vadim Zeitlin // Modified by: @@ -28,49 +28,20 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/log.h" #endif // WX_PRECOMP -#if wxOSX_USE_CARBON - #include -#else - #include -#endif +#include "wx/osx/private.h" + // ============================================================================ // wxEventLoop implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// high level functions for RunApplicationEventLoop() case -// ---------------------------------------------------------------------------- - - - -#if wxMAC_USE_RUN_APP_EVENT_LOOP - -int wxGUIEventLoop::Run() -{ - wxEventLoopActivator activate(this); - - RunApplicationEventLoop(); - - return m_exitcode; -} - -void wxGUIEventLoop::Exit(int rc) +wxGUIEventLoop::wxGUIEventLoop() { - m_exitcode = rc; - - QuitApplicationEventLoop(); - - OnExit(); + m_sleepTime = kEventDurationNoWait; } -#else // manual event loop - -// ---------------------------------------------------------------------------- -// functions only used by wxEventLoopManual-based implementation -// ---------------------------------------------------------------------------- - void wxGUIEventLoop::WakeUp() { extern void wxMacWakeUp(); @@ -78,15 +49,20 @@ void wxGUIEventLoop::WakeUp() wxMacWakeUp(); } -#endif // high/low-level event loop +void wxGUIEventLoop::DispatchAndReleaseEvent(EventRef theEvent) +{ + if ( wxTheApp ) + wxTheApp->MacSetCurrentEvent( theEvent, NULL ); -// ---------------------------------------------------------------------------- -// low level functions used in both cases -// ---------------------------------------------------------------------------- + OSStatus status = SendEventToEventTarget(theEvent, GetEventDispatcherTarget()); + if (status == eventNotHandledErr && wxTheApp) + wxTheApp->MacHandleUnhandledEvent(theEvent); + + ReleaseEvent( theEvent ); +} bool wxGUIEventLoop::Pending() const { -#if wxOSX_USE_CARBON EventRef theEvent; return ReceiveNextEvent @@ -97,9 +73,6 @@ bool wxGUIEventLoop::Pending() const false, // don't remove the event from queue &theEvent ) == noErr; -#else - return true; // TODO -#endif } bool wxGUIEventLoop::Dispatch() @@ -107,13 +80,97 @@ bool wxGUIEventLoop::Dispatch() 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); + 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 ) + { + default: + wxFAIL_MSG( "unexpected ReceiveNextEvent() error" ); + // fall through + + case eventLoopTimedOutErr: + return -1; + + case eventLoopQuitErr: + return 0; + + case noErr: + DispatchAndReleaseEvent(event); + return 1; + } +} + +bool wxGUIEventLoop::YieldFor(long eventsToProcess) +{ +#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() ) + { + return true; + } +#endif // wxUSE_THREADS + + m_isInsideYield = true; + m_eventsToProcessInsideYield = eventsToProcess; + +#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 + + // process all pending events: + while ( Pending() ) + Dispatch(); + + // 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() ) {} + +#if wxUSE_LOG + wxLog::Resume(); +#endif // wxUSE_LOG + m_isInsideYield = false; + return true; }