[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