summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimm Bäder <mail@baedert.org>2017-10-29 16:10:12 +0100
committerTimm Bäder <mail@baedert.org>2017-10-29 17:24:12 +0100
commitff6cd8f75ea929e28e94c1ea295fe1c624d6f241 (patch)
tree460b7dd83169602a98b3c15b544d69d3a8f8affa
parent0be4166b89633218199be58540ed6498aeef6f98 (diff)
downloadgtk+-ff6cd8f75ea929e28e94c1ea295fe1c624d6f241.tar.gz
widget: Remove parent-set signal
When a widget unparents its child widget manually in finalize, this can lead to the parent-set signal being emitted for those child widgets. The parent already has a ref_count of 0 though, so it can't be used in a meaningful way. Specifically, emitting the signal will already try to ref the parent which prints a critical. Since GtkWidget already has a "parent" property, one can use its notify signal instead to get notified when the parent widget changes.
-rw-r--r--gtk/gtklistbox.c41
-rw-r--r--gtk/gtkmenuitem.c20
-rw-r--r--gtk/gtktoolitem.c18
-rw-r--r--gtk/gtkwidget.c23
-rw-r--r--gtk/gtkwidget.h4
5 files changed, 49 insertions, 57 deletions
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index a206dcdd1f..9acc954254 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -100,6 +100,8 @@ typedef struct
GtkSelectionMode selection_mode;
+ gulong adjustment_changed_id;
+ GtkWidget *scrollable_parent;
GtkAdjustment *adjustment;
gboolean activate_single_click;
@@ -217,8 +219,9 @@ static void gtk_list_box_move_cursor (GtkListBo
GtkMovementStep step,
gint count);
static void gtk_list_box_finalize (GObject *obj);
-static void gtk_list_box_parent_set (GtkWidget *widget,
- GtkWidget *prev_parent);
+static void gtk_list_box_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
static void gtk_list_box_select_row_internal (GtkListBox *box,
GtkListBoxRow *row);
static void gtk_list_box_unselect_row_internal (GtkListBox *box,
@@ -378,7 +381,6 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
widget_class->measure = gtk_list_box_measure;
widget_class->size_allocate = gtk_list_box_size_allocate;
widget_class->drag_leave = gtk_list_box_drag_leave;
- widget_class->parent_set = gtk_list_box_parent_set;
container_class->add = gtk_list_box_add;
container_class->remove = gtk_list_box_remove;
container_class->forall = gtk_list_box_forall;
@@ -597,6 +599,9 @@ gtk_list_box_init (GtkListBox *box)
G_CALLBACK (gtk_list_box_multipress_gesture_pressed), box);
g_signal_connect (priv->multipress_gesture, "released",
G_CALLBACK (gtk_list_box_multipress_gesture_released), box);
+
+
+ g_signal_connect (box, "notify::parent", G_CALLBACK (gtk_list_box_parent_cb), NULL);
}
/**
@@ -977,25 +982,35 @@ adjustment_changed (GObject *object,
}
static void
-gtk_list_box_parent_set (GtkWidget *widget,
- GtkWidget *prev_parent)
+gtk_list_box_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
{
+ GtkListBoxPrivate *priv = BOX_PRIV (object);
GtkWidget *parent;
- parent = gtk_widget_get_parent (widget);
+ parent = gtk_widget_get_parent (GTK_WIDGET (object));
- if (prev_parent && GTK_IS_SCROLLABLE (prev_parent))
- g_signal_handlers_disconnect_by_func (prev_parent,
- G_CALLBACK (adjustment_changed), widget);
+ if (priv->adjustment_changed_id != 0 &&
+ priv->scrollable_parent != NULL)
+ {
+ g_signal_handler_disconnect (priv->scrollable_parent,
+ priv->adjustment_changed_id);
+ }
if (parent && GTK_IS_SCROLLABLE (parent))
{
- adjustment_changed (G_OBJECT (parent), NULL, widget);
- g_signal_connect (parent, "notify::vadjustment",
- G_CALLBACK (adjustment_changed), widget);
+ adjustment_changed (G_OBJECT (parent), NULL, object);
+ priv->scrollable_parent = parent;
+ priv->adjustment_changed_id = g_signal_connect (parent, "notify::vadjustment",
+ G_CALLBACK (adjustment_changed), object);
}
else
- gtk_list_box_set_adjustment (GTK_LIST_BOX (widget), NULL);
+ {
+ gtk_list_box_set_adjustment (GTK_LIST_BOX (object), NULL);
+ priv->adjustment_changed_id = 0;
+ priv->scrollable_parent = NULL;
+ }
}
/**
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index 0c98806f46..d9ef5bb7c5 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -140,8 +140,9 @@ static gboolean gtk_menu_item_enter (GtkWidget *widget,
GdkEventCrossing *event);
static gboolean gtk_menu_item_leave (GtkWidget *widget,
GdkEventCrossing *event);
-static void gtk_menu_item_parent_set (GtkWidget *widget,
- GtkWidget *previous_parent);
+static void gtk_menu_item_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
static void gtk_menu_item_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir);
@@ -510,7 +511,6 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
widget_class->enter_notify_event = gtk_menu_item_enter;
widget_class->leave_notify_event = gtk_menu_item_leave;
widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
- widget_class->parent_set = gtk_menu_item_parent_set;
widget_class->can_activate_accel = gtk_menu_item_can_activate_accel;
widget_class->measure = gtk_menu_item_measure;
widget_class->direction_changed = gtk_menu_item_direction_changed;
@@ -678,6 +678,8 @@ gtk_menu_item_init (GtkMenuItem *menu_item)
gtk_widget_set_has_window (GTK_WIDGET (menu_item), FALSE);
+ g_signal_connect (menu_item, "notify::parent", G_CALLBACK (gtk_menu_item_parent_cb), NULL);
+
priv->submenu = NULL;
priv->toggle_size = 0;
priv->accelerator_width = 0;
@@ -1627,14 +1629,15 @@ gtk_menu_item_accel_name_foreach (GtkWidget *widget,
}
static void
-gtk_menu_item_parent_set (GtkWidget *widget,
- GtkWidget *previous_parent)
+gtk_menu_item_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
+ GtkMenuItem *menu_item = GTK_MENU_ITEM (object);
GtkMenu *menu;
GtkWidget *parent;
- parent = gtk_widget_get_parent (widget);
+ parent = gtk_widget_get_parent (GTK_WIDGET (object));
menu = GTK_IS_MENU (parent) ? GTK_MENU (parent) : NULL;
if (menu)
@@ -1644,9 +1647,6 @@ gtk_menu_item_parent_set (GtkWidget *widget,
TRUE);
update_arrow_widget (menu_item);
-
- if (GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set)
- GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->parent_set (widget, previous_parent);
}
static void
diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c
index c8092473e2..03ce5b88f2 100644
--- a/gtk/gtktoolitem.c
+++ b/gtk/gtktoolitem.c
@@ -87,8 +87,9 @@ struct _GtkToolItemPrivate
};
static void gtk_tool_item_finalize (GObject *object);
-static void gtk_tool_item_parent_set (GtkWidget *toolitem,
- GtkWidget *parent);
+static void gtk_tool_item_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data);
static void gtk_tool_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -119,8 +120,6 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
object_class->finalize = gtk_tool_item_finalize;
object_class->notify = gtk_tool_item_property_notify;
- widget_class->parent_set = gtk_tool_item_parent_set;
-
klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
g_object_class_install_property (object_class,
@@ -215,6 +214,8 @@ gtk_tool_item_init (GtkToolItem *toolitem)
toolitem->priv->visible_vertical = TRUE;
toolitem->priv->homogeneous = FALSE;
toolitem->priv->expand = FALSE;
+
+ g_signal_connect (toolitem, "notify::parent", G_CALLBACK (gtk_tool_item_parent_cb), NULL);
}
static void
@@ -231,11 +232,14 @@ gtk_tool_item_finalize (GObject *object)
}
static void
-gtk_tool_item_parent_set (GtkWidget *toolitem,
- GtkWidget *prev_parent)
+gtk_tool_item_parent_cb (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
+
if (gtk_widget_get_parent (GTK_WIDGET (toolitem)) != NULL)
- gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
+ gtk_tool_item_toolbar_reconfigured (toolitem);
}
static void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index e1e7d7332e..ebf5dbf147 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -494,7 +494,6 @@ enum {
UNREALIZE,
SIZE_ALLOCATE,
STATE_FLAGS_CHANGED,
- PARENT_SET,
HIERARCHY_CHANGED,
DIRECTION_CHANGED,
GRAB_NOTIFY,
@@ -1025,7 +1024,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->get_request_mode = gtk_widget_real_get_request_mode;
klass->measure = gtk_widget_real_measure;
klass->state_flags_changed = gtk_widget_real_state_flags_changed;
- klass->parent_set = NULL;
klass->hierarchy_changed = NULL;
klass->direction_changed = gtk_widget_real_direction_changed;
klass->grab_notify = NULL;
@@ -1684,25 +1682,6 @@ gtk_widget_class_init (GtkWidgetClass *klass)
GTK_TYPE_STATE_FLAGS);
/**
- * GtkWidget::parent-set:
- * @widget: the object on which the signal is emitted
- * @old_parent: (allow-none): the previous parent, or %NULL if the widget
- * just got its initial parent.
- *
- * The ::parent-set signal is emitted when a new parent
- * has been set on a widget.
- */
- widget_signals[PARENT_SET] =
- g_signal_new (I_("parent-set"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkWidgetClass, parent_set),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 1,
- GTK_TYPE_WIDGET);
-
- /**
* GtkWidget::hierarchy-changed:
* @widget: the object on which the signal is emitted
* @previous_toplevel: (allow-none): the previous toplevel ancestor, or %NULL
@@ -4081,7 +4060,6 @@ gtk_widget_unparent (GtkWidget *widget)
_gtk_widget_update_parent_muxer (widget);
- g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
if (toplevel)
{
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
@@ -8380,7 +8358,6 @@ gtk_widget_reposition_after (GtkWidget *widget,
_gtk_widget_update_parent_muxer (widget);
- g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
if (priv->parent->priv->anchored && prev_parent == NULL)
_gtk_widget_propagate_hierarchy_changed (widget, NULL);
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index ff2aa771ba..5ba1ffa15e 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -157,8 +157,6 @@ struct _GtkWidget
* @size_allocate: Signal emitted to get the widget allocation.
* @state_flags_changed: Signal emitted when the widget state changes,
* see gtk_widget_get_state_flags().
- * @parent_set: Signal emitted when a new parent has been set on a
- * widget.
* @hierarchy_changed: Signal emitted when the anchored state of a
* widget changes.
* @direction_changed: Signal emitted when the text direction of a
@@ -306,8 +304,6 @@ struct _GtkWidgetClass
GtkAllocation *out_clip);
void (* state_flags_changed) (GtkWidget *widget,
GtkStateFlags previous_state_flags);
- void (* parent_set) (GtkWidget *widget,
- GtkWidget *previous_parent);
void (* hierarchy_changed) (GtkWidget *widget,
GtkWidget *previous_toplevel);
void (* direction_changed) (GtkWidget *widget,