[gnome-settings-daemon] housekeeping: use a notification for low space warning



commit ad4b797a5dcdd7b4e0725784905728955544edb1
Author: William Jon McCann <jmccann redhat com>
Date:   Mon Nov 15 13:59:10 2010 -0500

    housekeeping: use a notification for low space warning
    
    Only fallback to a dialog if the notification server doesn't
    support actions.
    
    Further work is needed to provide a way to blacklist volumes.  Also
    we probably don't want to run these notifications in a loop over
    volumes since notifications are async and it isn't super nice to
    send a stream of bubbles to the user anyway.  Better to say
    multiple volumes are low on space.

 gnome-settings-daemon/Makefile.am     |    6 +-
 gnome-settings-daemon/main.c          |    3 +
 plugins/housekeeping/gsd-disk-space.c |  212 +++++++++++++++++++++++++++------
 3 files changed, 186 insertions(+), 35 deletions(-)
---
diff --git a/gnome-settings-daemon/Makefile.am b/gnome-settings-daemon/Makefile.am
index 3aeee66..6e7ce29 100644
--- a/gnome-settings-daemon/Makefile.am
+++ b/gnome-settings-daemon/Makefile.am
@@ -8,6 +8,7 @@ INCLUDES = \
 	$(WARN_CFLAGS)						\
 	$(DISABLE_DEPRECATED_CFLAGS)				\
 	$(SETTINGS_DAEMON_CFLAGS)				\
+	$(LIBNOTIFY_CFLAGS)		\
 	$(NULL)
 
 noinst_LTLIBRARIES = 			\
@@ -78,7 +79,10 @@ gnome_settings_daemon_LDFLAGS = 	\
 
 gnome_settings_daemon_LDADD = 		\
 	libgsd-profile.la		\
-	$(SETTINGS_DAEMON_LIBS)
+	$(SETTINGS_DAEMON_LIBS)		\
+	$(LIBNOTIFY_LIBS)		\
+	$(NULL)
+
 
 EXTRA_DIST = 				\
 	$(Dbusapi_DATA)			\
diff --git a/gnome-settings-daemon/main.c b/gnome-settings-daemon/main.c
index 0e9ebf9..a6bc26c 100644
--- a/gnome-settings-daemon/main.c
+++ b/gnome-settings-daemon/main.c
@@ -32,6 +32,7 @@
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
 #include <gio/gio.h>
+#include <libnotify/notify.h>
 
 #include "gnome-settings-manager.h"
 #include "gnome-settings-profile.h"
@@ -270,6 +271,8 @@ main (int argc, char *argv[])
 
         g_log_set_default_handler (gsd_log_default_handler, NULL);
 
+        notify_init ("gnome-settings-daemon");
+
         bus_register ();
 
         gnome_settings_profile_start ("gnome_settings_manager_new");
diff --git a/plugins/housekeeping/gsd-disk-space.c b/plugins/housekeeping/gsd-disk-space.c
index d9bd1a1..7d793f0 100644
--- a/plugins/housekeeping/gsd-disk-space.c
+++ b/plugins/housekeeping/gsd-disk-space.c
@@ -35,6 +35,7 @@
 #include <gio/gunixmounts.h>
 #include <gio/gio.h>
 #include <gtk/gtk.h>
+#include <libnotify/notify.h>
 
 #include "gsd-disk-space.h"
 #include "gsd-ldsm-dialog.h"
@@ -71,6 +72,8 @@ static unsigned int       min_notify_period = 10;
 static GSList            *ignore_paths = NULL;
 static GSettings         *settings = NULL;
 static GsdLdsmDialog     *dialog = NULL;
+static NotifyNotification *notification = NULL;
+
 static guint64           *time_read;
 
 static gchar*
@@ -169,6 +172,71 @@ ldsm_analyze_path (const gchar *path)
 }
 
 static gboolean
+server_has_actions (void)
+{
+        gboolean has;
+        GList   *caps;
+        GList   *l;
+
+        caps = notify_get_server_caps ();
+        if (caps == NULL) {
+                fprintf (stderr, "Failed to receive server caps.\n");
+                return FALSE;
+        }
+
+        l = g_list_find_custom (caps, "actions", (GCompareFunc)strcmp);
+        has = l != NULL;
+
+        g_list_foreach (caps, (GFunc) g_free, NULL);
+        g_list_free (caps);
+
+        return has;
+}
+
+static void
+ignore_callback (NotifyNotification *n,
+                 const char         *action)
+{
+        g_assert (action != NULL);
+        g_assert (strcmp (action, "ignore") == 0);
+
+        /* Do nothing */
+
+        notify_notification_close (n, NULL);
+}
+
+static void
+examine_callback (NotifyNotification *n,
+                  const char         *action,
+                  const char         *path)
+{
+        g_assert (action != NULL);
+        g_assert (strcmp (action, "examine") == 0);
+
+        ldsm_analyze_path (path);
+
+        notify_notification_close (n, NULL);
+}
+
+static void
+empty_trash_callback (NotifyNotification *n,
+                      const char         *action)
+{
+        g_assert (action != NULL);
+        g_assert (strcmp (action, "empty-trash") == 0);
+
+        gsd_ldsm_trash_empty ();
+
+        notify_notification_close (n, NULL);
+}
+
+static void
+on_notification_closed (NotifyNotification *notification)
+{
+        notification = NULL;
+}
+
+static gboolean
 ldsm_notify_for_mount (LdsmMountInfo *mount,
                        gboolean       multiple_volumes,
                        gboolean       other_usable_volumes)
@@ -181,8 +249,8 @@ ldsm_notify_for_mount (LdsmMountInfo *mount,
         gboolean retval = TRUE;
         gchar *path;
 
-        /* Don't show a dialog if one is already displayed */
-        if (dialog)
+        /* Don't show a notice if one is already displayed */
+        if (dialog != NULL || notification != NULL)
                 return retval;
 
         name = g_unix_mount_guess_name (mount->mount);
@@ -194,42 +262,113 @@ ldsm_notify_for_mount (LdsmMountInfo *mount,
         has_disk_analyzer = (program != NULL);
         g_free (program);
 
-        dialog = gsd_ldsm_dialog_new (other_usable_volumes,
-                                      multiple_volumes,
-                                      has_disk_analyzer,
-                                      has_trash,
-                                      free_space,
-                                      name,
-                                      path);
+        if (server_has_actions ()) {
+                char *free_space_str;
+                char *summary;
+                char *body;
 
-        g_free (name);
+                free_space_str = g_format_size_for_display (free_space);
 
-        g_object_ref (G_OBJECT (dialog));
-        response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-        gtk_widget_destroy (GTK_WIDGET (dialog));
-        dialog = NULL;
-
-        switch (response) {
-        case GTK_RESPONSE_CANCEL:
-                retval = FALSE;
-                break;
-        case GSD_LDSM_DIALOG_RESPONSE_ANALYZE:
-                retval = FALSE;
-                ldsm_analyze_path (path);
-                break;
-        case GSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH:
-                retval = TRUE;
-                gsd_ldsm_trash_empty ();
-                break;
-        case GTK_RESPONSE_NONE:
-        case GTK_RESPONSE_DELETE_EVENT:
-                retval = TRUE;
-                break;
-        default:
-                g_assert_not_reached ();
+                if (multiple_volumes) {
+                        summary = g_strdup_printf (_("Low Disk Space on \"%s\""), name);
+                        if (has_trash) {
+                                body = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining.  You may free up some space by emptying the trash."),
+                                                        name,
+                                                        free_space_str);
+                        } else {
+                                body = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining."),
+                                                        name,
+                                                        free_space_str);
+                        }
+                } else {
+                        summary = g_strdup (_("Low Disk Space"));
+                        if (has_trash) {
+                                body = g_strdup_printf (_("This computer has only %s disk space remaining.  You may free up some space by emptying the trash."),
+                                                        free_space_str);
+                        } else {
+                                body = g_strdup_printf (_("This computer has only %s disk space remaining."),
+                                                        free_space_str);
+                        }
+                }
+                g_free (free_space_str);
+
+                notification = notify_notification_new (summary, body, NULL);
+                g_free (summary);
+                g_free (body);
+
+                g_signal_connect (notification,
+                                  "closed",
+                                  G_CALLBACK (on_notification_closed),
+                                  NULL);
+
+                notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE));
+                notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
+                notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT);
+                if (has_disk_analyzer) {
+                        notify_notification_add_action (notification,
+                                                        "examine",
+                                                        _("Examine"),
+                                                        (NotifyActionCallback) examine_callback,
+                                                        g_strdup (path),
+                                                        g_free);
+                }
+                if (has_trash) {
+                        notify_notification_add_action (notification,
+                                                        "empty-trash",
+                                                        _("Empty Trash"),
+                                                        (NotifyActionCallback) empty_trash_callback,
+                                                        NULL,
+                                                        NULL);
+                }
+                notify_notification_add_action (notification,
+                                                "ignore",
+                                                _("Ignore"),
+                                                (NotifyActionCallback) ignore_callback,
+                                                NULL,
+                                                NULL);
+                notify_notification_set_category (notification, "device");
+
+                if (!notify_notification_show (notification, NULL)) {
+                        g_warning ("failed to send disk space notification\n");
+                }
+
+        } else {
+                dialog = gsd_ldsm_dialog_new (other_usable_volumes,
+                                              multiple_volumes,
+                                              has_disk_analyzer,
+                                              has_trash,
+                                              free_space,
+                                              name,
+                                              path);
+
+                g_object_ref (G_OBJECT (dialog));
+                response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+                gtk_widget_destroy (GTK_WIDGET (dialog));
+                dialog = NULL;
+
+                switch (response) {
+                case GTK_RESPONSE_CANCEL:
+                        retval = FALSE;
+                        break;
+                case GSD_LDSM_DIALOG_RESPONSE_ANALYZE:
+                        retval = FALSE;
+                        ldsm_analyze_path (path);
+                        break;
+                case GSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH:
+                        retval = TRUE;
+                        gsd_ldsm_trash_empty ();
+                        break;
+                case GTK_RESPONSE_NONE:
+                case GTK_RESPONSE_DELETE_EVENT:
+                        retval = TRUE;
+                        break;
+                default:
+                        g_assert_not_reached ();
+                }
         }
 
+        g_free (name);
         g_free (path);
 
         return retval;
@@ -687,6 +826,11 @@ gsd_ldsm_clean (void)
                 dialog = NULL;
         }
 
+        if (notification != NULL) {
+                notify_notification_close (notification, NULL);
+                notification = NULL;
+        }
+
         if (ignore_paths) {
                 g_slist_foreach (ignore_paths, (GFunc) g_free, NULL);
                 g_slist_free (ignore_paths);



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