diff --git a/docs/changes.txt b/docs/changes.txt index 209877a204..2e3abd9c7e 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -246,6 +246,7 @@ All (GUI): wxGTK: +- Fix crash with wxNotebook and g_log_set_writer_func() in glibc 2.73+ (#22717). - Fix build with --disable-intl (#22626). - Fix build under MSW (Tim Stahlhut, #22633). - Fix CMake build under NetBSD (Thomas Klausner, #22643, #22644, #22645). diff --git a/include/wx/gtk/app.h b/include/wx/gtk/app.h index d2847e63e4..a14ff74c5a 100644 --- a/include/wx/gtk/app.h +++ b/include/wx/gtk/app.h @@ -64,6 +64,15 @@ public: // GLogLevelFlags enum. static void GTKSuppressDiagnostics(int flags = -1); +#if wxABI_VERSION >= 30201 + // 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(); +#endif // wxABI_VERSION >= 3.2.1 + + // 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 3ebdb6fb02..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 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 //----------------------------------------------------------------------------- diff --git a/version-script.in b/version-script.in index 4e1d9d9205..8ceb11d5fd 100644 --- a/version-script.in +++ b/version-script.in @@ -26,6 +26,7 @@ # public symbols added in 3.2.1 (please keep in alphabetical order): @WX_VERSION_TAG@.1 { extern "C++" { + "wxApp::GTKAllowDiagnosticsControl()"; "wxFileDialog::AddShortcut(const wxString&, int)"; }; };