[gnome-software] Show an in-app notification when installed plugins are changed



commit b022cd0e408bfd138e456e19496878025f4fceea
Author: Richard Hughes <richard hughsie com>
Date:   Tue Dec 6 12:40:56 2016 +0000

    Show an in-app notification when installed plugins are changed
    
    This could happen when installing an optional gnome-software plugin or during
    an unsupported live update of gnome-software.

 src/gs-plugin-loader.c |   41 +++++++++++++++++++++++++++++++++++++++++
 src/gs-plugin-types.h  |    2 ++
 src/gs-plugin.c        |    2 ++
 src/gs-shell.c         |   16 ++++++++++++++++
 4 files changed, 61 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 508f58e..4b42016 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -48,6 +48,7 @@ typedef struct
        AsProfile               *profile;
        SoupSession             *soup_session;
        GPtrArray               *auth_array;
+       GFileMonitor            *file_monitor;
 
        GMutex                   pending_apps_mutex;
        GPtrArray               *pending_apps;
@@ -3482,6 +3483,34 @@ gs_plugin_loader_plugin_sort_fn (gconstpointer a, gconstpointer b)
        return 0;
 }
 
+static void
+gs_plugin_loader_plugin_dir_changed_cb (GFileMonitor *monitor,
+                                       GFile *file,
+                                       GFile *other_file,
+                                       GFileMonitorEvent event_type,
+                                       GsPluginLoader *plugin_loader)
+{
+       GsPluginLoaderPrivate *priv = gs_plugin_loader_get_instance_private (plugin_loader);
+       GsApp *app;
+       g_autoptr(GsPluginEvent) event = gs_plugin_event_new ();
+       g_autoptr(GError) error = NULL;
+
+       /* add app */
+       gs_plugin_event_set_action (event, GS_PLUGIN_ACTION_SETUP);
+       app = gs_app_list_lookup (priv->global_cache,
+               "system/*/*/*/org.gnome.Software.desktop/*");
+       if (app != NULL)
+               gs_plugin_event_set_app (event, app);
+
+       /* add error */
+       g_set_error_literal (&error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_RESTART_REQUIRED,
+                            "A restart is required");
+       gs_plugin_event_set_error (event, error);
+       gs_plugin_loader_add_event (plugin_loader, event);
+}
+
 /**
  * gs_plugin_loader_setup:
  * @plugin_loader: a #GsPluginLoader
@@ -3513,11 +3542,22 @@ gs_plugin_loader_setup (GsPluginLoader *plugin_loader,
        guint i;
        guint j;
        g_autoptr(GDir) dir = NULL;
+       g_autoptr(GFile) plugin_dir = NULL;
        g_autoptr(AsProfileTask) ptask = NULL;
        g_autoptr(GsPluginLoaderJob) job = NULL;
 
        g_return_val_if_fail (priv->location != NULL, FALSE);
 
+       plugin_dir = g_file_new_for_path (priv->location);
+       priv->file_monitor = g_file_monitor_directory (plugin_dir,
+                                                      G_FILE_MONITOR_NONE,
+                                                      cancellable,
+                                                      error);
+       if (priv->file_monitor == NULL)
+               return FALSE;
+       g_signal_connect (priv->file_monitor, "changed",
+                         G_CALLBACK (gs_plugin_loader_plugin_dir_changed_cb), plugin_loader);
+
        /* search in the plugin directory for plugins */
        ptask = as_profile_start_literal (priv->profile, "GsPlugin::setup");
        g_assert (ptask != NULL);
@@ -3834,6 +3874,7 @@ gs_plugin_loader_finalize (GObject *object)
        g_free (priv->locale);
        g_free (priv->language);
        g_object_unref (priv->global_cache);
+       g_object_unref (priv->file_monitor);
        g_hash_table_unref (priv->events_by_id);
        g_hash_table_unref (priv->disallow_updates);
 
diff --git a/src/gs-plugin-types.h b/src/gs-plugin-types.h
index aa18f0e..273345d 100644
--- a/src/gs-plugin-types.h
+++ b/src/gs-plugin-types.h
@@ -89,6 +89,7 @@ typedef guint64 GsPluginFlags;
  * @GS_PLUGIN_ERROR_WRITE_FAILED:              The save-to-disk failed
  * @GS_PLUGIN_ERROR_INVALID_FORMAT:            The data format is invalid
  * @GS_PLUGIN_ERROR_DELETE_FAILED:             The delete action failed
+ * @GS_PLUGIN_ERROR_RESTART_REQUIRED:          A restart is required
  *
  * The failure error types.
  **/
@@ -109,6 +110,7 @@ typedef enum {
        GS_PLUGIN_ERROR_WRITE_FAILED,
        GS_PLUGIN_ERROR_INVALID_FORMAT,
        GS_PLUGIN_ERROR_DELETE_FAILED,
+       GS_PLUGIN_ERROR_RESTART_REQUIRED,
        /*< private >*/
        GS_PLUGIN_ERROR_LAST
 } GsPluginError;
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index caa6681..8b22232 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -1415,6 +1415,8 @@ gs_plugin_error_to_string (GsPluginError error)
                return "invalid-format";
        if (error == GS_PLUGIN_ERROR_DELETE_FAILED)
                return "delete-failed";
+       if (error == GS_PLUGIN_ERROR_RESTART_REQUIRED)
+               return "restart-required";
        return NULL;
 }
 
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 6b0f998..f4add93 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -1378,11 +1378,13 @@ gs_shell_show_event_file_to_app (GsShell *shell, GsPluginEvent *event)
 static gboolean
 gs_shell_show_event_fallback (GsShell *shell, GsPluginEvent *event)
 {
+       GsApp *app = gs_plugin_event_get_app (event);
        GsApp *origin = gs_plugin_event_get_origin (event);
        GsShellEventButtons buttons = GS_SHELL_EVENT_BUTTON_NONE;
        GsShellPrivate *priv = gs_shell_get_instance_private (shell);
        const GError *error = gs_plugin_event_get_error (event);
        g_autoptr(GString) str = g_string_new (NULL);
+       g_autofree gchar *str_app = NULL;
        g_autofree gchar *str_origin = NULL;
 
        switch (error->code) {
@@ -1402,6 +1404,20 @@ gs_shell_show_event_fallback (GsShell *shell, GsPluginEvent *event)
                                        "and try again"));
                buttons |= GS_SHELL_EVENT_BUTTON_NO_SPACE;
                break;
+       case GS_PLUGIN_ERROR_RESTART_REQUIRED:
+               if (app != NULL) {
+                       str_app = gs_shell_get_title_from_app (app);
+                       /* TRANSLATORS: failure text for the in-app notification,
+                        * where the %s is the application name (e.g. "GIMP") */
+                       g_string_append_printf (str, _("%s needs to be restarted "
+                                                      "to use new plugins."),
+                                               str_app);
+               } else {
+                       /* TRANSLATORS: failure text for the in-app notification */
+                       g_string_append (str, _("This application needs to be "
+                                               "restarted to use new plugins."));
+               }
+               break;
        default:
                break;
        }


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