diff options
author | Benjamin Otte <otte@redhat.com> | 2019-10-03 06:50:51 +0200 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-05-30 19:26:45 -0400 |
commit | 7c38ac19540c91d651bbe868ec56321bb9d2829a (patch) | |
tree | d74e4579ee629007549703e584bedc21fd9fdc22 /tests | |
parent | dbe802f68556d407d1a395ba93a714ce4e04ab00 (diff) | |
download | gtk+-7c38ac19540c91d651bbe868ec56321bb9d2829a.tar.gz |
testlistview: Load icons async
Speeds up loading by 4x, because out of view icons aren't loaded
anymore.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/testlistview.c | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/tests/testlistview.c b/tests/testlistview.c index 667986c0a3..10c30de6cd 100644 --- a/tests/testlistview.c +++ b/tests/testlistview.c @@ -37,7 +37,6 @@ create_directory_list (GFile *file) GtkDirectoryList *dir; dir = gtk_directory_list_new (G_FILE_ATTRIBUTE_STANDARD_TYPE - "," G_FILE_ATTRIBUTE_STANDARD_ICON "," G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, NULL); @@ -94,6 +93,7 @@ struct _RowData GtkWidget *expander; GtkWidget *icon; GtkWidget *name; + GCancellable *cancellable; GtkTreeListRow *current_item; GBinding *expander_binding; @@ -108,17 +108,86 @@ row_data_unbind (RowData *data) if (data->current_item == NULL) return; + if (data->cancellable) + { + g_cancellable_cancel (data->cancellable); + g_clear_object (&data->cancellable); + } + g_binding_unbind (data->expander_binding); g_clear_object (&data->current_item); } static void +row_data_update_info (RowData *data, + GFileInfo *info) +{ + GIcon *icon; + const char *thumbnail_path; + + thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + if (thumbnail_path) + { + /* XXX: not async */ + GFile *thumbnail_file = g_file_new_for_path (thumbnail_path); + icon = g_file_icon_new (thumbnail_file); + g_object_unref (thumbnail_file); + } + else + { + icon = g_file_info_get_icon (info); + } + + gtk_widget_set_visible (data->icon, icon != NULL); + gtk_image_set_from_gicon (GTK_IMAGE (data->icon), icon); +} + +static void +copy_attribute (GFileInfo *to, + GFileInfo *from, + const gchar *attribute) +{ + GFileAttributeType type; + gpointer value; + + if (g_file_info_get_attribute_data (from, attribute, &type, &value, NULL)) + g_file_info_set_attribute (to, attribute, type, value); +} + +static void +row_data_got_thumbnail_info_cb (GObject *source, + GAsyncResult *res, + gpointer _data) +{ + RowData *data = _data; /* invalid if operation was cancelled */ + GFile *file = G_FILE (source); + GFileInfo *queried, *info; + + queried = g_file_query_info_finish (file, res, NULL); + if (queried == NULL) + return; + + /* now we know row is valid */ + + info = gtk_tree_list_row_get_item (data->current_item); + + copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + copy_attribute (info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED); + copy_attribute (info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON); + + g_object_unref (queried); + + row_data_update_info (data, info); + + g_clear_object (&data->cancellable); +} + +static void row_data_bind (RowData *data, GtkTreeListRow *item) { GFileInfo *info; - GIcon *icon; guint depth; row_data_unbind (data); @@ -136,10 +205,22 @@ row_data_bind (RowData *data, info = gtk_tree_list_row_get_item (item); - icon = g_file_info_get_icon (info); - gtk_widget_set_visible (data->icon, icon != NULL); - if (icon) - gtk_image_set_from_gicon (GTK_IMAGE (data->icon), icon); + if (!g_file_info_has_attribute (info, "filechooser::queried")) + { + data->cancellable = g_cancellable_new (); + g_file_info_set_attribute_boolean (info, "filechooser::queried", TRUE); + g_file_query_info_async (G_FILE (g_file_info_get_attribute_object (info, "standard::file")), + G_FILE_ATTRIBUTE_THUMBNAIL_PATH "," + G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "," + G_FILE_ATTRIBUTE_STANDARD_ICON, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + data->cancellable, + row_data_got_thumbnail_info_cb, + data); + } + + row_data_update_info (data, info); gtk_label_set_label (GTK_LABEL (data->name), g_file_info_get_display_name (info)); |