[gtkmm] Gtk::Object::_release_c_instance(): Unref orphan managed widgets



commit c87db9f67480b07cc5d32f3b3cf138b128fcd7c7
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Thu Apr 14 13:24:19 2022 +0200

    Gtk::Object::_release_c_instance(): Unref orphan managed widgets
    
    g_object_run_dispose() unrefs a widget only if it has a parent.
    Use g_object_unref() on all widgets without a parent.
    Fixes #115

 gtk/gtkmm/object.cc | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkmm/object.cc b/gtk/gtkmm/object.cc
index 548fbc0c..c5fb417b 100644
--- a/gtk/gtkmm/object.cc
+++ b/gtk/gtkmm/object.cc
@@ -20,7 +20,6 @@
 #include <glibmm/quark.h>
 #include <gtk/gtk.h>
 
-
 namespace Gtk
 {
 
@@ -93,13 +92,21 @@ void Object::_release_c_instance()
     g_assert(G_IS_OBJECT(object));
     bool prevent_creation_of_another_wrapper = true;
 
-    if(referenced_)
+    if (referenced_ || (GTK_IS_WIDGET(object) && !gtk_widget_get_parent(GTK_WIDGET(object))))
     {
-      //It's not manage()ed so we just unref to destroy it
+      // It's not manage()d or it's an orphan widget, so we just unref to destroy it.
       #ifdef GLIBMM_DEBUG_REFCOUNTING
       g_warning("final unref: gtypename: %s, refcount: %d\n", G_OBJECT_TYPE_NAME(object), 
((GObject*)object)->ref_count);
       #endif
 
+      if (!referenced_ && g_object_is_floating(object))
+      {
+        GLIBMM_DEBUG_REFERENCE(this, object);
+        // It's floating if it's a managed widget which is not stored in a container.
+        // GTK prints a warning if a widget with a floating ref is finalized.
+        g_object_ref_sink(object); // Stop it from being floating.
+      }
+
       GLIBMM_DEBUG_UNREFERENCE(this, object);
       g_object_unref(object);
 
@@ -125,6 +132,9 @@ void Object::_release_c_instance()
           // It can't be safely destroyed, unless you know which container it
           // was added to and remove it from there. That may or may not be its
           // immediate parent, returned by gtk_widget_get_parent().
+          // https://bugzilla.gnome.org/show_bug.cgi?id=773642, comments 20-22
+          // a.k.a. https://gitlab.gnome.org/GNOME/gtkmm/-/issues/13
+          // https://bugzilla.gnome.org/show_bug.cgi?id=786048, comment 5
           // Accept that another wrapper is possibly created if a signal
           // is emitted or a vfunc is called.
           // The widget will be destroyed, when the container widget is destroyed.
@@ -362,5 +372,4 @@ GType Object::get_base_type()
   return g_object_get_type();
 }
 
-
 } // namespace Gtk


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]