X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/19722331f8f7fb41a778ddf8ed2c66a4ace8b501..27b2dd53f629a78266c51d1b0b5db918401dcd4f:/src/gtk/app.cpp diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 86822b5abd..b894f1bb1c 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -34,6 +34,7 @@ #include "wx/filename.h" #include "wx/module.h" #include "wx/image.h" +#include "wx/thread.h" #ifdef __WXGPE__ #include @@ -79,7 +80,6 @@ #include - //----------------------------------------------------------------------------- // global data //----------------------------------------------------------------------------- @@ -97,6 +97,10 @@ extern bool g_isIdle; void wxapp_install_idle_handler(); +#if wxUSE_THREADS +static wxMutex gs_idleTagsMutex; +#endif + //----------------------------------------------------------------------------- // wxYield //----------------------------------------------------------------------------- @@ -128,14 +132,9 @@ bool wxApp::Yield(bool onlyIfNeeded) wxIsInsideYield = TRUE; - if (!g_isIdle) - { - // We need to remove idle callbacks or the loop will - // never finish. - gtk_idle_remove( m_idleTag ); - m_idleTag = 0; - g_isIdle = TRUE; - } + // We need to remove idle callbacks or the loop will + // never finish. + wxTheApp->RemoveIdleTag(); // disable log flushing from here because a call to wxYield() shouldn't // normally result in message boxes popping up &c @@ -180,8 +179,7 @@ void wxApp::WakeUpIdle() #endif // wxUSE_THREADS_ #endif // __WXGTK2__ - if (g_isIdle) - wxapp_install_idle_handler(); + wxapp_install_idle_handler(); #ifndef __WXGTK20__ #if wxUSE_THREADS @@ -211,7 +209,12 @@ static gint wxapp_pending_callback( gpointer WXUNUSED(data) ) // Sent idle event to all who request them. wxTheApp->ProcessPendingEvents(); - g_pendingTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_pendingTag = 0; + } // Flush the logged messages if any. #if wxUSE_LOG @@ -259,8 +262,13 @@ static gint wxapp_idle_callback( gpointer WXUNUSED(data) ) // Indicate that we are now in idle mode and event handlers // will have to reinstall the idle handler again. - g_isIdle = TRUE; - wxTheApp->m_idleTag = 0; + { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + g_isIdle = TRUE; + wxTheApp->m_idleTag = 0; + } // Send idle event to all who request them as long as // no events have popped up in the event queue. @@ -368,6 +376,15 @@ static gint wxapp_poll_func( GPollFD *ufds, guint nfds, gint timeout ) void wxapp_install_idle_handler() { +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + + // Don't install the handler if it's already installed. This test *MUST* + // be done when gs_idleTagsMutex is locked! + if (!g_isIdle) + return; + // GD: this assert is raised when using the thread sample (which works) // so the test is probably not so easy. Can widget callbacks be // triggered from child threads and, if so, for which widgets? @@ -419,6 +436,7 @@ wxApp::wxApp() #endif // __WXDEBUG__ m_idleTag = 0; + g_isIdle = TRUE; wxapp_install_idle_handler(); #if wxUSE_THREADS @@ -679,3 +697,15 @@ void wxApp::OnAssert(const wxChar *file, int line, const wxChar* cond, const wxC #endif // __WXDEBUG__ +void wxApp::RemoveIdleTag() +{ +#if wxUSE_THREADS + wxMutexLocker lock(gs_idleTagsMutex); +#endif + if (!g_isIdle) + { + gtk_idle_remove( wxTheApp->m_idleTag ); + wxTheApp->m_idleTag = 0; + g_isIdle = TRUE; + } +}