From effa1336d671a8e37d14c9791857b7d1f678fe75 Mon Sep 17 00:00:00 2001
From: Damjan Jovanovic <damjan.jov@gmail.com>
Date: Tue, 23 Feb 2021 12:31:09 +0100
Subject: [PATCH] Improve device unmount messages (Issue #516)

Use glib's gio's GMountOperation's "show-unmount-progress" signal to update our notification, and extend its timeout to 5 seconds as 2 isn't long enough to read the notification.

Fixes #516

Fixes !64
---
 thunar/thunar-device.c | 39 +++++++++++++++++++++-----
 thunar/thunar-notify.c | 63 ++++++++++++++++++++++++++++++++++++++----
 thunar/thunar-notify.h |  2 ++
 3 files changed, 91 insertions(+), 13 deletions(-)

diff --git a/thunar/thunar-device.c b/thunar/thunar-device.c
index 932ca05f9..7a50ce9cd 100644
--- a/thunar/thunar-device.c
+++ b/thunar/thunar-device.c
@@ -83,6 +83,12 @@ typedef struct
   /* the device the operation is working on */
   ThunarDevice         *device;
 
+  /* for user interaction during the [un]mount operation */
+  GMountOperation *mount_operation;
+
+  /* the handler ID for the show-umount-progress signal */
+  gulong unmount_progress_signal_id;
+
   /* finish function for the async callback */
   AsyncCallbackFinish   callback_finish;
 
@@ -222,8 +228,22 @@ thunar_device_set_property (GObject      *object,
 
 
 
+static void
+show_unmount_progress_cb (GMountOperation *mount_operation,
+                          const gchar     *message_to_show,
+                          gint64           time_left,
+                          gint64           bytes_left,
+                          ThunarDevice    *device)
+{
+  if (message_to_show != NULL)
+    thunar_notify_progress (device, message_to_show);
+}
+
+
+
 static ThunarDeviceOperation *
 thunar_device_operation_new (ThunarDevice         *device,
+                             GMountOperation      *mount_operation,
                              ThunarDeviceCallback  callback,
                              gpointer              user_data,
                              gpointer              callback_finish)
@@ -232,6 +252,9 @@ thunar_device_operation_new (ThunarDevice         *device,
 
   op = g_slice_new0 (ThunarDeviceOperation);
   op->device = g_object_ref (device);
+  op->mount_operation = g_object_ref (mount_operation);
+  op->unmount_progress_signal_id = g_signal_connect (mount_operation,
+      "show-unmount-progress", G_CALLBACK (show_unmount_progress_cb), device);
   op->callback = callback;
   op->callback_finish = callback_finish;
   op->user_data = user_data;
@@ -276,6 +299,8 @@ thunar_device_operation_finish (GObject      *object,
 
   /* cleanup */
   g_clear_error (&error);
+  g_signal_handler_disconnect (op->mount_operation, op->unmount_progress_signal_id);
+  g_object_unref (G_OBJECT (op->mount_operation));
   g_object_unref (G_OBJECT (op->device));
   g_slice_free (ThunarDeviceOperation, op);
 }
@@ -629,7 +654,7 @@ thunar_device_mount (ThunarDevice         *device,
 
   if (G_IS_VOLUME (device->device))
     {
-      op = thunar_device_operation_new (device, callback, user_data,
+      op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                         g_volume_mount_finish);
       g_volume_mount (G_VOLUME (device->device),
                       G_MOUNT_MOUNT_NONE,
@@ -680,7 +705,7 @@ thunar_device_unmount (ThunarDevice         *device,
 
           /* try unmounting the mount */
           thunar_device_emit_pre_unmount (device, FALSE);
-          op = thunar_device_operation_new (device, callback, user_data,
+          op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                             g_mount_unmount_with_operation_finish);
           g_mount_unmount_with_operation (mount,
                                           G_MOUNT_UNMOUNT_NONE,
@@ -732,7 +757,7 @@ thunar_device_eject (ThunarDevice         *device,
 
               /* try to stop the drive */
               thunar_device_emit_pre_unmount (device, TRUE);
-              op = thunar_device_operation_new (device, callback, user_data,
+              op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                                 g_drive_stop_finish);
               g_drive_stop (drive,
                             G_MOUNT_UNMOUNT_NONE,
@@ -753,7 +778,7 @@ thunar_device_eject (ThunarDevice         *device,
 
               /* try to stop the drive */
               thunar_device_emit_pre_unmount (device, TRUE);
-              op = thunar_device_operation_new (device, callback, user_data,
+              op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                                 g_drive_eject_with_operation_finish);
               g_drive_eject_with_operation (drive,
                                             G_MOUNT_UNMOUNT_NONE,
@@ -778,7 +803,7 @@ thunar_device_eject (ThunarDevice         *device,
 
           /* try ejecting the volume */
           thunar_device_emit_pre_unmount (device, TRUE);
-          op = thunar_device_operation_new (device, callback, user_data,
+          op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                             g_volume_eject_with_operation_finish);
           g_volume_eject_with_operation (volume,
                                          G_MOUNT_UNMOUNT_NONE,
@@ -813,7 +838,7 @@ thunar_device_eject (ThunarDevice         *device,
 
           /* try ejecting the mount */
           thunar_device_emit_pre_unmount (device, FALSE);
-          op = thunar_device_operation_new (device, callback, user_data,
+          op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                             g_mount_eject_with_operation_finish);
           g_mount_eject_with_operation (mount,
                                         G_MOUNT_UNMOUNT_NONE,
@@ -829,7 +854,7 @@ thunar_device_eject (ThunarDevice         *device,
 
           /* try unmounting the mount */
           thunar_device_emit_pre_unmount (device, FALSE);
-          op = thunar_device_operation_new (device, callback, user_data,
+          op = thunar_device_operation_new (device, mount_operation, callback, user_data,
                                             g_mount_unmount_with_operation_finish);
           g_mount_unmount_with_operation (mount,
                                           G_MOUNT_UNMOUNT_NONE,
diff --git a/thunar/thunar-notify.c b/thunar/thunar-notify.c
index 17e653c15..f6e9e9b6c 100644
--- a/thunar/thunar-notify.c
+++ b/thunar/thunar-notify.c
@@ -62,12 +62,9 @@ thunar_notify_init (void)
 
 
 
-static void
-thunar_notify_show (ThunarDevice *device,
-                    const gchar  *summary,
-                    const gchar  *message)
+static gchar*
+thunar_get_device_icon (ThunarDevice *device)
 {
-  NotifyNotification *notification;
   GIcon              *icon;
   gchar              *icon_name = NULL;
   GFile              *icon_file;
@@ -95,6 +92,21 @@ thunar_notify_show (ThunarDevice *device,
   if (icon_name == NULL)
     icon_name = g_strdup ("drive-removable-media");
 
+  return icon_name;
+}
+
+
+
+static void
+thunar_notify_show (ThunarDevice *device,
+                    const gchar  *summary,
+                    const gchar  *message)
+{
+  NotifyNotification *notification;
+  gchar              *icon_name;
+
+  icon_name = thunar_get_device_icon (device);
+
   /* create notification */
 #ifdef NOTIFY_CHECK_VERSION
 #if NOTIFY_CHECK_VERSION (0, 7, 0)
@@ -148,6 +160,45 @@ thunar_notify_device_readonly (ThunarDevice *device)
 
 
 
+void
+thunar_notify_progress (ThunarDevice *device,
+                         const gchar *message)
+{
+#ifdef HAVE_LIBNOTIFY
+  NotifyNotification *notification;
+
+  _thunar_return_if_fail (THUNAR_IS_DEVICE (device));
+
+  notification = g_object_get_data (G_OBJECT (device), I_("thunar-notification"));
+  if (notification != NULL)
+    {
+      gchar *icon_name;
+      gchar *summary;
+      gchar *body;
+      gchar *endln;
+
+      icon_name = thunar_get_device_icon (device);
+      body = NULL;
+      endln = g_strstr_len (message, -1, "\n");
+      if (endln == NULL)
+        summary = g_strdup (message);
+      else
+        {
+          summary = g_strndup (message, endln - message);
+          body = endln + 1;
+        }
+      notify_notification_update (notification, summary, body, icon_name);
+
+      notify_notification_show (notification, NULL);
+
+      g_free (summary);
+      g_free (icon_name);
+    }
+#endif
+}
+
+
+
 void
 thunar_notify_unmount (ThunarDevice *device)
 {
@@ -239,7 +290,7 @@ thunar_notify_finish (ThunarDevice *device)
   if (notification != NULL)
     {
       notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
-      notify_notification_set_timeout (notification, 2000);
+      notify_notification_set_timeout (notification, 5000);
       notify_notification_show (notification, NULL);
 
       g_object_set_data (G_OBJECT (device), I_("thunar-notification"), NULL);
diff --git a/thunar/thunar-notify.h b/thunar/thunar-notify.h
index af17c87b9..8664107a9 100644
--- a/thunar/thunar-notify.h
+++ b/thunar/thunar-notify.h
@@ -30,6 +30,8 @@ void thunar_notify_unmount        (ThunarDevice *device);
 
 void thunar_notify_eject          (ThunarDevice *device);
 
+void thunar_notify_progress       (ThunarDevice *device, const gchar *message_to_show);
+
 void thunar_notify_finish         (ThunarDevice *device);
 
 void thunar_notify_uninit         (void);
-- 
GitLab