diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index b89c70bcb0..29f808f80d 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -59,11 +59,18 @@ public: static bool GTKIsUsingGlobalMenu(); // Provide the ability to suppress GTK output. By default, all output - // will be suppressed, but the user can pass in a mask specifiyng the + // will be suppressed, but the user can pass in a mask specifying the // types of messages to suppress. Flags are defined by glib with the // GLogLevelFlags enum. static void GTKSuppressDiagnostics(int flags = -1); + // Allow wxWidgets to control GTK diagnostics. This is recommended because + // it prevents spurious GTK messages from appearing, but can't be done by + // default because it would result in a fatal error if the application + // calls g_log_set_writer_func() itself. + static void GTKAllowDiagnosticsControl(); + + // implementation only from now on // ------------------------------- diff --git a/include/wx/gtk/private/log.h b/include/wx/gtk/private/log.h index 15ab0ee0c2..e54677b7c9 100644 --- a/include/wx/gtk/private/log.h +++ b/include/wx/gtk/private/log.h @@ -33,7 +33,14 @@ public: m_next = NULL; } - // Function to call to install this filter as the active one. + // Allow installing our own log writer function, we don't do it by default + // because this results in a fatal error if the application had already + // called g_log_set_writer_func() on its own. + static void Allow() { ms_allowed = true; } + + // Function to call to install this filter as the active one if we're + // allowed to do this, i.e. if Allow() had been called before. + // // Does nothing and just returns false if run-time glib version is too old. bool Install(); @@ -56,6 +63,10 @@ private: gsize n_fields, gpointer user_data); + // False initially, indicating that we're not allowed to install our own + // logging function. + static bool ms_allowed; + // False initially, set to true when we install wx_log_writer() as the log // writer. Once we do it, we never change it any more. static bool ms_installed; diff --git a/interface/wx/app.h b/interface/wx/app.h index 26077c231b..3f264ec3d8 100644 --- a/interface/wx/app.h +++ b/interface/wx/app.h @@ -1061,6 +1061,25 @@ public: */ static void GTKSuppressDiagnostics(int flags = -1); + /** + Allows wxWidgets to selectively suppress some GTK messages. + + This function can be called to allow wxWidgets to control GTK message + logging. You must @e not call it if your application calls the @c + g_log_set_writer_func() function itself, as this function can be only + called once. + + It is recommended to call this function in your overridden version of + wxApp::OnInit() to allow wxWidgets to suppress some spurious GTK error + messages, e.g. the ones that happen whenever wxNotebook pages are + removed with the current GTK versions. + + @onlyfor{wxgtk} + + @since 3.2.1 + */ + static void GTKAllowDiagnosticsControl(); + ///@} /** diff --git a/interface/wx/notebook.h b/interface/wx/notebook.h index 34fb0e7968..25b75f25a9 100644 --- a/interface/wx/notebook.h +++ b/interface/wx/notebook.h @@ -145,6 +145,10 @@ public: /** Destroys the wxNotebook object. + + @note When using wxGTK, destroying notebook can result in spurious GTK + diagnostic messages, you may use wxApp::GTKAllowDiagnosticsControl() to + suppress them. */ virtual ~wxNotebook(); diff --git a/samples/notebook/notebook.cpp b/samples/notebook/notebook.cpp index e4eb4c9bb3..5b029bae30 100644 --- a/samples/notebook/notebook.cpp +++ b/samples/notebook/notebook.cpp @@ -37,6 +37,13 @@ bool MyApp::OnInit() if ( !wxApp::OnInit() ) return false; +#ifdef __WXGTK__ + // Many version of wxGTK generate spurious diagnostic messages when + // destroying wxNotebook (or removing pages from it), allow wxWidgets to + // suppress them. + GTKAllowDiagnosticsControl(); +#endif // __WXGTK__ + #if wxUSE_HELP wxHelpProvider::Set( new wxSimpleHelpProvider ); #endif @@ -329,7 +336,7 @@ MyFrame::MyFrame() #endif menuType->AppendRadioItem(ID_BOOK_SIMPLEBOOK, "&Simple book\tCtrl-7"); - menuType->Check(ID_BOOK_NOTEBOOK + m_type, true); + menuType->Check(static_cast(ID_BOOK_NOTEBOOK) + m_type, true); wxMenu *menuOrient = new wxMenu; menuOrient->AppendRadioItem(ID_ORIENT_DEFAULT, "&Default\tAlt-0"); diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 4e8bd2926c..31c6c5905b 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -184,6 +184,7 @@ bool wxApp::DoIdle() namespace wxGTKImpl { +bool LogFilter::ms_allowed = false; bool LogFilter::ms_installed = false; LogFilter* LogFilter::ms_first = NULL; @@ -205,6 +206,9 @@ LogFilter::wx_log_writer(GLogLevelFlags log_level, bool LogFilter::Install() { + if ( !ms_allowed ) + return false; + if ( !ms_installed ) { if ( glib_check_version(2, 50, 0) != 0 ) @@ -278,12 +282,24 @@ void wxApp::GTKSuppressDiagnostics(int flags) s_logFilter.SetLevelToIgnore(flags); s_logFilter.Install(); } + +/* static */ +void wxApp::GTKAllowDiagnosticsControl() +{ + wxGTKImpl::LogFilter::Allow(); +} #else // !wxHAS_GLIB_LOG_WRITER /* static */ void wxApp::GTKSuppressDiagnostics(int WXUNUSED(flags)) { // We can't do anything here. } + +/* static */ +void wxApp::GTKAllowDiagnosticsControl() +{ + // And don't need to do anything here. +} #endif // wxHAS_GLIB_LOG_WRITER/!wxHAS_GLIB_LOG_WRITER //-----------------------------------------------------------------------------