[gnome-software] Refresh the updates panel if the update state changes



commit d070241e6e2852af77679f99c830df32c854e4e4
Author: Richard Hughes <richard hughsie com>
Date:   Tue Oct 29 10:33:53 2013 +0000

    Refresh the updates panel if the update state changes
    
    You can debug this by doing:
    
    $ pkcon update --only-download
    $ sudo rm /var/lib/PackageKit/prepared-update
    
    Resolves: https://bugzilla.gnome.org/show_bug.cgi?id=710880

 src/gs-plugin-loader.c                  |   20 +++++++++
 src/gs-plugin-loader.h                  |    1 +
 src/gs-plugin.c                         |   22 +++++++++
 src/gs-plugin.h                         |    5 ++
 src/gs-shell-updates.c                  |   14 ++++++
 src/plugins/gs-plugin-systemd-updates.c |   72 +++++++++++++++++++++++++++++++
 6 files changed, 134 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 068547e..15d421e 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -55,6 +55,7 @@ G_DEFINE_TYPE (GsPluginLoader, gs_plugin_loader, G_TYPE_OBJECT)
 enum {
        SIGNAL_STATUS_CHANGED,
        SIGNAL_PENDING_APPS_CHANGED,
+       SIGNAL_UPDATES_CHANGED,
        SIGNAL_LAST
 };
 
@@ -2393,6 +2394,17 @@ gs_plugin_loader_status_update_cb (GsPlugin *plugin,
 }
 
 /**
+ * gs_plugin_loader_updates_changed_cb:
+ */
+static void
+gs_plugin_loader_updates_changed_cb (GsPlugin *plugin, gpointer user_data)
+{
+       GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (user_data);
+       g_debug ("updates-changed");
+       g_signal_emit (plugin_loader, signals[SIGNAL_UPDATES_CHANGED], 0);
+}
+
+/**
  * gs_plugin_loader_open_plugin:
  */
 static GsPlugin *
@@ -2441,6 +2453,8 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        plugin->name = g_strdup (plugin_name ());
        plugin->status_update_fn = gs_plugin_loader_status_update_cb;
        plugin->status_update_user_data = plugin_loader;
+       plugin->updates_changed_fn = gs_plugin_loader_updates_changed_cb;
+       plugin->updates_changed_user_data = plugin_loader;
        plugin->profile = g_object_ref (plugin_loader->priv->profile);
        plugin->icon_cache = g_hash_table_ref (plugin_loader->priv->icon_cache);
        g_debug ("opened plugin %s: %s", filename, plugin->name);
@@ -2598,6 +2612,12 @@ gs_plugin_loader_class_init (GsPluginLoaderClass *klass)
                              G_STRUCT_OFFSET (GsPluginLoaderClass, pending_apps_changed),
                              NULL, NULL, g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
+       signals [SIGNAL_UPDATES_CHANGED] =
+               g_signal_new ("updates-changed",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsPluginLoaderClass, updates_changed),
+                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
 
        g_type_class_add_private (klass, sizeof (GsPluginLoaderPrivate));
 }
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 108fbd5..29014c4 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -53,6 +53,7 @@ typedef struct
                                                         GsApp          *app,
                                                         GsPluginStatus  status);
        void                    (*pending_apps_changed) (GsPluginLoader *plugin_loader);
+       void                    (*updates_changed)      (GsPluginLoader *plugin_loader);
 } GsPluginLoaderClass;
 
 typedef enum
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index 5b61654..8acd6ab 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -196,4 +196,26 @@ gs_plugin_status_update (GsPlugin *plugin, GsApp *app, GsPluginStatus status)
        g_source_set_name_by_id (id, "[gnome-software] gs_plugin_status_update_cb");
 }
 
+/**
+ * gs_plugin_updates_changed_cb:
+ **/
+static gboolean
+gs_plugin_updates_changed_cb (gpointer user_data)
+{
+       GsPlugin *plugin = GS_PLUGIN (user_data);
+       plugin->updates_changed_fn (plugin, plugin->updates_changed_user_data);
+       return FALSE;
+}
+
+/**
+ * gs_plugin_updates_changed:
+ **/
+void
+gs_plugin_updates_changed (GsPlugin *plugin)
+{
+       guint id;
+       id = g_idle_add (gs_plugin_updates_changed_cb, plugin);
+       g_source_set_name_by_id (id, "[gnome-software] gs_plugin_updates_changed_cb");
+}
+
 /* vim: set noexpandtab: */
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index cd35904..c04e6db 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -52,6 +52,8 @@ typedef void (*GsPluginStatusUpdate)  (GsPlugin       *plugin,
                                         GsApp          *app,
                                         GsPluginStatus  status,
                                         gpointer        user_data);
+typedef void (*GsPluginUpdatesChanged) (GsPlugin       *plugin,
+                                        gpointer        user_data);
 
 typedef gboolean (*GsPluginListFilter) (GsApp          *app,
                                         gpointer        user_data);
@@ -65,6 +67,8 @@ struct GsPlugin {
        guint                    pixbuf_size;
        GsPluginStatusUpdate     status_update_fn;
        gpointer                 status_update_user_data;
+       GsPluginUpdatesChanged   updates_changed_fn;
+       gpointer                 updates_changed_user_data;
        GsProfile               *profile;
        GHashTable              *icon_cache;
 };
@@ -138,6 +142,7 @@ void                 gs_plugin_list_filter_duplicates       (GList          **list);
 void            gs_plugin_status_update                (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         GsPluginStatus  status);
+void            gs_plugin_updates_changed              (GsPlugin       *plugin);
 const gchar    *gs_plugin_status_to_string             (GsPluginStatus  status);
 gboolean        gs_plugin_add_search                   (GsPlugin       *plugin,
                                                         const gchar    *value,
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index 90fdf95..e20d1f3 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -441,6 +441,17 @@ gs_shell_updates_button_back_cb (GtkWidget *widget, GsShellUpdates *shell_update
 }
 
 /**
+ * gs_shell_updates_changed_cb:
+ */
+static void
+gs_shell_updates_changed_cb (GsPluginLoader *plugin_loader,
+                            GsShellUpdates *shell_updates)
+{
+       gs_shell_updates_invalidate (shell_updates);
+       gs_shell_updates_refresh (shell_updates, FALSE, TRUE);
+}
+
+/**
  * gs_shell_updates_pending_apps_changed_cb:
  */
 static void
@@ -566,6 +577,9 @@ gs_shell_updates_setup (GsShellUpdates *shell_updates,
        g_signal_connect (priv->plugin_loader, "pending-apps-changed",
                          G_CALLBACK (gs_shell_updates_pending_apps_changed_cb),
                          shell_updates);
+       g_signal_connect (priv->plugin_loader, "updates-changed",
+                         G_CALLBACK (gs_shell_updates_changed_cb),
+                         shell_updates);
        priv->builder = g_object_ref (builder);
        priv->cancellable = g_object_ref (cancellable);
 
diff --git a/src/plugins/gs-plugin-systemd-updates.c b/src/plugins/gs-plugin-systemd-updates.c
index 07b1cd1..3bd6bf6 100644
--- a/src/plugins/gs-plugin-systemd-updates.c
+++ b/src/plugins/gs-plugin-systemd-updates.c
@@ -20,12 +20,18 @@
  */
 
 #include <config.h>
+#include <gio/gio.h>
 
 #define I_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
 #include <packagekit-glib2/packagekit.h>
 
 #include <gs-plugin.h>
 
+struct GsPluginPrivate {
+       GFileMonitor            *monitor;
+       gsize                    done_init;
+};
+
 /**
  * gs_plugin_get_name:
  */
@@ -47,6 +53,64 @@ gs_plugin_get_priority (GsPlugin *plugin)
 #define PK_PREPARED_UPDATE_FN  "/var/lib/PackageKit/prepared-update"
 
 /**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+       if (plugin->priv->monitor != NULL)
+               g_object_unref (plugin->priv->monitor);
+}
+
+/**
+ * gs_plugin_systemd_updates_changed_cb:
+ */
+static void
+gs_plugin_systemd_updates_changed_cb (GFileMonitor *monitor,
+                                     GFile *file, GFile *other_file,
+                                     GFileMonitorEvent event_type,
+                                     gpointer user_data)
+{
+       GsPlugin *plugin = GS_PLUGIN (user_data);
+       gs_plugin_updates_changed (plugin);
+}
+
+/**
+ * gs_plugin_startup:
+ */
+static gboolean
+gs_plugin_startup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+       GFile *file;
+       gboolean ret = TRUE;
+
+       file = g_file_new_for_path (PK_PREPARED_UPDATE_FN);
+       plugin->priv->monitor = g_file_monitor_file (file,
+                                                    G_FILE_MONITOR_NONE,
+                                                    cancellable,
+                                                    error);
+       if (plugin->priv->monitor == NULL) {
+               ret = FALSE;
+               goto out;
+       }
+       g_signal_connect (plugin->priv->monitor, "changed",
+                         G_CALLBACK (gs_plugin_systemd_updates_changed_cb),
+                         plugin);
+out:
+       g_object_unref (file);
+       return ret;
+}
+
+/**
  * gs_plugin_add_updates:
  */
 gboolean
@@ -62,6 +126,14 @@ gs_plugin_add_updates (GsPlugin *plugin,
        gchar *data = NULL;
        guint i;
 
+       /* watch the file in case it comes or goes */
+       if (g_once_init_enter (&plugin->priv->done_init)) {
+               ret = gs_plugin_startup (plugin, cancellable, error);
+               g_once_init_leave (&plugin->priv->done_init, TRUE);
+               if (!ret)
+                       goto out;
+       }
+
        /* does the file exist ? */
        if (!g_file_test (PK_PREPARED_UPDATE_FN, G_FILE_TEST_EXISTS)) {
                ret = TRUE;


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