diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index 500cc38e5e..2f2a1d2db9 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -149,21 +149,27 @@ gtk_list_item_manager_model_changed (GtkListItemManager *self, } /* - * gtk_list_item_manager_create_list_item: + * gtk_list_item_manager_acquire_list_item: * @self: a #GtkListItemManager * @position: the row in the model to create a list item for * @next_sibling: the widget this widget should be inserted before or %NULL * if none * - * Creates a new list item widget to use for @position. No widget may + * Creates a list item widget to use for @position. No widget may * yet exist that is used for @position. * + * When the returned item is no longer needed, the caller is responsible + * for calling gtk_list_item_manager_release_list_item(). + * A particular case is when the row at @position is removed. In that case, + * all list items in the removed range must be released before + * gtk_list_item_manager_model_changed() is called. + * * Returns: a properly setup widget to use in @position **/ GtkWidget * -gtk_list_item_manager_create_list_item (GtkListItemManager *self, - guint position, - GtkWidget *next_sibling) +gtk_list_item_manager_acquire_list_item (GtkListItemManager *self, + guint position, + GtkWidget *next_sibling) { GtkListItem *result; gpointer item; @@ -179,3 +185,22 @@ gtk_list_item_manager_create_list_item (GtkListItemManager *self, return GTK_WIDGET (result); } + +/* + * gtk_list_item_manager_release_list_item: + * @self: a #GtkListItemManager + * @item: an item previously acquired with + * gtk_list_item_manager_acquire_list_item() + * + * Releases an item that was previously acquired via + * gtk_list_item_manager_acquire_list_item() and is no longer in use. + **/ +void +gtk_list_item_manager_release_list_item (GtkListItemManager *self, + GtkWidget *item) +{ + g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self)); + g_return_if_fail (GTK_IS_LIST_ITEM (item)); + + gtk_widget_unparent (item); +} diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h index 34b57da97e..84f574576e 100644 --- a/gtk/gtklistitemmanagerprivate.h +++ b/gtk/gtklistitemmanagerprivate.h @@ -53,9 +53,11 @@ void gtk_list_item_manager_model_changed (GtkListItemMana guint position, guint removed, guint added); -GtkWidget * gtk_list_item_manager_create_list_item (GtkListItemManager *self, +GtkWidget * gtk_list_item_manager_acquire_list_item (GtkListItemManager *self, guint position, GtkWidget *next_sibling); +void gtk_list_item_manager_release_list_item (GtkListItemManager *self, + GtkWidget *widget); G_END_DECLS diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c index dec238c00c..c9d0e0ac29 100644 --- a/gtk/gtklistview.c +++ b/gtk/gtklistview.c @@ -125,7 +125,7 @@ list_row_clear (gpointer _row) { ListRow *row = _row; - g_clear_pointer (&row->widget, gtk_widget_unparent); + g_assert (row->widget == NULL); } static ListRow * @@ -454,6 +454,8 @@ gtk_list_view_remove_rows (GtkListView *self, for (i = 0; i < n_rows; i++) { ListRow *next = gtk_rb_tree_node_get_next (row); + gtk_list_item_manager_release_list_item (self->item_manager, row->widget); + row->widget = NULL; gtk_rb_tree_remove (self->rows, row); row = next; } @@ -487,9 +489,9 @@ gtk_list_view_add_rows (GtkListView *self, new_row = gtk_rb_tree_insert_before (self->rows, row); new_row->n_rows = 1; - new_row->widget = gtk_list_item_manager_create_list_item (self->item_manager, - position + i, - row ? row->widget : NULL); + new_row->widget = gtk_list_item_manager_acquire_list_item (self->item_manager, + position + i, + row ? row->widget : NULL); } gtk_widget_queue_resize (GTK_WIDGET (self));