[gnome-control-center] search: use g_get_system_data_dirs() to discover providers
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] search: use g_get_system_data_dirs() to discover providers
- Date: Mon, 27 Oct 2014 20:38:48 +0000 (UTC)
commit 0a7b552d936fef90111dfb69c112fcf2a8add8ca
Author: Cosimo Cecchi <cosimo endlessm com>
Date: Fri Oct 24 12:55:48 2014 -0700
search: use g_get_system_data_dirs() to discover providers
Currently, the search panel looks for search providers in
DATADIR/gnome-shell/search-providers. This won't work when providers are
located in a different directory which is still part of XDG_DATA_DIRS,
which is a valid use case and supported by gnome-shell.
This commit refactors the loader code to scan all the directories
upfront in a separate thread.
https://bugzilla.gnome.org/show_bug.cgi?id=739148
panels/search/cc-search-panel.c | 169 +++++++++++++++++++++++++-------------
1 files changed, 111 insertions(+), 58 deletions(-)
---
diff --git a/panels/search/cc-search-panel.c b/panels/search/cc-search-panel.c
index 717c3e7..d2a0f3b 100644
--- a/panels/search/cc-search-panel.c
+++ b/panels/search/cc-search-panel.c
@@ -36,6 +36,7 @@ struct _CcSearchPanelPrivate
GtkWidget *up_button;
GtkWidget *down_button;
+ GCancellable *load_cancellable;
GSettings *search_settings;
GHashTable *sort_order;
@@ -545,95 +546,146 @@ search_panel_add_one_provider (CcSearchPanel *self,
}
static void
-next_search_provider_ready (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
+search_providers_discover_ready (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
- CcSearchPanel *self = user_data;
- GFile *providers_location, *provider;
- GList *files;
+ GList *providers, *l;
+ GFile *provider;
+ CcSearchPanel *self = CC_SEARCH_PANEL (source);
GError *error = NULL;
- gchar *path;
- files = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (source),
- res, &error);
- providers_location = g_file_enumerator_get_container (G_FILE_ENUMERATOR (source));
+ providers = g_task_propagate_pointer (G_TASK (result), &error);
- if (error != NULL)
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
{
- path = g_file_get_path (providers_location);
+ g_error_free (error);
+ return;
+ }
- g_warning ("Error reading from %s: %s - search providers might be missing from the panel",
- path, error->message);
+ g_clear_object (&self->priv->load_cancellable);
- g_error_free (error);
- g_free (path);
+ if (providers == NULL)
+ {
+ search_panel_set_no_providers (self);
+ return;
}
- if (files != NULL)
+ for (l = providers; l != NULL; l = l->next)
{
- provider = g_file_get_child (providers_location, g_file_info_get_name (files->data));
+ provider = l->data;
search_panel_add_one_provider (self, provider);
g_object_unref (provider);
-
- g_file_enumerator_next_files_async (G_FILE_ENUMERATOR (source), 1,
- G_PRIORITY_DEFAULT, NULL,
- next_search_provider_ready, self);
- }
- else
- {
- /* propagate a write to GSettings, to make sure we always have
- * all the providers in the list.
- */
- search_panel_propagate_sort_order (self);
}
- g_list_free_full (files, g_object_unref);
+ /* propagate a write to GSettings, to make sure we always have
+ * all the providers in the list.
+ */
+ search_panel_propagate_sort_order (self);
+ g_list_free (providers);
}
-static void
-enumerate_search_providers_ready (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
+static GList *
+search_providers_discover_one_directory (const gchar *system_dir,
+ GCancellable *cancellable)
{
- CcSearchPanel *self = user_data;
+ GList *providers = NULL;
+ gchar *providers_path;
+ GFile *providers_location, *provider;
+ GFileInfo *info;
GFileEnumerator *enumerator;
GError *error = NULL;
- gchar *path;
- enumerator = g_file_enumerate_children_finish (G_FILE (source), res, &error);
+ providers_path = g_build_filename (system_dir, "gnome-shell", "search-providers", NULL);
+ providers_location = g_file_new_for_path (providers_path);
+
+ enumerator = g_file_enumerate_children (providers_location,
+ "standard::type,standard::name,standard::content-type",
+ G_FILE_QUERY_INFO_NONE,
+ cancellable, &error);
+
if (error != NULL)
{
- path = g_file_get_path (G_FILE (source));
-
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Error opening %s: %s - search provider configuration won't be possible",
- path, error->message);
+ providers_path, error->message);
+ g_clear_error (&error);
- search_panel_set_no_providers (self);
- g_error_free (error);
- return;
+ goto out;
+ }
+
+ while ((info = g_file_enumerator_next_file (enumerator, cancellable, &error)) != NULL)
+ {
+ provider = g_file_get_child (providers_location, g_file_info_get_name (info));
+ providers = g_list_prepend (providers, provider);
+ g_object_unref (info);
+ }
+
+ if (error != NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Error reading from %s: %s - search providers might be missing from the panel",
+ providers_path, error->message);
+ g_clear_error (&error);
+ }
+
+ out:
+ g_clear_object (&enumerator);
+ g_clear_object (&providers_location);
+ g_free (providers_path);
+
+ return providers;
+}
+
+static void
+search_providers_discover_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GList *providers = NULL;
+ const gchar * const *system_data_dirs;
+ int idx;
+
+ system_data_dirs = g_get_system_data_dirs ();
+ for (idx = 0; system_data_dirs[idx] != NULL; idx++)
+ {
+ providers = g_list_concat (search_providers_discover_one_directory (system_data_dirs[idx],
cancellable),
+ providers);
+
+ if (g_task_return_error_if_cancelled (task))
+ {
+ g_list_free_full (providers, g_object_unref);
+ return;
+ }
}
- g_file_enumerator_next_files_async (enumerator, 1,
- G_PRIORITY_DEFAULT, NULL,
- next_search_provider_ready, self);
- g_object_unref (enumerator);
+ g_task_return_pointer (task, providers, NULL);
}
static void
populate_search_providers (CcSearchPanel *self)
{
- GFile *providers_location;
-
- providers_location = g_file_new_for_path (DATADIR "/gnome-shell/search-providers");
- g_file_enumerate_children_async (providers_location,
- "standard::type,standard::name,standard::content-type",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- NULL,
- enumerate_search_providers_ready, self);
- g_object_unref (providers_location);
+ GTask *task;
+
+ self->priv->load_cancellable = g_cancellable_new ();
+ task = g_task_new (self, self->priv->load_cancellable,
+ search_providers_discover_ready, self);
+ g_task_run_in_thread (task, search_providers_discover_thread);
+ g_object_unref (task);
+}
+
+static void
+cc_search_panel_dispose (GObject *object)
+{
+ CcSearchPanelPrivate *priv = CC_SEARCH_PANEL (object)->priv;
+
+ if (priv->load_cancellable != NULL)
+ g_cancellable_cancel (priv->load_cancellable);
+ g_clear_object (&priv->load_cancellable);
+
+ G_OBJECT_CLASS (cc_search_panel_parent_class)->dispose (object);
}
static void
@@ -752,6 +804,7 @@ cc_search_panel_class_init (CcSearchPanelClass *klass)
GObjectClass *oclass = G_OBJECT_CLASS (klass);
oclass->constructed = cc_search_panel_constructed;
+ oclass->dispose = cc_search_panel_dispose;
oclass->finalize = cc_search_panel_finalize;
g_type_class_add_private (klass, sizeof (CcSearchPanelPrivate));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]