[gnome-software] Add gs_plugin_reload() to trigger an app reload



commit 0a3c32351931aff4776e10d6b6925dada65dc8a6
Author: Richard Hughes <richard hughsie com>
Date:   Sat Jun 11 22:37:22 2016 +0100

    Add gs_plugin_reload() to trigger an app reload
    
    If a plugin calls this then a few seconds later the entire gnome-software UI
    will reload. The aim is to split up updates-changed so that we don't refresh
    the entire UI when just the updates list is changed.

 src/gs-plugin-loader.c                   |   40 ++++++++++++++++++++++++++++++
 src/gs-plugin-loader.h                   |    1 +
 src/gs-plugin.c                          |   33 ++++++++++++++++++++++++
 src/gs-plugin.h                          |    4 ++-
 src/gs-shell.c                           |    9 +++---
 src/plugins/gs-flatpak.c                 |    3 +-
 src/plugins/gs-plugin-appstream.c        |    5 +--
 src/plugins/gs-plugin-shell-extensions.c |    6 +++-
 8 files changed, 89 insertions(+), 12 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 854ad53..71c2526 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -34,6 +34,7 @@
 #include "gs-common.h"
 
 #define GS_PLUGIN_LOADER_UPDATES_CHANGED_DELAY 3       /* s */
+#define GS_PLUGIN_LOADER_RELOAD_DELAY          5       /* s */
 
 typedef struct
 {
@@ -54,6 +55,7 @@ typedef struct
        gint                     scale;
 
        guint                    updates_changed_id;
+       guint                    reload_id;
        gboolean                 online; 
 } GsPluginLoaderPrivate;
 
@@ -63,6 +65,7 @@ enum {
        SIGNAL_STATUS_CHANGED,
        SIGNAL_PENDING_APPS_CHANGED,
        SIGNAL_UPDATES_CHANGED,
+       SIGNAL_RELOAD,
        SIGNAL_LAST
 };
 
@@ -3423,6 +3426,34 @@ gs_plugin_loader_updates_changed_cb (GsPlugin *plugin,
                                       g_object_ref (plugin_loader));
 }
 
+static gboolean
+gs_plugin_loader_reload_delay_cb (gpointer user_data)
+{
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (user_data);
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+
+       /* notify shells */
+       g_debug ("emitting ::reload");
+       g_signal_emit (plugin_loader, signals[SIGNAL_RELOAD], 0);
+       priv->reload_id = 0;
+
+       g_object_unref (plugin_loader);
+       return FALSE;
+}
+
+static void
+gs_plugin_loader_reload_cb (GsPlugin *plugin,
+                           GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       if (priv->reload_id != 0)
+               return;
+       priv->reload_id =
+               g_timeout_add_seconds (GS_PLUGIN_LOADER_RELOAD_DELAY,
+                                      gs_plugin_loader_reload_delay_cb,
+                                      g_object_ref (plugin_loader));
+}
+
 /**
  * gs_plugin_loader_open_plugin:
  */
@@ -3443,6 +3474,9 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        g_signal_connect (plugin, "updates-changed",
                          G_CALLBACK (gs_plugin_loader_updates_changed_cb),
                          plugin_loader);
+       g_signal_connect (plugin, "reload",
+                         G_CALLBACK (gs_plugin_loader_reload_cb),
+                         plugin_loader);
        g_signal_connect (plugin, "status-changed",
                          G_CALLBACK (gs_plugin_loader_status_changed_cb),
                          plugin_loader);
@@ -3862,6 +3896,12 @@ gs_plugin_loader_class_init (GsPluginLoaderClass *klass)
                              G_STRUCT_OFFSET (GsPluginLoaderClass, updates_changed),
                              NULL, NULL, g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
+       signals [SIGNAL_RELOAD] =
+               g_signal_new ("reload",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsPluginLoaderClass, reload),
+                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
 }
 
 /**
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 9307cea..1214d53 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -43,6 +43,7 @@ struct _GsPluginLoaderClass
                                                         GsPluginStatus  status);
        void                    (*pending_apps_changed) (GsPluginLoader *plugin_loader);
        void                    (*updates_changed)      (GsPluginLoader *plugin_loader);
+       void                    (*reload)               (GsPluginLoader *plugin_loader);
 };
 
 typedef enum {
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index 0f0b84b..183d73c 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -84,6 +84,7 @@ enum {
 enum {
        SIGNAL_UPDATES_CHANGED,
        SIGNAL_STATUS_CHANGED,
+       SIGNAL_RELOAD,
        SIGNAL_LAST
 };
 
@@ -773,6 +774,31 @@ gs_plugin_updates_changed (GsPlugin *plugin)
        g_idle_add (gs_plugin_updates_changed_cb, plugin);
 }
 
+static gboolean
+gs_plugin_reload_cb (gpointer user_data)
+{
+       GsPlugin *plugin = GS_PLUGIN (user_data);
+       g_signal_emit (plugin, signals[SIGNAL_RELOAD], 0);
+       return FALSE;
+}
+
+/**
+ * gs_plugin_reload:
+ * @plugin: a #GsPlugin
+ *
+ * Plugins that call this function should expect that all panels will
+ * reload after a small delay, causing mush flashing, wailing and
+ * gnashing of teeth.
+ *
+ * Plugins should not call this unless absolutely required.
+ **/
+void
+gs_plugin_reload (GsPlugin *plugin)
+{
+       g_debug ("emitting ::reload in idle");
+       g_idle_add (gs_plugin_reload_cb, plugin);
+}
+
 typedef struct {
        GsPlugin        *plugin;
        GsApp           *app;
@@ -1082,6 +1108,13 @@ gs_plugin_class_init (GsPluginClass *klass)
                              G_STRUCT_OFFSET (GsPluginClass, status_changed),
                              NULL, NULL, g_cclosure_marshal_generic,
                              G_TYPE_NONE, 2, GS_TYPE_APP, G_TYPE_UINT);
+
+       signals [SIGNAL_RELOAD] =
+               g_signal_new ("reload",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsPluginClass, reload),
+                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
 }
 
 /**
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 74758cf..6efa74d 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -46,7 +46,8 @@ struct _GsPluginClass
        void                    (*status_changed)       (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         guint           status);
-       gpointer                 padding[29];
+       void                    (*reload)               (GsPlugin       *plugin);
+       gpointer                 padding[28];
 };
 
 typedef struct GsPluginData    GsPluginData;
@@ -271,6 +272,7 @@ gboolean     gs_plugin_app_launch                   (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         GError         **error);
 void            gs_plugin_updates_changed              (GsPlugin       *plugin);
+void            gs_plugin_reload                       (GsPlugin       *plugin);
 const gchar    *gs_plugin_status_to_string             (GsPluginStatus  status);
 
 G_END_DECLS
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 332625c..466b60a 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -550,11 +550,8 @@ main_window_closed_cb (GtkWidget *dialog, GdkEvent *event, gpointer user_data)
        return TRUE;
 }
 
-/**
- * gs_shell_updates_changed_cb:
- */
 static void
-gs_shell_updates_changed_cb (GsPluginLoader *plugin_loader, GsShell *shell)
+gs_shell_reload_cb (GsPluginLoader *plugin_loader, GsShell *shell)
 {
        GsShellPrivate *priv = gs_shell_get_instance_private (shell);
        gs_page_reload (GS_PAGE (priv->shell_category));
@@ -613,8 +610,10 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
        g_return_if_fail (GS_IS_SHELL (shell));
 
        priv->plugin_loader = g_object_ref (plugin_loader);
+       g_signal_connect (priv->plugin_loader, "reload",
+                         G_CALLBACK (gs_shell_reload_cb), shell);
        g_signal_connect (priv->plugin_loader, "updates-changed",
-                         G_CALLBACK (gs_shell_updates_changed_cb), shell);
+                         G_CALLBACK (gs_shell_reload_cb), shell);
        priv->cancellable = g_object_ref (cancellable);
 
        gs_shell_monitor_permission (shell);
diff --git a/src/plugins/gs-flatpak.c b/src/plugins/gs-flatpak.c
index 8ba06d0..269cf2c 100644
--- a/src/plugins/gs-flatpak.c
+++ b/src/plugins/gs-flatpak.c
@@ -205,7 +205,8 @@ gs_flatpak_refresh_appstream (GsFlatpak *self, guint cache_age,
                                                  cancellable,
                                                  error))
                        return FALSE;
-               gs_plugin_updates_changed (self->plugin);
+               /* FIXME: we don't want to do this; rely on AppStream */
+               gs_plugin_reload (self->plugin);
        }
 
        return TRUE;
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 8e5846f..e226a9b 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -45,10 +45,9 @@ gs_plugin_appstream_store_changed_cb (AsStore *store, GsPlugin *plugin)
 {
        g_debug ("AppStream metadata changed");
 
-       /* this is not strictly true, but it causes all the UI to be reloaded
-        * which is what we really want */
+       /* all the UI is reloaded as something external has happened */
        if (!gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_RUNNING_OTHER))
-               gs_plugin_updates_changed (plugin);
+               gs_plugin_reload (plugin);
 }
 
 void
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
index 7d05602..35b3f0c 100644
--- a/src/plugins/gs-plugin-shell-extensions.c
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -217,8 +217,10 @@ gs_plugin_shell_extensions_changed_cb (GDBusProxy *proxy,
                                       GVariant *parameters,
                                       GsPlugin *plugin)
 {
-       if (g_strcmp0 (signal_name, "ExtensionStatusChanged") == 0)
-               gs_plugin_updates_changed (plugin);
+       if (g_strcmp0 (signal_name, "ExtensionStatusChanged") == 0) {
+               /* FIXME: we want to only reload specific GsApps */
+               gs_plugin_reload (plugin);
+       }
 }
 
 gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]