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:
@@ -30,7 +30,9 @@ public:
|
|||||||
|
|
||||||
#ifdef __WXOSX_COCOA__
|
#ifdef __WXOSX_COCOA__
|
||||||
// skip wxGUIEventLoop to avoid missing Enter/Exit notifications
|
// skip wxGUIEventLoop to avoid missing Enter/Exit notifications
|
||||||
int Run() { return wxCFEventLoop::Run(); }
|
virtual int Run() { return wxCFEventLoop::Run(); }
|
||||||
|
|
||||||
|
virtual bool ProcessIdle();
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
virtual void OSXDoRun();
|
virtual void OSXDoRun();
|
||||||
|
@@ -421,6 +421,45 @@ void wxModalEventLoop::OSXDoStop()
|
|||||||
[NSApp abortModal];
|
[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 )
|
void wxGUIEventLoop::BeginModalSession( wxWindow* modalWindow )
|
||||||
{
|
{
|
||||||
WXWindow nsnow = nil;
|
WXWindow nsnow = nil;
|
||||||
|
@@ -71,14 +71,14 @@ wxCFEventLoopSource::~wxCFEventLoopSource()
|
|||||||
void wxCFEventLoop::OSXCommonModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
|
void wxCFEventLoop::OSXCommonModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
|
||||||
{
|
{
|
||||||
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
|
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
|
||||||
if ( eventloop )
|
if ( eventloop && eventloop->IsRunning() )
|
||||||
eventloop->CommonModeObserverCallBack(observer, activity);
|
eventloop->CommonModeObserverCallBack(observer, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCFEventLoop::OSXDefaultModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
|
void wxCFEventLoop::OSXDefaultModeObserverCallBack(CFRunLoopObserverRef observer, int activity, void *info)
|
||||||
{
|
{
|
||||||
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
|
wxCFEventLoop * eventloop = static_cast<wxCFEventLoop *>(info);
|
||||||
if ( eventloop )
|
if ( eventloop && eventloop->IsRunning() )
|
||||||
eventloop->DefaultModeObserverCallBack(observer, activity);
|
eventloop->DefaultModeObserverCallBack(observer, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user