places-sidebar: Use asynchronous API for querying bookmarks

Removes two FIXMEs, and ensures that the places sidebar does not block
while enumerating bookmarks or application shortcuts to remote volumes.

https://bugzilla.gnome.org/show_bug.cgi?id=735953
This commit is contained in:
Emmanuele Bassi 2014-09-03 12:52:52 +01:00 committed by Matthias Clasen
parent 6efbe745b1
commit c68fc27719

View File

@ -742,6 +742,51 @@ file_is_shown (GtkPlacesSidebar *sidebar,
return FALSE;
}
static void
on_app_shortcuts_query_complete (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPlacesSidebar *sidebar = data;
GFile *file = G_FILE (source);
GFileInfo *info;
info = g_file_query_info_finish (file, result, NULL);
if (info == NULL)
{
gchar *uri;
gchar *tooltip;
const gchar *name;
GIcon *icon;
int pos = 0;
name = g_file_info_get_display_name (info);
icon = g_file_info_get_symbolic_icon (info);
uri = g_file_get_uri (file);
tooltip = g_file_get_parse_name (file);
/* XXX: we could avoid this by using an ancillary closure
* with the index coming from add_application_shortcuts(),
* but in terms of algorithmic overhead, the application
* shortcuts is not going to be really big
*/
pos = g_slist_index (sidebar->shortcuts, file);
add_place (sidebar, PLACES_BUILT_IN,
SECTION_COMPUTER,
name, icon, uri,
NULL, NULL, NULL,
pos,
tooltip);
g_free (uri);
g_free (tooltip);
g_object_unref (info);
}
}
static void
add_application_shortcuts (GtkPlacesSidebar *sidebar)
{
@ -749,10 +794,7 @@ add_application_shortcuts (GtkPlacesSidebar *sidebar)
for (l = sidebar->shortcuts; l; l = l->next)
{
GFile *file;
GFileInfo *info;
file = G_FILE (l->data);
GFile *file = l->data;
if (!should_show_file (sidebar, file))
continue;
@ -760,36 +802,13 @@ add_application_shortcuts (GtkPlacesSidebar *sidebar)
if (file_is_shown (sidebar, file))
continue;
/* FIXME: we are getting file info synchronously. We may want to do it async at some point. */
info = g_file_query_info (file,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
NULL,
NULL); /* NULL-GError */
if (info)
{
gchar *uri;
gchar *tooltip;
const gchar *name;
GIcon *icon;
name = g_file_info_get_display_name (info);
icon = g_file_info_get_symbolic_icon (info);
uri = g_file_get_uri (file);
tooltip = g_file_get_parse_name (file);
add_place (sidebar, PLACES_BUILT_IN,
SECTION_COMPUTER,
name, icon, uri,
NULL, NULL, NULL, 0,
tooltip);
g_free (uri);
g_free (tooltip);
g_object_unref (info);
}
g_file_query_info_async (file,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
NULL,
on_app_shortcuts_query_complete,
sidebar);
}
}
@ -804,6 +823,65 @@ get_selected_iter (GtkPlacesSidebar *sidebar,
return gtk_tree_selection_get_selected (selection, NULL, iter);
}
typedef struct {
GtkPlacesSidebar *sidebar;
int index;
gboolean is_native;
} BookmarkQueryClosure;
static void
on_bookmark_query_info_complete (GObject *source,
GAsyncResult *result,
gpointer data)
{
BookmarkQueryClosure *clos = data;
GtkPlacesSidebar *sidebar = clos->sidebar;
GFile *root = G_FILE (source);
GFileInfo *info;
gchar *bookmark_name;
gchar *mount_uri;
gchar *tooltip;
GIcon *icon;
info = g_file_query_info_finish (root, result, NULL);
bookmark_name = _gtk_bookmarks_manager_get_bookmark_label (sidebar->bookmarks_manager, root);
if (bookmark_name == NULL && info != NULL)
bookmark_name = g_strdup (g_file_info_get_display_name (info));
else if (bookmark_name == NULL)
{
/* Don't add non-UTF-8 bookmarks */
bookmark_name = g_file_get_basename (root);
if (!g_utf8_validate (bookmark_name, -1, NULL))
{
g_free (bookmark_name);
goto out;
}
}
if (info)
icon = g_object_ref (g_file_info_get_symbolic_icon (info));
else
icon = g_themed_icon_new_with_default_fallbacks (clos->is_native ? ICON_NAME_FOLDER : ICON_NAME_FOLDER_NETWORK);
mount_uri = g_file_get_uri (root);
tooltip = g_file_get_parse_name (root);
add_place (sidebar, PLACES_BOOKMARK,
SECTION_BOOKMARKS,
bookmark_name, icon, mount_uri,
NULL, NULL, NULL, clos->index,
tooltip);
g_free (mount_uri);
g_free (tooltip);
g_free (bookmark_name);
out:
g_clear_object (&info);
g_slice_free (BookmarkQueryClosure, clos);
}
static void
update_places (GtkPlacesSidebar *sidebar)
{
@ -819,7 +897,6 @@ update_places (GtkPlacesSidebar *sidebar)
gint index;
gchar *original_uri, *mount_uri, *name, *identifier;
gchar *home_uri;
gchar *bookmark_name;
GIcon *icon;
GFile *root;
gchar *tooltip;
@ -1131,8 +1208,8 @@ update_places (GtkPlacesSidebar *sidebar)
for (sl = bookmarks, index = 0; sl; sl = sl->next, index++)
{
GFileInfo *info;
gboolean is_native;
BookmarkQueryClosure *clos;
root = sl->data;
is_native = g_file_is_native (root);
@ -1149,47 +1226,17 @@ update_places (GtkPlacesSidebar *sidebar)
if (sidebar->local_only && !is_native)
continue;
/* FIXME: we are getting file info synchronously. We may want to do it async at some point. */
info = g_file_query_info (root,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
NULL,
NULL); /* NULL-GError */
bookmark_name = _gtk_bookmarks_manager_get_bookmark_label (sidebar->bookmarks_manager, root);
if (bookmark_name == NULL && info != NULL)
bookmark_name = g_strdup (g_file_info_get_display_name (info));
else if (bookmark_name == NULL)
{
/* Don't add non-UTF-8 bookmarks */
bookmark_name = g_file_get_basename (root);
if (!g_utf8_validate (bookmark_name, -1, NULL))
{
g_free (bookmark_name);
continue;
}
}
if (info)
icon = g_object_ref (g_file_info_get_symbolic_icon (info));
else
icon = g_themed_icon_new_with_default_fallbacks (is_native ? ICON_NAME_FOLDER : ICON_NAME_FOLDER_NETWORK);
mount_uri = g_file_get_uri (root);
tooltip = g_file_get_parse_name (root);
add_place (sidebar, PLACES_BOOKMARK,
SECTION_BOOKMARKS,
bookmark_name, icon, mount_uri,
NULL, NULL, NULL, index,
tooltip);
g_free (mount_uri);
g_free (tooltip);
g_free (bookmark_name);
if (info)
g_object_unref (info);
clos = g_slice_new (BookmarkQueryClosure);
clos->sidebar = sidebar;
clos->index = index;
clos->is_native = is_native;
g_file_query_info_async (root,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
NULL,
on_bookmark_query_info_complete,
clos);
}
g_slist_foreach (bookmarks, (GFunc) g_object_unref, NULL);