making sure no pending deletes get executed while a modal loop is running, avoiding double deletes because the dialogs are mostly allocated on the stack.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75289 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2013-11-25 13:51:12 +00:00
parent f155a9f376
commit 16cc627332
3 changed files with 44 additions and 3 deletions

View File

@ -30,7 +30,9 @@ public:
#ifdef __WXOSX_COCOA__
// skip wxGUIEventLoop to avoid missing Enter/Exit notifications
int Run() { return wxCFEventLoop::Run(); }
virtual int Run() { return wxCFEventLoop::Run(); }
virtual bool ProcessIdle();
#endif
protected:
virtual void OSXDoRun();

View File

@ -421,6 +421,45 @@ void wxModalEventLoop::OSXDoStop()
[NSApp abortModal];
}
// we need our own version of ProcessIdle here in order to
// avoid deletion of pending objects, because ProcessIdle is running
// to soon and ends up in destroying the object too early, ie before
// a stack allocated instance is removed resulting in double deletes
bool wxModalEventLoop::ProcessIdle()
{
bool needMore = false;
if ( wxTheApp )
{
// synthesize an idle event and check if more of them are needed
wxIdleEvent event;
event.SetEventObject(wxTheApp);
wxTheApp->ProcessEvent(event);
#if wxUSE_LOG
// flush the logged messages if any (do this after processing the events
// which could have logged new messages)
wxLog::FlushActive();
#endif
bool needMore = event.MoreRequested();
wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
while (node)
{
wxWindow* win = node->GetData();
// Don't send idle events to the windows that are about to be destroyed
// anyhow, this is wasteful and unexpected.
if ( !wxPendingDelete.Member(win) && win->SendIdleEvents(event) )
needMore = true;
node = node->GetNext();
}
wxUpdateUIEvent::ResetUpdateTime();
}
return needMore;
}
void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow )
{
WXWindow nsnow = nil;

View File

@ -71,14 +71,14 @@ wxCFEventLoopSource::~wxCFEventLoopSource()
void wxCFEventLoop::OSXCommonModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
{
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
if ( eventloop )
if ( eventloop && eventloop->IsRunning() )
eventloop->CommonModeObserverCallBack(observer, activity);
}
void wxCFEventLoop::OSXDefaultModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
{
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
if ( eventloop )
if ( eventloop && eventloop->IsRunning() )
eventloop->DefaultModeObserverCallBack(observer, activity);
}