X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f965a844db8663b80c42afcbb6ae2dc36fd77ac3..13390af486a8b9b72408260f6d89309870a43812:/src/osx/cocoa/evtloop.mm diff --git a/src/osx/cocoa/evtloop.mm b/src/osx/cocoa/evtloop.mm index 92f08d178e..89957cd2bd 100644 --- a/src/osx/cocoa/evtloop.mm +++ b/src/osx/cocoa/evtloop.mm @@ -28,6 +28,7 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/nonownedwnd.h" #endif // WX_PRECOMP #include "wx/log.h" @@ -38,27 +39,70 @@ // wxEventLoop implementation // ============================================================================ -wxGUIEventLoop::wxGUIEventLoop() +/* +static int CalculateNSEventMaskFromEventCategory(wxEventCategory cat) { - m_sleepTime = 0.0; + NSLeftMouseDownMask | + NSLeftMouseUpMask | + NSRightMouseDownMask | + NSRightMouseUpMask = 1 << NSRightMouseUp, + NSMouseMovedMask = 1 << NSMouseMoved, + NSLeftMouseDraggedMask = 1 << NSLeftMouseDragged, + NSRightMouseDraggedMask = 1 << NSRightMouseDragged, + NSMouseEnteredMask = 1 << NSMouseEntered, + NSMouseExitedMask = 1 << NSMouseExited, + NSScrollWheelMask = 1 << NSScrollWheel, +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + NSTabletPointMask = 1 << NSTabletPoint, + NSTabletProximityMask = 1 << NSTabletProximity, +#endif + NSOtherMouseDownMask = 1 << NSOtherMouseDown, + NSOtherMouseUpMask = 1 << NSOtherMouseUp, + NSOtherMouseDraggedMask = 1 << NSOtherMouseDragged, + + + + NSKeyDownMask = 1 << NSKeyDown, + NSKeyUpMask = 1 << NSKeyUp, + NSFlagsChangedMask = 1 << NSFlagsChanged, + + NSAppKitDefinedMask = 1 << NSAppKitDefined, + NSSystemDefinedMask = 1 << NSSystemDefined, + NSApplicationDefinedMask = 1 << NSApplicationDefined, + NSPeriodicMask = 1 << NSPeriodic, + NSCursorUpdateMask = 1 << NSCursorUpdate, + + NSAnyEventMask = 0xffffffffU } +*/ -void wxGUIEventLoop::WakeUp() +wxGUIEventLoop::wxGUIEventLoop() { - extern void wxMacWakeUp(); - - wxMacWakeUp(); } +//----------------------------------------------------------------------------- +// 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() @@ -74,11 +118,22 @@ 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 { + if (wxTheApp) + wxTheApp->ProcessPendingEvents(); + if ( wxTheApp->ProcessIdle() ) m_sleepTime = 0.0 ; else @@ -95,44 +150,9 @@ bool wxGUIEventLoop::Dispatch() return true; } -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; -} +#endif -int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) +int wxGUIEventLoop::DoDispatchTimeout(unsigned long timeout) { wxMacAutoreleasePool autoreleasepool; @@ -141,10 +161,82 @@ int wxGUIEventLoop::DispatchTimeout(unsigned long timeout) untilDate:[NSDate dateWithTimeIntervalSinceNow: timeout/1000] inMode:NSDefaultRunLoopMode dequeue: YES]; - if ( !event ) + + if ( event == nil ) return -1; [NSApp sendEvent: event]; - return true; + return 1; +} + +void wxGUIEventLoop::DoRun() +{ + wxMacAutoreleasePool autoreleasepool; + [NSApp run]; +} + +void wxGUIEventLoop::DoStop() +{ + [NSApp stop:0]; + // only calling stop: is not enough when called from a runloop-observer, + // therefore add a dummy event, to make sure the runloop gets another round + NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined + location:NSMakePoint(0.0, 0.0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + subtype:0 data1:0 data2:0]; + [NSApp postEvent:event atStart:FALSE]; +} + +CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const +{ + NSRunLoop* nsloop = [NSRunLoop currentRunLoop]; + return [nsloop getCFRunLoop]; +} + + +// TODO move into a evtloop_osx.cpp + +wxModalEventLoop::wxModalEventLoop(wxWindow *modalWindow) +{ + m_modalWindow = dynamic_cast (modalWindow); + wxASSERT_MSG( m_modalWindow != NULL, "must pass in a toplevel window for modal event loop" ); + m_modalNativeWindow = m_modalWindow->GetWXWindow(); +} + +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::DoRun() +{ + wxMacAutoreleasePool pool; + + // 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]; +} +