fix for idle processing stopping without processing all pending events, replaces patch 1912157
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@52465 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -166,6 +166,8 @@ wxGTK:
|
|||||||
- Fix wxNotebook::GetPage{Text,Image}() when they were called from the page
|
- Fix wxNotebook::GetPage{Text,Image}() when they were called from the page
|
||||||
change event handler for the first added page (Mikkel S).
|
change event handler for the first added page (Mikkel S).
|
||||||
- Fixed wxBitmapButton to use focus and hover bitmaps correctly.
|
- Fixed wxBitmapButton to use focus and hover bitmaps correctly.
|
||||||
|
- Fixed race condition which could cause idle processing to stop without
|
||||||
|
processing all pending events.
|
||||||
|
|
||||||
wxMac:
|
wxMac:
|
||||||
|
|
||||||
|
102
src/gtk/app.cpp
102
src/gtk/app.cpp
@@ -174,59 +174,63 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) )
|
|||||||
if (!wxTheApp)
|
if (!wxTheApp)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool moreIdles = false;
|
guint idleID_save;
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
|
||||||
// don't generate the idle events while the assert modal dialog is shown,
|
|
||||||
// this matches the behavior of wxMSW
|
|
||||||
if (!wxTheApp->IsInAssert())
|
|
||||||
#endif // __WXDEBUG__
|
|
||||||
{
|
|
||||||
guint idleID_save;
|
|
||||||
{
|
|
||||||
// Allow another idle source to be added while this one is busy.
|
|
||||||
// Needed if an idle event handler runs a new event loop,
|
|
||||||
// for example by showing a dialog.
|
|
||||||
#if wxUSE_THREADS
|
|
||||||
wxMutexLocker lock(gs_idleTagsMutex);
|
|
||||||
#endif
|
|
||||||
idleID_save = wxTheApp->m_idleTag;
|
|
||||||
wxTheApp->m_idleTag = 0;
|
|
||||||
g_isIdle = true;
|
|
||||||
wxAddEmissionHook();
|
|
||||||
}
|
|
||||||
|
|
||||||
// When getting called from GDK's time-out handler
|
|
||||||
// we are no longer within GDK's grab on the GUI
|
|
||||||
// thread so we must lock it here ourselves.
|
|
||||||
gdk_threads_enter();
|
|
||||||
|
|
||||||
// Send idle event to all who request them as long as
|
|
||||||
// no events have popped up in the event queue.
|
|
||||||
do {
|
|
||||||
moreIdles = wxTheApp->ProcessIdle();
|
|
||||||
} while (moreIdles && gtk_events_pending() == 0);
|
|
||||||
|
|
||||||
// Release lock again
|
|
||||||
gdk_threads_leave();
|
|
||||||
|
|
||||||
{
|
|
||||||
// If another idle source was added, remove it
|
|
||||||
#if wxUSE_THREADS
|
|
||||||
wxMutexLocker lock(gs_idleTagsMutex);
|
|
||||||
#endif
|
|
||||||
if (wxTheApp->m_idleTag != 0)
|
|
||||||
g_source_remove(wxTheApp->m_idleTag);
|
|
||||||
wxTheApp->m_idleTag = idleID_save;
|
|
||||||
g_isIdle = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moreIdles)
|
|
||||||
{
|
{
|
||||||
|
// Allow another idle source to be added while this one is busy.
|
||||||
|
// Needed if an idle event handler runs a new event loop,
|
||||||
|
// for example by showing a dialog.
|
||||||
#if wxUSE_THREADS
|
#if wxUSE_THREADS
|
||||||
wxMutexLocker lock(gs_idleTagsMutex);
|
wxMutexLocker lock(gs_idleTagsMutex);
|
||||||
#endif
|
#endif
|
||||||
|
idleID_save = wxTheApp->m_idleTag;
|
||||||
|
wxTheApp->m_idleTag = 0;
|
||||||
|
g_isIdle = true;
|
||||||
|
wxAddEmissionHook();
|
||||||
|
}
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
// don't generate the idle events while the assert modal dialog is shown,
|
||||||
|
// this matches the behavior of wxMSW
|
||||||
|
if (wxTheApp->IsInAssert())
|
||||||
|
return false;
|
||||||
|
#endif // __WXDEBUG__
|
||||||
|
|
||||||
|
// When getting called from GDK's time-out handler
|
||||||
|
// we are no longer within GDK's grab on the GUI
|
||||||
|
// thread so we must lock it here ourselves.
|
||||||
|
gdk_threads_enter();
|
||||||
|
|
||||||
|
// Send idle event to all who request them as long as
|
||||||
|
// no events have popped up in the event queue.
|
||||||
|
bool moreIdles;
|
||||||
|
do {
|
||||||
|
moreIdles = wxTheApp->ProcessIdle();
|
||||||
|
} while (moreIdles && gtk_events_pending() == 0);
|
||||||
|
|
||||||
|
// Release lock again
|
||||||
|
gdk_threads_leave();
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
wxMutexLocker lock(gs_idleTagsMutex);
|
||||||
|
#endif
|
||||||
|
// If another idle source was added, remove it
|
||||||
|
if (wxTheApp->m_idleTag != 0)
|
||||||
|
g_source_remove(wxTheApp->m_idleTag);
|
||||||
|
wxTheApp->m_idleTag = idleID_save;
|
||||||
|
g_isIdle = false;
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
if (wxPendingEventsLocker)
|
||||||
|
wxPendingEventsLocker->Enter();
|
||||||
|
#endif
|
||||||
|
// Pending events can be added asynchronously,
|
||||||
|
// need to keep idle source if any have appeared
|
||||||
|
moreIdles = moreIdles || (wxPendingEvents && !wxPendingEvents->IsEmpty());
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
if (wxPendingEventsLocker)
|
||||||
|
wxPendingEventsLocker->Leave();
|
||||||
|
#endif
|
||||||
|
if (!moreIdles)
|
||||||
|
{
|
||||||
// Indicate that we are now in idle mode and event handlers
|
// Indicate that we are now in idle mode and event handlers
|
||||||
// will have to reinstall the idle handler again.
|
// will have to reinstall the idle handler again.
|
||||||
g_isIdle = true;
|
g_isIdle = true;
|
||||||
|
Reference in New Issue
Block a user