[gnome-software] Fix a race with displaying results from shell search provider
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Fix a race with displaying results from shell search provider
- Date: Sun, 5 Oct 2014 20:25:27 +0000 (UTC)
commit a69e779204348fc264185388d1a40f3bf602445e
Author: Kalev Lember <kalevlember gmail com>
Date: Sun Oct 5 22:12:24 2014 +0200
Fix a race with displaying results from shell search provider
Clicking on an app in gnome-shell search results is supposed to bring up
the details page for that app, with the back button leading to the
search page, pre-populated with the same search that was done in
gnome-shell.
The code for this was all there, but it rarely worked properly because
we'd spawn two parallel async processes, one to switch to the search
page, and another one to switch to the details page. Whichever finished
last was the one that the user actually saw.
Fix this by properly chaining the async operations so that we'd always
end up on the details page.
https://bugzilla.gnome.org/show_bug.cgi?id=735798
src/gs-shell-search.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++
src/gs-shell-search.h | 2 +
src/gs-shell.c | 44 +--------------------------------
3 files changed, 68 insertions(+), 43 deletions(-)
---
diff --git a/src/gs-shell-search.c b/src/gs-shell-search.c
index 2828e34..21d8cd2 100644
--- a/src/gs-shell-search.c
+++ b/src/gs-shell-search.c
@@ -41,6 +41,7 @@ struct GsShellSearchPrivate
GtkSizeGroup *sizegroup_image;
GtkSizeGroup *sizegroup_name;
GsShell *shell;
+ gchar *appid_to_show;
gchar *value;
GtkWidget *list_box_search;
@@ -234,6 +235,36 @@ gs_shell_search_app_row_clicked_cb (GsAppRow *app_row,
gs_shell_search_show_missing_url (app);
}
+typedef struct {
+ GsShellSearch *shell_search;
+ GsApp *app;
+} RefineData;
+
+static void
+refine_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer data)
+{
+ RefineData *refine = data;
+ GsShellSearchPrivate *priv = refine->shell_search->priv;
+ GError *error = NULL;
+
+ if (!gs_plugin_loader_app_refine_finish (priv->plugin_loader,
+ res,
+ &error)) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ refine->app = gs_plugin_loader_dedupe (priv->plugin_loader, refine->app);
+ gs_shell_show_app (priv->shell, refine->app);
+
+out:
+ g_object_unref (refine->app);
+ g_free (refine);
+}
+
/**
* gs_shell_search_get_search_cb:
**/
@@ -291,6 +322,24 @@ gs_shell_search_get_search_cb (GObject *source_object,
gtk_widget_show (app_row);
}
+ if (priv->appid_to_show != NULL) {
+ RefineData *refine;
+
+ refine = g_new0 (RefineData, 1);
+ refine->shell_search = shell_search;
+ refine->app = gs_app_new (priv->appid_to_show);
+ gs_plugin_loader_app_refine_async (priv->plugin_loader,
+ refine->app,
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL,
+ priv->cancellable,
+ refine_cb,
+ refine);
+
+ g_clear_pointer (&priv->appid_to_show, g_free);
+ }
+
out: ;
}
@@ -340,6 +389,21 @@ gs_shell_search_reload (GsShellSearch *shell_search)
gs_shell_search_load (shell_search);
}
+
+/**
+ * gs_shell_search_set_appid_to_show:
+ *
+ * Switch to the specified app id after loading the search results.
+ **/
+void
+gs_shell_search_set_appid_to_show (GsShellSearch *shell_search, const gchar *appid)
+{
+ GsShellSearchPrivate *priv = shell_search->priv;
+
+ g_free (priv->appid_to_show);
+ priv->appid_to_show = g_strdup (appid);
+}
+
/**
* gs_shell_search_switch_to:
**/
@@ -585,6 +649,7 @@ gs_shell_search_finalize (GObject *object)
if (priv->search_cancellable != NULL)
g_object_unref (priv->search_cancellable);
+ g_free (priv->appid_to_show);
g_free (priv->value);
G_OBJECT_CLASS (gs_shell_search_parent_class)->finalize (object);
diff --git a/src/gs-shell-search.h b/src/gs-shell-search.h
index 9538020..49678a3 100644
--- a/src/gs-shell-search.h
+++ b/src/gs-shell-search.h
@@ -53,6 +53,8 @@ typedef struct
GType gs_shell_search_get_type (void);
GsShellSearch *gs_shell_search_new (void);
+void gs_shell_search_set_appid_to_show (GsShellSearch *shell_search,
+ const gchar *appid);
void gs_shell_search_switch_to (GsShellSearch *shell_search,
const gchar *text,
gboolean scroll_up);
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 43f87e9..db953fc 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -747,62 +747,20 @@ gs_shell_show_filename (GsShell *shell, const gchar *filename)
gs_shell_activate (shell);
}
-typedef struct {
- GsShell *shell;
- GsApp *app;
-} RefineData;
-
-static void
-refine_cb (GObject *source,
- GAsyncResult *res,
- gpointer data)
-{
- RefineData *refine = data;
- GsShellPrivate *priv = refine->shell->priv;
- GError *error = NULL;
-
- if (!gs_plugin_loader_app_refine_finish (priv->plugin_loader,
- res,
- &error)) {
- g_warning ("%s", error->message);
- g_error_free (error);
- goto out;
- }
-
- refine->app = gs_plugin_loader_dedupe (priv->plugin_loader, refine->app);
- gs_shell_show_app (refine->shell, refine->app);
-
-out:
- g_object_unref (refine->app);
- g_free (refine);
-}
-
void
gs_shell_show_search_result (GsShell *shell, const gchar *id, const gchar *search)
{
GsShellPrivate *priv = shell->priv;
GtkWidget *widget;
- RefineData *refine;
if (search != NULL && search[0] != '\0') {
widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_search"));
gtk_entry_set_text (GTK_ENTRY (widget), search);
+ gs_shell_search_set_appid_to_show (priv->shell_search, id);
gs_shell_search_switch_to (priv->shell_search, search, TRUE);
gs_shell_change_mode (shell, GS_SHELL_MODE_SEARCH, NULL, NULL, TRUE);
}
-
- refine = g_new0 (RefineData, 1);
- refine->shell = shell;
- refine->app = gs_app_new (id);
- gs_plugin_loader_app_refine_async (priv->plugin_loader,
- refine->app,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE |
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE |
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_URL,
- priv->cancellable,
- refine_cb,
- refine);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]