mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 07:04:29 +00:00
treelistmodel: Track the item in the row
That way, we can return the item even after the row is removed. This is particularly relevant in ListItemFactory::unbind callbacks because they often use gtk_tree_list_row_get_item() and user code never tracks changes to this property. A side effect of this is that the item will survive until the row gets destroyed, but that's what users expect anyway, so we can live with it. Related: #5646
This commit is contained in:
parent
9048e391b6
commit
bf55685000
@ -88,6 +88,7 @@ struct _GtkTreeListRow
|
|||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
TreeNode *node; /* NULL when the row has been destroyed */
|
TreeNode *node; /* NULL when the row has been destroyed */
|
||||||
|
gpointer item;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkTreeListRowClass
|
struct _GtkTreeListRowClass
|
||||||
@ -293,6 +294,7 @@ tree_node_get_row (TreeNode *node)
|
|||||||
{
|
{
|
||||||
node->row = g_object_new (GTK_TYPE_TREE_LIST_ROW, NULL);
|
node->row = g_object_new (GTK_TYPE_TREE_LIST_ROW, NULL);
|
||||||
node->row->node = node;
|
node->row->node = node;
|
||||||
|
node->row->item = g_object_ref (node->item);
|
||||||
|
|
||||||
return node->row;
|
return node->row;
|
||||||
}
|
}
|
||||||
@ -947,7 +949,6 @@ gtk_tree_list_row_destroy (GtkTreeListRow *self)
|
|||||||
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_DEPTH]);
|
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_DEPTH]);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_EXPANDABLE]);
|
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_EXPANDABLE]);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_EXPANDED]);
|
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_EXPANDED]);
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), row_properties[ROW_PROP_ITEM]);
|
|
||||||
|
|
||||||
self->node = NULL;
|
self->node = NULL;
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
@ -1017,6 +1018,8 @@ gtk_tree_list_row_dispose (GObject *object)
|
|||||||
if (self->node)
|
if (self->node)
|
||||||
self->node->row = NULL;
|
self->node->row = NULL;
|
||||||
|
|
||||||
|
g_clear_object (&self->item);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_tree_list_row_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gtk_tree_list_row_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,21 +1266,16 @@ gtk_tree_list_row_is_expandable (GtkTreeListRow *self)
|
|||||||
*
|
*
|
||||||
* Gets the item corresponding to this row,
|
* Gets the item corresponding to this row,
|
||||||
*
|
*
|
||||||
* The value returned by this function never changes until the
|
|
||||||
* row is destroyed.
|
|
||||||
*
|
|
||||||
* Returns: (nullable) (type GObject) (transfer full): The item
|
* Returns: (nullable) (type GObject) (transfer full): The item
|
||||||
* of this row or %NULL when the row was destroyed
|
* of this row. This function is only marked as nullable for backwards
|
||||||
|
* compatibility reasons.
|
||||||
*/
|
*/
|
||||||
gpointer
|
gpointer
|
||||||
gtk_tree_list_row_get_item (GtkTreeListRow *self)
|
gtk_tree_list_row_get_item (GtkTreeListRow *self)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GTK_IS_TREE_LIST_ROW (self), NULL);
|
g_return_val_if_fail (GTK_IS_TREE_LIST_ROW (self), NULL);
|
||||||
|
|
||||||
if (self->node == NULL)
|
return g_object_ref (self->item);
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return g_object_ref (self->node->item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,6 +151,12 @@ test_type (gconstpointer data)
|
|||||||
if ((pspec->flags & G_PARAM_READABLE) == 0)
|
if ((pspec->flags & G_PARAM_READABLE) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* This is set by the treelistmodel, plain
|
||||||
|
* g_object_new() will crash here */
|
||||||
|
if (g_type_is_a (type, GTK_TYPE_TREE_LIST_ROW) &&
|
||||||
|
(strcmp (pspec->name, "item") == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* This is set via class_init, and we have a11y tests to verify it */
|
/* This is set via class_init, and we have a11y tests to verify it */
|
||||||
if (g_type_is_a (type, GTK_TYPE_ACCESSIBLE) &&
|
if (g_type_is_a (type, GTK_TYPE_ACCESSIBLE) &&
|
||||||
strcmp (pspec->name, "accessible-role") == 0)
|
strcmp (pspec->name, "accessible-role") == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user