#ifndef WX_PRECOMP
#include "wx/app.h"
+ #include "wx/nonownedwnd.h"
#endif // WX_PRECOMP
#include "wx/log.h"
wxGUIEventLoop::wxGUIEventLoop()
{
- m_sleepTime = 0.0;
-}
-
-void wxGUIEventLoop::WakeUp()
-{
- extern void wxMacWakeUp();
-
- wxMacWakeUp();
-}
-
-//-----------------------------------------------------------------------------
-// event loop sources operations
-//-----------------------------------------------------------------------------
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-extern "C"
-{
-struct wx_cffd_data
-{
- wxEventLoopSourceHandler* handler;
- int flags;
-};
-
-static void wx_cffiledescriptor_callback(CFFileDescriptorRef cffd,
- CFOptionFlags flags, void* ctxData)
-{
- wxLogTrace(wxTRACE_EVT_SOURCE, "CFFileDescriptor Callback");
-
- wx_cffd_data* data = static_cast<wx_cffd_data*>(ctxData);
- wxEventLoopSourceHandler* handler = data->handler;
- if (flags & kCFFileDescriptorReadCallBack)
- handler->OnReadWaiting();
- if (flags & kCFFileDescriptorWriteCallBack)
- handler->OnWriteWaiting();
-
- // reenable callbacks
- if (data->flags & wxEVENT_SOURCE_INPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
- if (data->flags & wxEVENT_SOURCE_OUTPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
-}
-}
-
-wxMacEventLoopSource* wxGUIEventLoop::CreateSource(int fd,
- wxEventLoopSourceHandler* handler,
- int flags) const
-{
- wxMacEventLoopSource* source = new wxMacEventLoopSource();
- // FIXME this is currently a leak :-)
- wx_cffd_data* data = new wx_cffd_data;
- data->handler = handler;
- data->flags = flags;
- CFFileDescriptorContext ctx = { 0, data, NULL, NULL, NULL };
- CFFileDescriptorRef cffd = CFFileDescriptorCreate(kCFAllocatorDefault, fd,
- true, wx_cffiledescriptor_callback, &ctx);
-
- if (flags & wxEVENT_SOURCE_INPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorReadCallBack);
- if (flags & wxEVENT_SOURCE_OUTPUT)
- CFFileDescriptorEnableCallBacks(cffd, kCFFileDescriptorWriteCallBack);
-
- source->SetResource(
- CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, cffd, 0));
- source->SetHandler(handler);
- source->SetFlags(flags);
- return source;
-}
-#elif
-wxMacEventLoopSource* wxGUIEventLoop::CreateSource(int fd,
- wxEventLoopSourceHandler* handler,
- int flags) const
-{
- return NULL;
-}
-#endif
-
-bool wxGUIEventLoop::DoAddSource(wxAbstractEventLoopSource* src)
-{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::AddSource() source=%d",
- source->GetResource());
-
- NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
- CFRunLoopRef cfloop = [nsloop getCFRunLoop];
- CFRunLoopAddSource(cfloop, source->GetResource(), kCFRunLoopDefaultMode);
-
- return true;
-}
-
-bool wxGUIEventLoop::DoRemoveSource(wxAbstractEventLoopSource* src)
-{
- Source* source = dynamic_cast<Source*>(src);
- wxCHECK_MSG( source, false, "Invalid source type" );
-
- wxLogTrace(wxTRACE_EVT_SOURCE,
- "wxGUIEventLoop::RemoveSource() source=%d",
- source->GetResource());
-
- NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
- CFRunLoopRef cfloop = [nsloop getCFRunLoop];
- CFRunLoopRemoveSource(cfloop, source->GetResource(), kCFRunLoopDefaultMode);
-
- return true;
}
//-----------------------------------------------------------------------------
// events dispatch and loop handling
//-----------------------------------------------------------------------------
+#if 0
+
bool wxGUIEventLoop::Pending() const
{
+#if 0
+ // this code doesn't reliably detect pending events
+ // so better return true and have the dispatch deal with it
+ // as otherwise we end up in a tight loop when idle events are responded
+ // to by RequestMore(true)
wxMacAutoreleasePool autoreleasepool;
- // a pointer to the event is returned if there is one, or nil if not
+
return [[NSApplication sharedApplication]
nextEventMatchingMask: NSAnyEventMask
untilDate: nil
inMode: NSDefaultRunLoopMode
- dequeue: NO];
+ dequeue: NO] != nil;
+#else
+ return true;
+#endif
}
bool wxGUIEventLoop::Dispatch()
inMode:NSDefaultRunLoopMode
dequeue: YES])
{
+ WXEVENTREF formerEvent = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEvent();
+ WXEVENTHANDLERCALLREF formerHandler = wxTheApp == NULL ? NULL : wxTheApp->MacGetCurrentEventHandlerCallRef();
+
+ if (wxTheApp)
+ wxTheApp->MacSetCurrentEvent(event, NULL);
m_sleepTime = 0.0;
[NSApp sendEvent: event];
+
+ if (wxTheApp)
+ wxTheApp->MacSetCurrentEvent(formerEvent , formerHandler);
}
else
{
return true;
}
-bool wxGUIEventLoop::YieldFor(long eventsToProcess)
+#endif
+
+int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout)
{
-#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
+ wxMacAutoreleasePool autoreleasepool;
- m_isInsideYield = true;
- m_eventsToProcessInsideYield = eventsToProcess;
+ NSEvent *event = [NSApp
+ nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
+ inMode:NSDefaultRunLoopMode
+ dequeue: YES];
+
+ if ( event == nil )
+ return -1;
-#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
+ [NSApp sendEvent: event];
- // process all pending events:
- while ( Pending() )
- Dispatch();
+ return 1;
+}
- // 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() ) {}
+void wxGUIEventLoop::DoRun()
+{
+ wxMacAutoreleasePool autoreleasepool;
+ [NSApp run];
+}
- // if there are pending events, we must process them.
- if (wxTheApp)
- wxTheApp->ProcessPendingEvents();
+void wxGUIEventLoop::DoStop()
+{
+ [NSApp stop:0];
+}
-#if wxUSE_LOG
- wxLog::Resume();
-#endif // wxUSE_LOG
- m_isInsideYield = false;
+CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const
+{
+ NSRunLoop* nsloop = [NSRunLoop currentRunLoop];
+ return [nsloop getCFRunLoop];
+}
- return true;
+
+// TODO move into a evtloop_osx.cpp
+
+wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow)
+{
+ m_modalWindow = dynamic_cast<wxNonOwnedWindow*> (modalWindow);
+ wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" );
+ m_modalNativeWindow = m_modalWindow->GetWXWindow();
}
-int wxGUIEventLoop::DispatchTimeout(unsigned long timeout)
+wxModalEventLoop::wxModalEventLoop(WXWindow modalNativeWindow)
{
- wxMacAutoreleasePool autoreleasepool;
+ m_modalWindow = NULL;
+ wxASSERT_MSG( modalNativeWindow != NULL, "must pass in a toplevel window for modal event loop" );
+ m_modalNativeWindow = modalNativeWindow;
+}
- NSEvent *event = [NSApp
- nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000]
- inMode:NSDefaultRunLoopMode
- dequeue: YES];
- if ( !event )
- return -1;
+// END move into a evtloop_osx.cpp
- [NSApp sendEvent: event];
+void wxModalEventLoop::DoRun()
+{
+ wxMacAutoreleasePool pool;
- return true;
+ // If the app hasn't started, flush the event queue
+ // If we don't do this, the Dock doesn't get the message that
+ // the app has started so will refuse to activate it.
+ [NSApplication sharedApplication];
+ if (![NSApp isRunning])
+ {
+ while(NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
+ {
+ [NSApp sendEvent:event];
+ }
+ }
+
+ [NSApp runModalForWindow:m_modalNativeWindow];
}
+
+void wxModalEventLoop::DoStop()
+{
+ [NSApp stopModal];
+}
+