[gimp] libgimp: sink the floating references after adding them to hash table.



commit e1a489a43af3b35e532581c4e048e70fc063f11d
Author: Jehan <jehan girinstud io>
Date:   Tue Apr 20 17:08:31 2021 +0200

    libgimp: sink the floating references after adding them to hash table.
    
    Though the previous implementation worked fine on C plug-ins, I realized
    it was problematic on bindings. In particular, the Python binding at
    least was somehow freeing returned floating objects, unless assigned to
    a variable.
    For instance, the widget returned by the following code:
    
    > dialog.get_color_widget('color', True, GimpUi.ColorAreaType.FLAT)
    
    … was freed by the PyGObject binding when it was floating, even though
    (transfer none) was set (hence telling the binding it should not free
    the returned object). The workaround was to assign it to some variable,
    even though I was not planning to use it.
    Making sure all references are full fixes it.
    
    GObject docs also notes:
    
    > **Note**: Floating references are a C convenience API and should not
    > be used in modern GObject code. Language bindings in particular find
    > the concept highly problematic, as floating references are not
    > identifiable through annotations, and neither are deviations from the
    > floating reference behavior, like types that inherit from
    > GInitiallyUnowned and still return a full reference from
    > g_object_new().

 libgimp/gimpproceduredialog.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
---
diff --git a/libgimp/gimpproceduredialog.c b/libgimp/gimpproceduredialog.c
index cf5b12225a..187e30616b 100644
--- a/libgimp/gimpproceduredialog.c
+++ b/libgimp/gimpproceduredialog.c
@@ -627,6 +627,8 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
 
   gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
+  if (g_object_is_floating (widget))
+    g_object_ref_sink (widget);
 
   return widget;
 }
@@ -707,6 +709,8 @@ gimp_procedure_dialog_get_color_widget (GimpProcedureDialog *dialog,
 
   gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
+  if (g_object_is_floating (widget))
+    g_object_ref_sink (widget);
 
   return widget;
 }
@@ -782,6 +786,8 @@ gimp_procedure_dialog_get_int_combo (GimpProcedureDialog *dialog,
 
   gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
+  if (g_object_is_floating (widget))
+    g_object_ref_sink (widget);
 
   return widget;
 }
@@ -847,6 +853,8 @@ gimp_procedure_dialog_get_scale_entry (GimpProcedureDialog *dialog,
 
   gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
+  if (g_object_is_floating (widget))
+    g_object_ref_sink (widget);
 
   return widget;
 }
@@ -896,6 +904,8 @@ gimp_procedure_dialog_get_label (GimpProcedureDialog *dialog,
 
   label = gtk_label_new (text);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (label_id), label);
+  if (g_object_is_floating (label))
+    g_object_ref_sink (label);
 
   return label;
 }
@@ -1299,6 +1309,8 @@ gimp_procedure_dialog_fill_frame (GimpProcedureDialog *dialog,
     }
 
   g_hash_table_insert (dialog->priv->widgets, g_strdup (container_id), frame);
+  if (g_object_is_floating (frame))
+    g_object_ref_sink (frame);
 
   return frame;
 }
@@ -1694,6 +1706,8 @@ gimp_procedure_dialog_fill_container_list (GimpProcedureDialog *dialog,
     g_list_free (properties);
 
   g_hash_table_insert (dialog->priv->widgets, g_strdup (container_id), container);
+  if (g_object_is_floating (container))
+    g_object_ref_sink (container);
 
   return GTK_WIDGET (container);
 }


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