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

Re: custom cell renderer start_editing refcount



Torsten Schoenfeld <kaffeetisch gmx de> writes:
>
> The pre-2.10 branch would need to use GTK_OBJECT_FLOATING
> and GTK_OBJECT_FLAGS, I think.

Maybe something like below.  I think it compiles, but does someone have
an old enough gtk setup to try the test program?

> A unit test would be great.

Unit testing means it compiles doesn't it?  Integration testing is if it
links too. :)

Actually I don't know really how to programmatically make TreeView or
IconView start editing then stop editing, as normally done by mouse
clicks of course.  A forced focus change to stop editing might be ok, or
maybe running $entry->activate, but I don't have a good idea for a
realistic start editing.



What about the newSVGtkCellEditable macro?  Since a GtkCellEditable
interface requires GtkWidget I'd think maybe it should wrap the same as
other widgets, ie. it should be gtk2perl_new_gtkobject() instead of the
current gperl_new_object(...,FALSE), the difference of course being the
latter doesn't sink a floating ref.

Something like $renderer->start_editing from say an ordinary
Gtk2::CellRendererText comes back with a floating ref to be taken over.
I don't think there's any outright bug, since any viewer widget will add
it as a container child, sinking the ref at that point.  But leaving a
floating ref kicking around is not normal is it?


Index: GtkCellRenderer.xs
===================================================================
--- GtkCellRenderer.xs	(revision 2095)
+++ GtkCellRenderer.xs	(working copy)
@@ -272,22 +272,58 @@
 		sv = POPs;
 		if (gperl_sv_is_defined (sv)) {
 			editable = SvGtkCellEditable (sv);
-			/* if the object returned here was newly created by
-			 * the called code, then the wrapper (pointed to by
-			 * sv) is the owner of the object.  if there are no
-			 * other references to the wrapper, the call to
-			 * FREETMPS below will actually result in finalization
-			 * of the GObject, which means we'll return a bad
-			 * pointer to our caller.  to prevent this situation,
-			 * we need to add a ref to the wrapper (that is, the
-			 * blessed sv stored in the GObject, not the reference
-			 * sv) to keep it alive across FREETMPS and thus
-			 * prevent premature destruction.
+
+#if GLIB_CHECK_VERSION (2, 10, 0)
+			/* (*start_editing)() is basically a constructor and
+			 * as such should return an object with a floating
+			 * reference for the caller to take over.
+			 *
+			 * For GtkTreeView and GtkIconView for example that
+			 * ref is sunk when gtk_tree_view_put() or
+			 * gtk_icon_view_put() call gtk_widget_set_parent()
+			 * to add "editable" as one of their container
+			 * children.  (Eventually to be dereffed in the
+			 * usual way by gtk_container_remove() from
+			 * gtk_tree_view_remove_widget() or
+			 * gtk_icon_view_remove_widget() at the end of
+			 * editing.)
+			 *
+			 * Perl code constructors like Gtk2::Foo->new or
+			 * Glib::Object->new sink any initial floating
+			 * reference when making the wrapper (either if
+			 * constructing in the START_EDITING code or from
+			 * something made or wrapped previously).  So must
+			 * explicitly add a floating ref for GtkTreeView etc
+			 * to take over.
+			 *
+			 * If START_EDITING code gives a new object in "sv"
+			 * and it's used nowhere else then FREETMPS below
+			 * will SvREFCNT_dec it to zero and send it to the
+			 * usual Glib::Object::DESTROY.  If there wasn't a
+			 * floating ref added here on the GObject then that
+			 * GObject would be destroyed before we ever got to
+			 * return it.  With the extra floating ref the
+			 * wrapper converts to undead (ie. unused from perl
+			 * for the time being) and the GObject has a
+			 * refcount of 1 and the floating flag set.
+			 *
+			 * It's conceivable there could be a floating ref
+			 * already at this point.  That was the case in the
+			 * past from chained-up perl SUPER::START_EDITING
+			 * for instance.  Though it's abnormal let's assume
+			 * any floating ref here is meant for the caller to
+			 * take over and therefore should be left unchanged.
 			 */
-			if (G_OBJECT (editable)->ref_count == 1 &&
-			    SvREFCNT (SvRV (sv)) == 1) {
-				SvREFCNT_inc (SvRV (sv));
+			if (! g_object_is_floating (editable)) {
+				g_object_ref (editable);
+				g_object_force_floating (G_OBJECT (editable));
 			}
+#else
+			if (! GTK_OBJECT_FLOATING (editable)) {
+				gtk_object_ref (GTK_OBJECT (editable));
+				GTK_OBJECT_SET_FLAGS (editable, GTK_FLOATING);
+			}
+#endif
 		} else {
 			editable = NULL;
 		}

-- 
The most important thing when cooking with fish is freshness, so I
always make sure to use seafood extender within an hour of thawing it.


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