[nautilus/f17] Show notifications on slow unmount/eject (#819492)

Tomas Bzatek tbzatek at fedoraproject.org
Tue May 15 18:16:17 UTC 2012


commit 35408864ef0192c7c33542dad8591fabef309586
Author: Tomas Bzatek <tbzatek at redhat.com>
Date:   Tue May 15 20:15:09 2012 +0200

    Show notifications on slow unmount/eject (#819492)

 nautilus-3.4.3-unmount-notification.patch |  336 +++++++++++++++++++++++++++++
 nautilus.spec                             |   14 +-
 2 files changed, 348 insertions(+), 2 deletions(-)
---
diff --git a/nautilus-3.4.3-unmount-notification.patch b/nautilus-3.4.3-unmount-notification.patch
new file mode 100644
index 0000000..d6aefbe
--- /dev/null
+++ b/nautilus-3.4.3-unmount-notification.patch
@@ -0,0 +1,336 @@
+diff -up nautilus-3.4.2/libnautilus-private/nautilus-file-operations.c.bak nautilus-3.4.2/libnautilus-private/nautilus-file-operations.c
+--- nautilus-3.4.2/libnautilus-private/nautilus-file-operations.c.bak	2012-05-14 21:37:55.000000000 +0200
++++ nautilus-3.4.2/libnautilus-private/nautilus-file-operations.c	2012-05-15 20:10:54.000000000 +0200
+@@ -66,6 +66,8 @@
+ #include "nautilus-file-undo-operations.h"
+ #include "nautilus-file-undo-manager.h"
+ 
++#include <libnotify/notify.h>
++
+ /* TODO: TESTING!!! */
+ 
+ typedef struct {
+@@ -2015,9 +2017,38 @@ typedef struct {
+ 	GtkWindow *parent_window;
+ 	NautilusUnmountCallback callback;
+ 	gpointer callback_data;
++	guint timeout_id;
++	NotifyNotification *notify;
+ } UnmountData;
+ 
+ static void
++pop_down_notification (UnmountData *data)
++{
++	if (data->timeout_id > 0) {
++		g_source_remove (data->timeout_id);
++		data->timeout_id = 0;
++	}
++
++	if (data->notify != NULL) {
++		notify_notification_close (data->notify, NULL);
++		g_object_unref (data->notify);
++		data->notify = NULL;
++	}
++}
++
++static void
++mount_op_show_processes (GMountOperation *op,
++                         gchar           *message,
++                         GArray          *processes,
++                         GStrv            choices,
++                         gpointer         user_data)
++{
++	UnmountData *data = user_data;
++
++	pop_down_notification (data);
++}
++
++static void
+ unmount_mount_callback (GObject *source_object,
+ 			GAsyncResult *res,
+ 			gpointer user_data)
+@@ -2038,6 +2069,7 @@ unmount_mount_callback (GObject *source_
+ 	
+ 	if (! unmounted) {
+ 		if (error->code != G_IO_ERROR_FAILED_HANDLED) {
++			pop_down_notification (data);
+ 			if (data->eject) {
+ 				primary = f (_("Unable to eject %V"), source_object);
+ 			} else {
+@@ -2058,11 +2090,45 @@ unmount_mount_callback (GObject *source_
+ 		g_error_free (error);
+ 	}
+ 	
++	if (data->timeout_id > 0)
++		g_source_remove (data->timeout_id);
++	
++	if (data->notify != NULL) {
++		/* Notification was shown, let's update it saying we're finished */
++		notify_notification_update (data->notify,
++					    _("You can now unplug the device"),
++					    NULL,
++					    "media-removable");
++	
++		notify_notification_set_urgency (data->notify, NOTIFY_URGENCY_LOW);
++		notify_notification_set_timeout (data->notify, NOTIFY_EXPIRES_DEFAULT);
++		notify_notification_show (data->notify, NULL);
++		g_object_unref (data->notify);
++	}
++	
+ 	eel_remove_weak_pointer (&data->parent_window);
+ 	g_object_unref (data->mount);
+ 	g_free (data);
+ }
+ 
++static gboolean
++eject_timeout (gpointer user_data)
++{
++	UnmountData *data = user_data;
++
++	data->timeout_id = 0;
++
++	data->notify = notify_notification_new (_("Writing data to device"),
++						_("Don't unplug until finished"),
++						"media-removable");
++	notify_notification_set_urgency (data->notify, NOTIFY_URGENCY_CRITICAL);
++	notify_notification_set_timeout (data->notify, NOTIFY_EXPIRES_NEVER);
++
++	notify_notification_show (data->notify, NULL);
++
++	return FALSE;
++}
++
+ static void
+ do_unmount (UnmountData *data)
+ {
+@@ -2084,6 +2150,11 @@ do_unmount (UnmountData *data)
+ 						unmount_mount_callback,
+ 						data);
+ 	}
++
++	data->timeout_id = g_timeout_add_seconds (1, (GSourceFunc) eject_timeout, data);
++	g_signal_connect (G_OBJECT (mount_op), "show-processes",
++			  G_CALLBACK (mount_op_show_processes), data);
++
+ 	g_object_unref (mount_op);
+ }
+ 
+diff -up nautilus-3.4.2/src/nautilus-places-sidebar.c.bak nautilus-3.4.2/src/nautilus-places-sidebar.c
+--- nautilus-3.4.2/src/nautilus-places-sidebar.c.bak	2012-05-14 21:37:55.000000000 +0200
++++ nautilus-3.4.2/src/nautilus-places-sidebar.c	2012-05-15 20:08:38.000000000 +0200
+@@ -53,6 +53,8 @@
+ #include "nautilus-window.h"
+ #include "nautilus-window-slot.h"
+ 
++#include <libnotify/notify.h>
++
+ #define DEBUG_FLAG NAUTILUS_DEBUG_PLACES
+ #include <libnautilus-private/nautilus-debug.h>
+ 
+@@ -2134,22 +2136,79 @@ unmount_shortcut_cb (GtkMenuItem
+ 	do_unmount_selection (sidebar);
+ }
+ 
++typedef struct {
++	NautilusWindow *window;
++	GMountOperation *mount_op;
++	guint timeout_id;
++	NotifyNotification *notify;
++} EjectOpData;
++
++static void
++free_eject_op_data (EjectOpData *data)
++{
++	if (data->timeout_id > 0)
++		g_source_remove (data->timeout_id);
++
++	if (data->notify != NULL) {
++		/* Notification was shown, let's update it saying we're finished */
++		notify_notification_update (data->notify,
++					    _("You can now unplug the device"),
++					    NULL,
++					    "media-removable");
++
++		notify_notification_set_urgency (data->notify, NOTIFY_URGENCY_LOW);
++		notify_notification_set_timeout (data->notify, NOTIFY_EXPIRES_DEFAULT);
++		notify_notification_show (data->notify, NULL);
++		g_object_unref (data->notify);
++	}
++
++	g_object_unref (data->mount_op);
++	g_free (data);
++}
++
++static void
++pop_down_notification (EjectOpData *data)
++{
++	if (data->timeout_id > 0) {
++		g_source_remove (data->timeout_id);
++		data->timeout_id = 0;
++	}
++
++	if (data->notify != NULL) {
++		notify_notification_close (data->notify, NULL);
++		g_object_unref (data->notify);
++		data->notify = NULL;
++	}
++}
++
++static void
++mount_op_show_processes (GMountOperation *op,
++                         gchar           *message,
++                         GArray          *processes,
++                         GStrv            choices,
++                         gpointer         user_data)
++{
++	EjectOpData *data = user_data;
++
++	pop_down_notification (data);
++}
++
+ static void
+ drive_eject_cb (GObject *source_object,
+ 		GAsyncResult *res,
+ 		gpointer user_data)
+ {
+-	NautilusWindow *window;
++	EjectOpData *data = user_data;
+ 	GError *error;
+ 	char *primary;
+ 	char *name;
+ 
+-	window = user_data;
+-	g_object_unref (window);
++	g_object_unref (data->window);
+ 
+ 	error = NULL;
+ 	if (!g_drive_eject_with_operation_finish (G_DRIVE (source_object), res, &error)) {
+ 		if (error->code != G_IO_ERROR_FAILED_HANDLED) {
++			pop_down_notification (data);
+ 			name = g_drive_get_name (G_DRIVE (source_object));
+ 			primary = g_strdup_printf (_("Unable to eject %s"), name);
+ 			g_free (name);
+@@ -2160,6 +2219,8 @@ drive_eject_cb (GObject *source_object,
+ 		}
+ 		g_error_free (error);
+ 	}
++
++	free_eject_op_data (data);
+ }
+ 
+ static void
+@@ -2167,17 +2228,17 @@ volume_eject_cb (GObject *source_object,
+ 		GAsyncResult *res,
+ 		gpointer user_data)
+ {
+-	NautilusWindow *window;
++	EjectOpData *data = user_data;
+ 	GError *error;
+ 	char *primary;
+ 	char *name;
+ 
+-	window = user_data;
+-	g_object_unref (window);
++	g_object_unref (data->window);
+ 
+ 	error = NULL;
+ 	if (!g_volume_eject_with_operation_finish (G_VOLUME (source_object), res, &error)) {
+ 		if (error->code != G_IO_ERROR_FAILED_HANDLED) {
++			pop_down_notification (data);
+ 			name = g_volume_get_name (G_VOLUME (source_object));
+ 			primary = g_strdup_printf (_("Unable to eject %s"), name);
+ 			g_free (name);
+@@ -2188,6 +2249,8 @@ volume_eject_cb (GObject *source_object,
+ 		}
+ 		g_error_free (error);
+ 	}
++
++	free_eject_op_data (data);
+ }
+ 
+ static void
+@@ -2195,17 +2258,17 @@ mount_eject_cb (GObject *source_object,
+ 		GAsyncResult *res,
+ 		gpointer user_data)
+ {
+-	NautilusWindow *window;
++	EjectOpData *data = user_data;
+ 	GError *error;
+ 	char *primary;
+ 	char *name;
+ 
+-	window = user_data;
+-	g_object_unref (window);
++	g_object_unref (data->window);
+ 
+ 	error = NULL;
+ 	if (!g_mount_eject_with_operation_finish (G_MOUNT (source_object), res, &error)) {
+ 		if (error->code != G_IO_ERROR_FAILED_HANDLED) {
++			pop_down_notification (data);
+ 			name = g_mount_get_name (G_MOUNT (source_object));
+ 			primary = g_strdup_printf (_("Unable to eject %s"), name);
+ 			g_free (name);
+@@ -2216,6 +2279,26 @@ mount_eject_cb (GObject *source_object,
+ 		}
+ 		g_error_free (error);
+ 	}
++
++	free_eject_op_data (data);
++}
++
++static gboolean
++eject_timeout (gpointer user_data)
++{
++	EjectOpData *data = user_data;
++
++	data->timeout_id = 0;
++
++	data->notify = notify_notification_new (_("Writing data to device"),
++						_("Don't unplug until finished"),
++						"media-removable");
++	notify_notification_set_urgency (data->notify, NOTIFY_URGENCY_CRITICAL);
++	notify_notification_set_timeout (data->notify, NOTIFY_EXPIRES_NEVER);
++
++	notify_notification_show (data->notify, NULL);
++
++	return FALSE;
+ }
+ 
+ static void
+@@ -2224,20 +2307,27 @@ do_eject (GMount *mount,
+ 	  GDrive *drive,
+ 	  NautilusPlacesSidebar *sidebar)
+ {
+-	GMountOperation *mount_op;
++	EjectOpData *data;
++
++
++	data = g_malloc0 (sizeof (EjectOpData));
++	data->window = g_object_ref (sidebar->window);
++	data->mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
+ 
+-	mount_op = gtk_mount_operation_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (sidebar))));
+ 	if (mount != NULL) {
+-		g_mount_eject_with_operation (mount, 0, mount_op, NULL, mount_eject_cb,
+-					      g_object_ref (sidebar->window));
++		g_mount_eject_with_operation (mount, 0, data->mount_op, NULL, mount_eject_cb, data);
+ 	} else if (volume != NULL) {
+-		g_volume_eject_with_operation (volume, 0, mount_op, NULL, volume_eject_cb,
+-					      g_object_ref (sidebar->window));
++		g_volume_eject_with_operation (volume, 0, data->mount_op, NULL, volume_eject_cb, data);
+ 	} else if (drive != NULL) {
+-		g_drive_eject_with_operation (drive, 0, mount_op, NULL, drive_eject_cb,
+-					      g_object_ref (sidebar->window));
++		g_drive_eject_with_operation (drive, 0, data->mount_op, NULL, drive_eject_cb, data);
++	}
++
++	/* Display a notification of ongoing operation after a timeout */
++	if (mount != NULL || volume != NULL || drive != NULL) {
++		data->timeout_id = g_timeout_add_seconds (1, (GSourceFunc) eject_timeout, data);
++		g_signal_connect (G_OBJECT (data->mount_op), "show-processes",
++				  G_CALLBACK (mount_op_show_processes), data);
+ 	}
+-	g_object_unref (mount_op);
+ }
+ 
+ static void
diff --git a/nautilus.spec b/nautilus.spec
index 4ed8ad6..6a0982e 100644
--- a/nautilus.spec
+++ b/nautilus.spec
@@ -13,10 +13,10 @@
 Name:           nautilus
 Summary:        File manager for GNOME
 Version:        3.4.2
-Release:        1%{?dist}
+Release:        2%{?dist}
 License:        GPLv2+
 Group:          User Interface/Desktops
-Source:         http://download.gnome.org/sources/%{name}/3.3/%{name}-%{version}.tar.xz
+Source:         http://download.gnome.org/sources/%{name}/3.4/%{name}-%{version}.tar.xz
 
 URL:            http://projects.gnome.org/nautilus/
 Requires:       redhat-menus >= %{redhat_menus_version}
@@ -65,6 +65,12 @@ Provides:       eel2 = 2.26.0-3
 Patch7:         rtl-fix.patch
 #Patch8:        nautilus-2.22.1-hide-white-screen.patch
 
+
+# GVfs apps should convey when eject/unmount takes a long time
+# https://bugzilla.redhat.com/show_bug.cgi?id=819492
+Patch9:         nautilus-3.4.3-unmount-notification.patch
+
+
 %description
 Nautilus is the file manager and graphical shell for the GNOME desktop
 that makes it easy to manage your files and the rest of your system.
@@ -98,6 +104,7 @@ for developing nautilus extensions.
 
 #%patch4 -p1 -b .selinux
 %patch7 -p1 -b .rtl-fix
+# %patch9 -p1 -b .unmount-notification
 
 %build
 
@@ -185,6 +192,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas >&/dev/null || :
 %doc %{_datadir}/gtk-doc/html/libnautilus-extension/*
 
 %changelog
+* Tue May 15 2012 Tomas Bzatek <tbzatek at redhat.com> - 3.4.2-2
+- Show notifications on slow unmount/eject (#819492)
+
 * Tue May 15 2012 Richard Hughes <hughsient at gmail.com> - 3.4.2-1
 - Update to 3.4.2
 


More information about the scm-commits mailing list