X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9cc7a35d9c1a054a8f88dcf7b51347e95f4a2557..c127177f8dc31dbe99764852b8dbcc047d3ad826:/src/gtk/app.cpp diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 5c08aad9d6..d70f078447 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -51,6 +51,7 @@ extern wxList *wxPendingEvents; extern wxCriticalSection *wxPendingEventsLocker; #endif extern wxResourceCache *wxTheResourceCache; +extern bool g_isIdle; unsigned char g_palette[64*3] = { @@ -135,7 +136,7 @@ void wxExit() gtk_main_quit(); } -// forward decl +/* forward declaration */ gint wxapp_idle_callback( gpointer WXUNUSED(data) ); bool wxYield() @@ -151,15 +152,63 @@ bool wxYield() win->OnInternalIdle(); } - // We need to temporarily remove idle callbacks or the loop will - // never finish. + if (wxTheApp->m_idleTag) + { + /* We need to temporarily remove idle callbacks or the loop will + never finish. */ + gtk_idle_remove( wxTheApp->m_idleTag ); + wxTheApp->m_idleTag = 0; + + while (gtk_events_pending()) + gtk_main_iteration(); + + /* re-add idle handler */ + wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + } + else + { + while (gtk_events_pending()) + gtk_main_iteration(); + } + + return TRUE; +} + +gint wxapp_idle_callback( gpointer WXUNUSED(data) ) +{ + if (!wxTheApp) return TRUE; + + /* sent idle event to all who request them */ + while (wxTheApp->ProcessIdle()) { } + + /* we don't want any more idle events until the next event is + sent to wxGTK */ gtk_idle_remove( wxTheApp->m_idleTag ); + wxTheApp->m_idleTag = 0; + + /* indicate that we are now in idle mode - even so deeply + in idle mode that we don't get any idle events anymore. + this is like wxMSW where an idle event is sent only + once each time after the event queue has been completely + emptied */ + g_isIdle = TRUE; + + /* wake up other threads */ + wxMutexGuiLeave(); + wxUsleep(0); + wxMutexGuiEnter(); + + return TRUE; +} - while (gtk_events_pending()) - gtk_main_iteration(); +void wxapp_install_idle_handler() +{ + /* this routine gets called by all event handlers + indicating that the idle is over. */ wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); - return TRUE; + + g_isIdle = FALSE; } //----------------------------------------------------------------------------- @@ -172,22 +221,6 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) EVT_IDLE(wxApp::OnIdle) END_EVENT_TABLE() -gint wxapp_idle_callback( gpointer WXUNUSED(data) ) -{ - if (wxTheApp) - { - while (wxTheApp->ProcessIdle()) - { - } - } - - wxMutexGuiLeave(); - wxUsleep(10); - wxMutexGuiEnter(); - - return TRUE; -} - wxApp::wxApp() { wxTheApp = this; @@ -202,7 +235,7 @@ wxApp::wxApp() wxApp::~wxApp() { - gtk_idle_remove( m_idleTag ); + if (m_idleTag) gtk_idle_remove( m_idleTag ); if (m_colorCube) free(m_colorCube); } @@ -255,14 +288,14 @@ bool wxApp::OnInitGui() int bb = (b << 3) | (b >> 2); GdkColor *colors = cmap->colors; - int max = 3 * (65536); + int max = 3 * 65536; int index = -1; for (int i = 0; i < cmap->size; i++) { int rdiff = ((rr << 8) - colors[i].red); - int gdiff = ((gg << 8)- colors[i].green); - int bdiff = ((bb << 8)- colors[i].blue); + int gdiff = ((gg << 8) - colors[i].green); + int bdiff = ((bb << 8) - colors[i].blue); int sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff); if (sum < max) { index = i; max = sum; } } @@ -272,7 +305,6 @@ bool wxApp::OnInitGui() } } - return TRUE; } @@ -378,7 +410,7 @@ bool wxApp::Initialized() bool wxApp::Pending() { - return gtk_events_pending(); + return (gtk_events_pending() > 0); } void wxApp::Dispatch() @@ -581,39 +613,45 @@ int wxEntry( int argc, char *argv[] ) wxStripExtension( name ); wxTheApp->SetAppName( name ); - if (!wxTheApp->OnInitGui()) - return 0; + int retValue = 0; + + if ( !wxTheApp->OnInitGui() ) + retValue = -1; // Here frames insert themselves automatically into wxTopLevelWindows by // getting created in OnInit(). - if (!wxTheApp->OnInit()) - return 0; - - wxTheApp->m_initialized = wxTopLevelWindows.GetCount() != 0; + if ( retValue == 0 ) + { + if ( !wxTheApp->OnInit() ) + retValue = -1; + } - int retValue = 0; + if ( retValue == 0 ) + { + wxTheApp->m_initialized = wxTopLevelWindows.GetCount() != 0; - if (wxTheApp->Initialized()) - retValue = wxTheApp->OnRun(); + if (wxTheApp->Initialized()) + retValue = wxTheApp->OnRun(); - wxWindow *topWindow = wxTheApp->GetTopWindow(); - if (topWindow) - { - // Forcibly delete the window. - if (topWindow->IsKindOf(CLASSINFO(wxFrame)) || - topWindow->IsKindOf(CLASSINFO(wxDialog)) ) - { - topWindow->Close( TRUE ); - wxTheApp->DeletePendingObjects(); - } - else + wxWindow *topWindow = wxTheApp->GetTopWindow(); + if (topWindow) { - delete topWindow; - wxTheApp->SetTopWindow( (wxWindow*) NULL ); + // Forcibly delete the window. + if (topWindow->IsKindOf(CLASSINFO(wxFrame)) || + topWindow->IsKindOf(CLASSINFO(wxDialog)) ) + { + topWindow->Close( TRUE ); + wxTheApp->DeletePendingObjects(); + } + else + { + delete topWindow; + wxTheApp->SetTopWindow( (wxWindow*) NULL ); + } } - } - wxTheApp->OnExit(); + wxTheApp->OnExit(); + } // flush the logged messages if any wxLog *log = wxLog::GetActiveTarget();