X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/203ec4242ba623e2d8ce5ab7ef56bdead3001689..ab67e8874db324fab5223cc8d5dff8a8de3e2b77:/src/osx/cocoa/evtloop.mm?ds=sidebyside diff --git a/src/osx/cocoa/evtloop.mm b/src/osx/cocoa/evtloop.mm index c9ac5ee75d..135f936de5 100644 --- a/src/osx/cocoa/evtloop.mm +++ b/src/osx/cocoa/evtloop.mm @@ -107,12 +107,16 @@ wxGUIEventLoop::wxGUIEventLoop() { m_modalSession = nil; m_dummyWindow = nil; + m_modalNestedLevel = 0; + m_modalWindow = NULL; + m_osxLowLevelWakeUp = false; } wxGUIEventLoop::~wxGUIEventLoop() { wxASSERT( m_modalSession == nil ); wxASSERT( m_dummyWindow == nil ); + wxASSERT( m_modalNestedLevel == 0 ); } //----------------------------------------------------------------------------- @@ -140,6 +144,7 @@ bool wxGUIEventLoop::Pending() const #endif } + bool wxGUIEventLoop::Dispatch() { if ( !wxTheApp ) @@ -243,17 +248,36 @@ void wxGUIEventLoop::DoRun() 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 + [NSApp stop:0]; + WakeUp(); +} + +void wxGUIEventLoop::WakeUp() +{ + // NSEvent* cevent = [NSApp currentEvent]; + // NSString* mode = [[NSRunLoop mainRunLoop] currentMode]; + + // when already in a mouse event handler, don't add higher level event + // if ( cevent != nil && [cevent type] <= NSMouseMoved && ) + if ( m_osxLowLevelWakeUp /* [NSEventTrackingRunLoopMode isEqualToString:mode] */ ) + { + // NSLog(@"event for wakeup %@ in mode %@",cevent,mode); + wxCFEventLoop::WakeUp(); + } + else + { + wxMacAutoreleasePool autoreleasepool; + 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]; + [NSApp postEvent:event atStart:FALSE]; + } } CFRunLoopRef wxGUIEventLoop::CFGetCurrentRunLoop() const @@ -302,12 +326,22 @@ void wxModalEventLoop::DoRun() void wxModalEventLoop::DoStop() { - [NSApp stopModal]; + [NSApp abortModal]; } void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow ) { WXWindow nsnow = nil; + + if ( m_modalNestedLevel > 0 ) + { + wxASSERT_MSG( m_modalWindow == modalWindow, "Nested Modal Sessions must be based on same window"); + m_modalNestedLevel++; + return; + } + + m_modalWindow = modalWindow; + m_modalNestedLevel = 1; if ( modalWindow ) { @@ -339,12 +373,18 @@ void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow ) void wxGUIEventLoop::EndModalSession() { wxASSERT_MSG(m_modalSession != NULL, "no modal session active"); - [NSApp endModalSession:(NSModalSession)m_modalSession]; - m_modalSession = nil; - if ( m_dummyWindow ) + + wxASSERT_MSG(m_modalNestedLevel > 0, "incorrect modal nesting level"); + + if ( --m_modalNestedLevel == 0 ) { - [m_dummyWindow release]; - m_dummyWindow = nil; + [NSApp endModalSession:(NSModalSession)m_modalSession]; + m_modalSession = nil; + if ( m_dummyWindow ) + { + [m_dummyWindow release]; + m_dummyWindow = nil; + } } } @@ -396,7 +436,8 @@ void wxWindowDisabler::DoDisable(wxWindow *winToSkip) } m_modalEventLoop = (wxEventLoop*)wxEventLoopBase::GetActive(); - m_modalEventLoop->BeginModalSession(winToSkip); + if (m_modalEventLoop) + m_modalEventLoop->BeginModalSession(winToSkip); } wxWindowDisabler::~wxWindowDisabler() @@ -404,7 +445,8 @@ wxWindowDisabler::~wxWindowDisabler() if ( !m_disabled ) return; - m_modalEventLoop->EndModalSession(); + if (m_modalEventLoop) + m_modalEventLoop->EndModalSession(); wxWindowList::compatibility_iterator node; for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) @@ -418,5 +460,4 @@ wxWindowDisabler::~wxWindowDisabler() } delete m_winDisabled; -} - +} \ No newline at end of file