From 31d03f9f26dc3f9d0787a322bf4a877d0374a777 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 16:10:54 -0400 Subject: [PATCH 1/6] Add gtk_list_item_manager_gc_tiles This will allow us to simplify size allocation code in listview and gridview. --- gtk/gtklistitemmanager.c | 12 ++++++++++++ gtk/gtklistitemmanagerprivate.h | 1 + 2 files changed, 13 insertions(+) diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index a8b12cef7f..0945241c1b 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -1094,6 +1094,18 @@ gtk_list_tile_gc (GtkListItemManager *self, return tile; } +void +gtk_list_item_manager_gc_tiles (GtkListItemManager *self) +{ + GtkListTile *tile; + + for (tile = gtk_list_tile_gc (self, gtk_list_item_manager_get_first (self)); + tile != NULL; + tile = gtk_list_tile_gc (self, gtk_rb_tree_node_get_next (tile))) + { + } +} + static void gtk_list_item_manager_release_items (GtkListItemManager *self, GtkListItemChange *change) diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h index ea855f4cc5..13ab10b90b 100644 --- a/gtk/gtklistitemmanagerprivate.h +++ b/gtk/gtklistitemmanagerprivate.h @@ -94,6 +94,7 @@ gpointer gtk_list_item_manager_get_nth (GtkListItemMana GtkListTile * gtk_list_item_manager_get_nearest_tile (GtkListItemManager *self, int x, int y); +void gtk_list_item_manager_gc_tiles (GtkListItemManager *self); static inline gboolean gtk_list_tile_is_header (GtkListTile *tile) From b1c2a1c015b94131d7c2596957e969196871573b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 18:52:44 -0400 Subject: [PATCH 2/6] listitemmanager: Use gc_tiles Replace an open-coded version of this function with a call to gtk_list_item_manager_gc_tiles. --- gtk/gtklistitemmanager.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index 0945241c1b..599d6d0c39 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -1606,7 +1606,6 @@ static void gtk_list_item_manager_clear_model (GtkListItemManager *self) { GtkListItemChange change; - GtkListTile *tile; GSList *l; if (self->model == NULL) @@ -1628,11 +1627,8 @@ gtk_list_item_manager_clear_model (GtkListItemManager *self) self); g_clear_object (&self->model); - /* really empty the tiles */ - for (tile = gtk_list_tile_gc (self, gtk_list_item_manager_get_first (self)); - tile; - tile = gtk_list_tile_gc (self, tile)) - { } + gtk_list_item_manager_gc_tiles (self); + g_assert (gtk_rb_tree_get_root (self->items) == NULL); } From 00914257291b20f06e94b1a9e2ea80b39d403247 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 18:55:05 -0400 Subject: [PATCH 3/6] listitemmanager: Stop exporting tile_gc This function is now just used internally, so make it static. --- gtk/gtklistitemmanager.c | 2 +- gtk/gtklistitemmanagerprivate.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c index 599d6d0c39..69d0e32bc1 100644 --- a/gtk/gtklistitemmanager.c +++ b/gtk/gtklistitemmanager.c @@ -1044,7 +1044,7 @@ gtk_list_tile_split (GtkListItemManager *self, * * Returns: The next tile or NULL if everything was gc'ed **/ -GtkListTile * +static GtkListTile * gtk_list_tile_gc (GtkListItemManager *self, GtkListTile *tile) { diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h index 13ab10b90b..cae4f87a27 100644 --- a/gtk/gtklistitemmanagerprivate.h +++ b/gtk/gtklistitemmanagerprivate.h @@ -127,8 +127,6 @@ void gtk_list_tile_set_area_size (GtkListItemMana GtkListTile * gtk_list_tile_split (GtkListItemManager *self, GtkListTile *tile, guint n_items); -GtkListTile * gtk_list_tile_gc (GtkListItemManager *self, - GtkListTile *tile); void gtk_list_item_manager_set_model (GtkListItemManager *self, GtkSelectionModel *model); From 56cfef354405bb554e3c681bdfb8c011a8adcc11 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 16:12:54 -0400 Subject: [PATCH 4/6] testsuite: Use gtk_list_item_manager_gc_tiles Use this new api instead of open-coding it. Also, assert that it merges consecutive multi-item tiles. --- testsuite/gtk/listitemmanager.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/testsuite/gtk/listitemmanager.c b/testsuite/gtk/listitemmanager.c index 7f14a0f6d8..5b6da7c856 100644 --- a/testsuite/gtk/listitemmanager.c +++ b/testsuite/gtk/listitemmanager.c @@ -100,6 +100,7 @@ check_list_item_manager (GtkListItemManager *items, MATCHED_SECTION, UNMATCHED_SECTION } section_state = NO_SECTION; + gboolean after_items = FALSE; has_sections = gtk_list_item_manager_get_has_sections (items); @@ -115,6 +116,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_true (has_sections); g_assert_true (tile->widget); section_state = MATCHED_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_UNMATCHED_HEADER: @@ -122,6 +124,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_cmpint (tile->n_items, ==, 0); g_assert_null (tile->widget); section_state = UNMATCHED_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_FOOTER: @@ -130,6 +133,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_true (has_sections); g_assert_null (tile->widget); section_state = NO_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_UNMATCHED_FOOTER: @@ -137,6 +141,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_cmpint (tile->n_items, ==, 0); g_assert_null (tile->widget); section_state = NO_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_ITEM: @@ -152,6 +157,11 @@ check_list_item_manager (GtkListItemManager *items, g_object_unref (item); g_assert_cmpint (n_items, ==, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (tile->widget))); g_assert_cmpint (tile->n_items, ==, 1); + after_items = FALSE; + } + else + { + after_items = TRUE; } if (tile->n_items) n_items += tile->n_items; @@ -184,10 +194,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_true (tile->widget); } - for (tile = gtk_list_tile_gc (items, gtk_list_item_manager_get_first (items)); - tile != NULL; - tile = gtk_list_tile_gc (items, gtk_rb_tree_node_get_next (tile))) - ; + gtk_list_item_manager_gc_tiles (items); n_items = 0; @@ -203,6 +210,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_true (has_sections); g_assert_true (tile->widget); section_state = MATCHED_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_UNMATCHED_HEADER: @@ -210,6 +218,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_cmpint (tile->n_items, ==, 0); g_assert_false (tile->widget); section_state = UNMATCHED_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_FOOTER: @@ -218,6 +227,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_true (has_sections); g_assert_false (tile->widget); section_state = NO_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_UNMATCHED_FOOTER: @@ -225,6 +235,7 @@ check_list_item_manager (GtkListItemManager *items, g_assert_cmpint (tile->n_items, ==, 0); g_assert_false (tile->widget); section_state = NO_SECTION; + after_items = FALSE; break; case GTK_LIST_TILE_ITEM: @@ -232,6 +243,12 @@ check_list_item_manager (GtkListItemManager *items, if (tile->widget) { g_assert_cmpint (tile->n_items, ==, 1); + after_items = FALSE; + } + else + { + g_assert_false (after_items); + after_items = TRUE; } if (tile->n_items) n_items += tile->n_items; From 431458ed78da633f90f5b45bcb57d930fc9f4866 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 16:12:25 -0400 Subject: [PATCH 5/6] listview: Use gtk_list_item_manager_gc_tiles This simplifies the code a bit. --- gtk/gtklistview.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c index 28c4706814..f06b9cafec 100644 --- a/gtk/gtklistview.c +++ b/gtk/gtklistview.c @@ -608,8 +608,10 @@ gtk_list_view_size_allocate (GtkWidget *widget, opposite_scroll_policy = gtk_list_base_get_scroll_policy (GTK_LIST_BASE (self), opposite_orientation); gtk_list_base_get_border_spacing (GTK_LIST_BASE (self), NULL, &spacing); + gtk_list_item_manager_gc_tiles (self->item_manager); + /* step 0: exit early if list is empty */ - tile = gtk_list_tile_gc (self->item_manager, gtk_list_item_manager_get_first (self->item_manager)); + tile = gtk_list_item_manager_get_first (self->item_manager); if (tile == NULL) { gtk_list_base_allocate (GTK_LIST_BASE (self)); @@ -631,7 +633,7 @@ gtk_list_view_size_allocate (GtkWidget *widget, for (; tile != NULL; - tile = gtk_list_tile_gc (self->item_manager, gtk_rb_tree_node_get_next (tile))) + tile = gtk_rb_tree_node_get_next (tile)) { if (tile->widget == NULL) continue; From 53c63673e42cf829fcd99d95bc7a2729794aef29 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 20 May 2023 16:45:19 -0400 Subject: [PATCH 6/6] gridview: Use gtk_list_item_manager_gc_tiles This simplifies the code a bit. --- gtk/gtkgridview.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gtk/gtkgridview.c b/gtk/gtkgridview.c index 9408e16123..dd36309844 100644 --- a/gtk/gtkgridview.c +++ b/gtk/gtkgridview.c @@ -756,8 +756,10 @@ gtk_grid_view_size_allocate (GtkWidget *widget, min_row_height = ceil ((double) height / GTK_GRID_VIEW_MAX_VISIBLE_ROWS); gtk_list_base_get_border_spacing (GTK_LIST_BASE (self), &xspacing, &yspacing); + gtk_list_item_manager_gc_tiles (self->item_manager); + /* step 0: exit early if list is empty */ - tile = gtk_list_tile_gc (self->item_manager, gtk_list_item_manager_get_first (self->item_manager)); + tile = gtk_list_item_manager_get_first (self->item_manager); if (tile == NULL) { gtk_list_base_allocate (GTK_LIST_BASE (self)); @@ -776,9 +778,7 @@ gtk_grid_view_size_allocate (GtkWidget *widget, /* step 2: determine height of known rows */ heights = g_array_new (FALSE, FALSE, sizeof (int)); - for (; - tile != NULL; - tile = gtk_list_tile_gc (self->item_manager, tile)) + while (tile != NULL) { /* if it's a multirow tile, handle it here */ if (tile->n_items > 1 && tile->n_items >= self->n_columns) @@ -795,7 +795,7 @@ gtk_grid_view_size_allocate (GtkWidget *widget, for (i = 0, start = tile; i < self->n_columns && tile != NULL; - tile = gtk_list_tile_gc (self->item_manager, gtk_rb_tree_node_get_next (tile))) + tile = gtk_rb_tree_node_get_next (tile)) { if (tile->widget) {