]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/app.cpp
fixed (rare but fatal) bug in wxWindowDisabler
[wxWidgets.git] / src / gtk1 / app.cpp
index 115d743eae8e864d275c1a44e6462b25757e74d2..7b9962d1651be3a949b4264f1fbed4aa2f8ff4d0 100644 (file)
@@ -51,6 +51,8 @@ extern bool g_isIdle;
 
 bool g_mainThreadLocked = FALSE;
 
 
 bool g_mainThreadLocked = FALSE;
 
+GtkWidget *wxRootWindow = (GtkWidget*) NULL;
+
 //-----------------------------------------------------------------------------
 // local functions
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // local functions
 //-----------------------------------------------------------------------------
@@ -91,16 +93,24 @@ bool wxYield()
     while (gtk_events_pending())
         gtk_main_iteration();
 
     while (gtk_events_pending())
         gtk_main_iteration();
 
+    if (has_idle)
+    {
+        /* re-add idle handler (very low priority) */
+        wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
+    }
+
+    // disable log flushing from here because a call to wxYield() shouldn't
+    // normally result in message boxes popping up &c
+    wxLog::Suspend();
+
     /* it's necessary to call ProcessIdle() to update the frames sizes which
        might have been changed (it also will update other things set from
        OnUpdateUI() which is a nice (and desired) side effect) */
     /* it's necessary to call ProcessIdle() to update the frames sizes which
        might have been changed (it also will update other things set from
        OnUpdateUI() which is a nice (and desired) side effect) */
-    while (wxTheApp->ProcessIdle()) { }
+    while (wxTheApp->ProcessIdle())
+        ;
 
 
-    if (has_idle)
-    {
-        /* re-add idle handler */
-        wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
-    }
+    // let the logs be flashed again
+    wxLog::Resume();
 
     return TRUE;
 }
 
     return TRUE;
 }
@@ -116,9 +126,9 @@ void wxWakeUpIdle()
         wxMutexGuiEnter();
 #endif
 
         wxMutexGuiEnter();
 #endif
 
-    if (g_isIdle) 
+    if (g_isIdle)
         wxapp_install_idle_handler();
         wxapp_install_idle_handler();
-    
+
 #if wxUSE_THREADS
     if (!wxThread::IsMain())
         wxMutexGuiLeave();
 #if wxUSE_THREADS
     if (!wxThread::IsMain())
         wxMutexGuiLeave();
@@ -138,9 +148,6 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
     // thread so we must lock it here ourselves
     gdk_threads_enter();
 
     // thread so we must lock it here ourselves
     gdk_threads_enter();
 
-    /* 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 );
     /* we don't want any more idle events until the next event is
        sent to wxGTK */
     gtk_idle_remove( wxTheApp->m_idleTag );
@@ -153,6 +160,9 @@ gint wxapp_idle_callback( gpointer WXUNUSED(data) )
        emptied */
     g_isIdle = TRUE;
 
        emptied */
     g_isIdle = TRUE;
 
+    /* sent idle event to all who request them */
+    while (wxTheApp->ProcessIdle()) { }
+
     // release lock again
     gdk_threads_leave();
 
     // release lock again
     gdk_threads_leave();
 
@@ -167,9 +177,9 @@ void wxapp_install_idle_handler()
        indicating that the idle is over. It may also
        get called from other thread for sending events
        to the main thread (and processing these in
        indicating that the idle is over. It may also
        get called from other thread for sending events
        to the main thread (and processing these in
-       idle time). */
+       idle time). Very low priority. */
 
 
-    wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL );
+    wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL );
 
     g_isIdle = FALSE;
 }
 
     g_isIdle = FALSE;
 }
@@ -202,7 +212,7 @@ gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
 
     // unblock other threads wishing to do some GUI things
     wxMutexGuiLeave();
 
     // unblock other threads wishing to do some GUI things
     wxMutexGuiLeave();
-    
+
     g_mainThreadLocked = TRUE;
 
     // wake up other threads
     g_mainThreadLocked = TRUE;
 
     // wake up other threads
@@ -217,7 +227,7 @@ gint wxapp_wakeup_timerout_callback( gpointer WXUNUSED(data) )
 
     // release lock again
     gdk_threads_leave();
 
     // release lock again
     gdk_threads_leave();
-    
+
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -248,6 +258,8 @@ wxApp::wxApp()
 #endif
 
     m_colorCube = (unsigned char*) NULL;
 #endif
 
     m_colorCube = (unsigned char*) NULL;
+
+    m_useBestVisual = FALSE;
 }
 
 wxApp::~wxApp()
 }
 
 wxApp::~wxApp()
@@ -268,8 +280,9 @@ bool wxApp::OnInitGui()
     /* on some machines, the default visual is just 256 colours, so
        we make sure we get the best. this can sometimes be wasteful,
        of course, but what do these guys pay $30.000 for? */
     /* on some machines, the default visual is just 256 colours, so
        we make sure we get the best. this can sometimes be wasteful,
        of course, but what do these guys pay $30.000 for? */
-/*
-    if (gdk_visual_get_best() != gdk_visual_get_system())
+
+    if ((gdk_visual_get_best() != gdk_visual_get_system()) &&
+        (m_useBestVisual))
     {
         GdkVisual* vis = gdk_visual_get_best();
         gtk_widget_set_default_visual( vis );
     {
         GdkVisual* vis = gdk_visual_get_best();
         gtk_widget_set_default_visual( vis );
@@ -279,7 +292,6 @@ bool wxApp::OnInitGui()
 
         visual = vis;
     }
 
         visual = vis;
     }
-*/
 
     /* Nothing to do for 15, 16, 24, 32 bit displays */
     if (visual->depth > 8) return TRUE;
 
     /* Nothing to do for 15, 16, 24, 32 bit displays */
     if (visual->depth > 8) return TRUE;
@@ -366,13 +378,6 @@ void wxApp::OnIdle( wxIdleEvent &event )
     /* 'Garbage' collection of windows deleted with Close(). */
     DeletePendingObjects();
 
     /* 'Garbage' collection of windows deleted with Close(). */
     DeletePendingObjects();
 
-    /* flush the logged messages if any */
-#if wxUSE_LOG
-    wxLog *log = wxLog::GetActiveTarget();
-    if (log != NULL && log->HasPendingMessages())
-        log->Flush();
-#endif // wxUSE_LOG
-
     /* Send OnIdle events to all windows */
     bool needMore = SendIdleEvents();
 
     /* Send OnIdle events to all windows */
     bool needMore = SendIdleEvents();
 
@@ -380,6 +385,11 @@ void wxApp::OnIdle( wxIdleEvent &event )
         event.RequestMore(TRUE);
 
     s_inOnIdle = FALSE;
         event.RequestMore(TRUE);
 
     s_inOnIdle = FALSE;
+
+    /* flush the logged messages if any */
+#if wxUSE_LOG
+    wxLog::FlushActive();
+#endif // wxUSE_LOG
 }
 
 bool wxApp::SendIdleEvents()
 }
 
 bool wxApp::SendIdleEvents()
@@ -508,7 +518,7 @@ void wxApp::CleanUp()
 
     if (wxTheColourDatabase)
         delete wxTheColourDatabase;
 
     if (wxTheColourDatabase)
         delete wxTheColourDatabase;
-        
+
     wxTheColourDatabase = (wxColourDatabase*) NULL;
 
     wxDeleteStockObjects();
     wxTheColourDatabase = (wxColourDatabase*) NULL;
 
     wxDeleteStockObjects();
@@ -555,22 +565,23 @@ void wxApp::CleanUp()
 // wxEntry
 //-----------------------------------------------------------------------------
 
 // wxEntry
 //-----------------------------------------------------------------------------
 
-int wxEntry( int argc, char *argv[] )
+
+int wxEntryStart( int argc, char *argv[] )
 {
 #if wxUSE_THREADS
     /* GTK 1.2 up to version 1.2.3 has broken threads */
     if ((gtk_major_version == 1) &&
         (gtk_minor_version == 2) &&
 {
 #if wxUSE_THREADS
     /* GTK 1.2 up to version 1.2.3 has broken threads */
     if ((gtk_major_version == 1) &&
         (gtk_minor_version == 2) &&
-           (gtk_micro_version < 4))
+        (gtk_micro_version < 4))
     {
     {
-        printf( "wxWindows warning: Disabled GUI threading due to outdated GTK version\n" );
+        printf( "wxWindows warning: GUI threading disabled due to outdated GTK version\n" );
     }
     else
     {
         g_thread_init(NULL);
     }
 #endif
     }
     else
     {
         g_thread_init(NULL);
     }
 #endif
-    
+
     gtk_set_locale();
 
 #if wxUSE_WCHAR_T
     gtk_set_locale();
 
 #if wxUSE_WCHAR_T
@@ -591,6 +602,55 @@ int wxEntry( int argc, char *argv[] )
         return -1;
     }
 
         return -1;
     }
 
+    return 0;
+}
+
+
+int wxEntryInitGui()
+{
+    int retValue = 0;
+
+    if ( !wxTheApp->OnInitGui() )
+        retValue = -1;
+
+    wxRootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+    gtk_widget_realize( wxRootWindow );
+
+    return retValue;
+}
+
+
+void wxEntryCleanup()
+{
+#if wxUSE_LOG
+    // flush the logged messages if any
+    wxLog *log = wxLog::GetActiveTarget();
+    if (log != NULL && log->HasPendingMessages())
+        log->Flush();
+
+    // continuing to use user defined log target is unsafe from now on because
+    // some resources may be already unavailable, so replace it by something
+    // more safe
+    wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
+    if ( oldlog )
+        delete oldlog;
+#endif // wxUSE_LOG
+
+    wxApp::CleanUp();
+
+    gdk_threads_leave();
+}
+
+
+
+int wxEntry( int argc, char *argv[] )
+{
+    int err;
+
+    err = wxEntryStart(argc, argv);
+    if (err)
+        return err;
+
     if (!wxTheApp)
     {
         wxCHECK_MSG( wxApp::GetInitializerFunction(), -1,
     if (!wxTheApp)
     {
         wxCHECK_MSG( wxApp::GetInitializerFunction(), -1,
@@ -609,7 +669,7 @@ int wxEntry( int argc, char *argv[] )
 #if wxUSE_UNICODE
     wxTheApp->argv = new wxChar*[argc+1];
     int mb_argc = 0;
 #if wxUSE_UNICODE
     wxTheApp->argv = new wxChar*[argc+1];
     int mb_argc = 0;
-    while (mb_argc < argc) 
+    while (mb_argc < argc)
     {
         wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
         mb_argc++;
     {
         wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
         mb_argc++;
@@ -623,10 +683,8 @@ int wxEntry( int argc, char *argv[] )
     wxStripExtension( name );
     wxTheApp->SetAppName( name );
 
     wxStripExtension( name );
     wxTheApp->SetAppName( name );
 
-    int retValue = 0;
-
-    if ( !wxTheApp->OnInitGui() )
-        retValue = -1;
+    int retValue;
+    retValue = wxEntryInitGui();
 
     // Here frames insert themselves automatically into wxTopLevelWindows by
     // getting created in OnInit().
 
     // Here frames insert themselves automatically into wxTopLevelWindows by
     // getting created in OnInit().
@@ -647,7 +705,7 @@ int wxEntry( int argc, char *argv[] )
 
         if (wxTheApp->Initialized())
         {
 
         if (wxTheApp->Initialized())
         {
-            retValue = wxTheApp->OnRun();
+            wxTheApp->OnRun();
 
             wxWindow *topWindow = wxTheApp->GetTopWindow();
             if (topWindow)
 
             wxWindow *topWindow = wxTheApp->GetTopWindow();
             if (topWindow)
@@ -665,27 +723,12 @@ int wxEntry( int argc, char *argv[] )
                     wxTheApp->SetTopWindow( (wxWindow*) NULL );
                 }
             }
                     wxTheApp->SetTopWindow( (wxWindow*) NULL );
                 }
             }
-            wxTheApp->OnExit();
+
+            retValue = wxTheApp->OnExit();
         }
     }
 
         }
     }
 
-#if wxUSE_LOG
-    // flush the logged messages if any
-    wxLog *log = wxLog::GetActiveTarget();
-    if (log != NULL && log->HasPendingMessages())
-        log->Flush();
-
-    // continuing to use user defined log target is unsafe from now on because
-    // some resources may be already unavailable, so replace it by something
-    // more safe
-    wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
-    if ( oldlog )
-        delete oldlog;
-#endif // wxUSE_LOG
-
-    wxApp::CleanUp();
-
-    gdk_threads_leave();
+    wxEntryCleanup();
 
     return retValue;
 }
 
     return retValue;
 }