From 4c4cbded1ff919906fb783368c020531794316ea Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 15 Jun 2012 00:03:51 +0000 Subject: [PATCH] offer suppression of idle processing (delayed destruction happened too early eg when showing native message boxes) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71778 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/evtloop.h | 19 ++++++++++++++++++- src/osx/core/evtloop_cf.cpp | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/wx/osx/evtloop.h b/include/wx/osx/evtloop.h index 00a5258fce..d33e44d2c3 100644 --- a/include/wx/osx/evtloop.h +++ b/include/wx/osx/evtloop.h @@ -17,8 +17,11 @@ DECLARE_WXOSX_OPAQUE_CFREF( CFRunLoop ); DECLARE_WXOSX_OPAQUE_CFREF( CFRunLoopObserver ); +class WXDLLIMPEXP_BASE wxCFEventLoopPauseObservers; + class WXDLLIMPEXP_BASE wxCFEventLoop : public wxEventLoopBase { + friend class wxCFEventLoopPauseObservers; public: wxCFEventLoop(); virtual ~wxCFEventLoop(); @@ -53,11 +56,13 @@ public: AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags); #endif // wxUSE_EVENTLOOP_SOURCE - protected: void CommonModeObserverCallBack(CFRunLoopObserverRef observer, int activity); void DefaultModeObserverCallBack(CFRunLoopObserverRef observer, int activity); + // set to false to avoid idling at unexpected moments - eg when having native message boxes + void SetProcessIdleEvents(bool process) { m_processIdleEvents = process; } + static void OSXCommonModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info); static void OSXDefaultModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info); @@ -84,6 +89,9 @@ protected: // default mode runloop observer CFRunLoopObserverRef m_defaultModeRunLoopObserver; + + // set to false to avoid idling at unexpected moments - eg when having native message boxes + bool m_processIdleEvents; private: // process all already pending events and dispatch a new one (blocking @@ -91,6 +99,15 @@ private: // // returns the return value of DoDispatchTimeout() int DoProcessEvents(); + + wxDECLARE_NO_COPY_CLASS(wxCFEventLoop); +}; + +class WXDLLIMPEXP_BASE wxCFEventLoopPauseObservers : public wxObject +{ +public: + wxCFEventLoopPauseObservers(); + virtual ~wxCFEventLoopPauseObservers(); }; #if wxUSE_GUI diff --git a/src/osx/core/evtloop_cf.cpp b/src/osx/core/evtloop_cf.cpp index 57fa767aba..0c98ae3fea 100644 --- a/src/osx/core/evtloop_cf.cpp +++ b/src/osx/core/evtloop_cf.cpp @@ -169,7 +169,7 @@ void wxCFEventLoop::CommonModeObserverCallBack(CFRunLoopObserverRef WXUNUSED(obs if ( activity & kCFRunLoopBeforeWaiting ) { - if ( ProcessIdle() ) + if ( m_processIdleEvents && ProcessIdle() ) { WakeUp(); } @@ -201,6 +201,7 @@ wxCFEventLoop::DefaultModeObserverCallBack(CFRunLoopObserverRef WXUNUSED(observe wxCFEventLoop::wxCFEventLoop() { m_shouldExit = false; + m_processIdleEvents = true; m_runLoop = CFGetCurrentRunLoop(); @@ -210,18 +211,19 @@ wxCFEventLoop::wxCFEventLoop() m_commonModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXCommonModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_commonModeRunLoopObserver, kCFRunLoopCommonModes); - CFRelease(m_commonModeRunLoopObserver); m_defaultModeRunLoopObserver = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting , true /* repeats */, 0, (CFRunLoopObserverCallBack) wxCFEventLoop::OSXDefaultModeObserverCallBack, &ctxt ); CFRunLoopAddObserver(m_runLoop, m_defaultModeRunLoopObserver, kCFRunLoopDefaultMode); - CFRelease(m_defaultModeRunLoopObserver); } wxCFEventLoop::~wxCFEventLoop() { CFRunLoopRemoveObserver(m_runLoop, m_commonModeRunLoopObserver, kCFRunLoopCommonModes); CFRunLoopRemoveObserver(m_runLoop, m_defaultModeRunLoopObserver, kCFRunLoopDefaultMode); + + CFRelease(m_defaultModeRunLoopObserver); + CFRelease(m_commonModeRunLoopObserver); } @@ -439,6 +441,20 @@ void wxCFEventLoop::Exit(int rc) DoStop(); } +wxCFEventLoopPauseObservers::wxCFEventLoopPauseObservers() +{ + wxCFEventLoop* cfl = dynamic_cast(wxEventLoopBase::GetActive()); + if ( cfl ) + cfl->SetProcessIdleEvents(false); +} + +wxCFEventLoopPauseObservers::~wxCFEventLoopPauseObservers() +{ + wxCFEventLoop* cfl = dynamic_cast(wxEventLoopBase::GetActive()); + if ( cfl ) + cfl->SetProcessIdleEvents(true); +} + // TODO Move to thread_osx.cpp #if wxUSE_THREADS -- 2.47.2