summaryrefslogtreecommitdiff
path: root/gtk/gtkwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkwidget.c')
-rw-r--r--gtk/gtkwidget.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 2b614a0295..686e52b181 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -150,6 +150,8 @@ struct _GtkWidgetPrivate
/* unused bits in our 32-bit block */
guint reserved : 10;
+ guint in_destruction : 1;
+
/* The widget's name. If the widget does not have a name
* (the name is NULL), then its name (as returned by
* "gtk_widget_get_name") is its class's name.
@@ -184,6 +186,7 @@ struct _GtkWidgetPrivate
};
enum {
+ DESTROY,
SHOW,
HIDE,
MAP,
@@ -513,8 +516,8 @@ gtk_widget_get_type (void)
NULL /* interface data */
};
- widget_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkWidget",
- &widget_info, G_TYPE_FLAG_ABSTRACT);
+ widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, "GtkWidget",
+ &widget_info, G_TYPE_FLAG_ABSTRACT);
g_type_add_interface_static (widget_type, ATK_TYPE_IMPLEMENTOR,
&accessibility_info) ;
@@ -1037,6 +1040,23 @@ gtk_widget_class_init (GtkWidgetClass *klass)
0,
GTK_PARAM_READWRITE));
+ /**
+ * GtkWidget::destroy:
+ * @object: the object which received the signal
+ *
+ * Signals that all holders of a reference to the widget should release
+ * the reference that they hold. May result in finalization of the widget
+ * if all references are released.
+ */
+ widget_signals[DESTROY] =
+ g_signal_new (I_("destroy"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (GtkWidgetClass, destroy),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
/**
* GtkWidget::show:
* @widget: the object which received the signal.
@@ -3432,8 +3452,9 @@ gtk_widget_unparent (GtkWidget *widget)
* gtk_widget_destroy:
* @widget: a #GtkWidget
*
- * Destroys a widget. Equivalent to gtk_object_destroy(), except that
- * you don't have to cast the widget to #GtkObject. When a widget is
+ * Destroys a widget.
+ *
+ * When a widget is
* destroyed, it will break any references it holds to other objects.
* If the widget is inside a container, the widget will be removed
* from the container. If the widget is a toplevel (derived from
@@ -3452,7 +3473,8 @@ gtk_widget_destroy (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
- gtk_object_destroy ((GtkObject*) widget);
+ if (!widget->priv->in_destruction)
+ g_object_run_dispose (G_OBJECT (widget));
}
/**
@@ -9344,7 +9366,14 @@ gtk_widget_dispose (GObject *object)
GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
if (gtk_widget_get_realized (widget))
gtk_widget_unrealize (widget);
-
+
+ if (!priv->in_destruction)
+ {
+ priv->in_destruction = TRUE;
+ g_signal_emit (object, widget_signals[DESTROY], 0);
+ priv->in_destruction = FALSE;
+ }
+
G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object);
}
@@ -9367,8 +9396,6 @@ gtk_widget_real_destroy (GtkObject *object)
g_object_unref (priv->style);
priv->style = gtk_widget_get_default_style ();
g_object_ref (priv->style);
-
- GTK_OBJECT_CLASS (gtk_widget_parent_class)->destroy (object);
}
static void
@@ -9394,6 +9421,12 @@ gtk_widget_finalize (GObject *object)
if (accessible)
g_object_unref (accessible);
+ if (g_object_is_floating (object))
+ g_warning ("A floating object was finalized. This means that someone\n"
+ "called g_object_unref() on an object that had only a floating\n"
+ "reference; the initial floating reference is not owned by anyone\n"
+ "and must be removed with g_object_ref_sink().");
+
G_OBJECT_CLASS (gtk_widget_parent_class)->finalize (object);
}