[virt-tools-list] [remote-viewer] Make the progress bar smooth during file-transfer

Victor Toso victortoso at redhat.com
Wed May 10 12:35:02 UTC 2017


From: Victor Toso <me at victortoso.com>

When the transfer of a file finishes we stop considering that file's
size in the progress bar which makes it move back due the new
'transfer size' and 'transferred bytes' - for all the other files.

This patch aims to keep the progress smooth when a file is finished
using the notify::total-bytes from SpiceFileTransferTask to be aware
of all file's sizes.

Note that as we have only one progress bar for all files being
transferred, it is expected that it will go back when a new
file-transfer operation starts (e.g we drag-and-drop new files while
we are already transferring other files).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1449572
Signed-off-by: Victor Toso <victortoso at redhat.com>
---
 src/virt-viewer-file-transfer-dialog.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/virt-viewer-file-transfer-dialog.c b/src/virt-viewer-file-transfer-dialog.c
index 07d25a7..bff0cda 100644
--- a/src/virt-viewer-file-transfer-dialog.c
+++ b/src/virt-viewer-file-transfer-dialog.c
@@ -30,6 +30,8 @@ struct _VirtViewerFileTransferDialogPrivate
     GSList *failed;
     guint timer_show_src;
     guint timer_hide_src;
+    guint64 total_transfer_size;
+    guint64 completed_transfer_size;
     GtkWidget *transfer_summary;
     GtkWidget *progressbar;
 };
@@ -85,6 +87,8 @@ dialog_response(GtkDialog *dialog,
             for (slist = self->priv->file_transfers; slist != NULL; slist = g_slist_next(slist)) {
                 spice_file_transfer_task_cancel(SPICE_FILE_TRANSFER_TASK(slist->data));
             }
+            self->priv->total_transfer_size = 0;
+            self->priv->completed_transfer_size = 0;
             break;
         case GTK_RESPONSE_DELETE_EVENT:
             /* silently ignore */
@@ -128,20 +132,20 @@ virt_viewer_file_transfer_dialog_new(GtkWindow *parent)
 static void update_global_progress(VirtViewerFileTransferDialog *self)
 {
     GSList *slist;
-    guint64 total = 0, transferred = 0;
+    guint64 transferred = 0;
     gchar *message = NULL;
     guint n_files = 0;
     gdouble fraction = 1.0;
 
     for (slist = self->priv->file_transfers; slist != NULL; slist = g_slist_next(slist)) {
         SpiceFileTransferTask *task = slist->data;
-        total += spice_file_transfer_task_get_total_bytes(task);
         transferred += spice_file_transfer_task_get_transferred_bytes(task);
         n_files++;
     }
 
+    transferred += self->priv->completed_transfer_size;
     if (n_files > 0)
-        fraction = (gdouble)transferred / total;
+        fraction = (gdouble)transferred / self->priv->total_transfer_size;
     message = g_strdup_printf(ngettext("Transferring %d file...",
                                        "Transferring %d files...", n_files),
                               n_files);
@@ -159,6 +163,18 @@ static void task_progress_notify(GObject *object G_GNUC_UNUSED,
     update_global_progress(self);
 }
 
+static void task_total_bytes_notify(GObject *object,
+                                    GParamSpec *pspec G_GNUC_UNUSED,
+                                    gpointer user_data)
+{
+    VirtViewerFileTransferDialog *self = VIRT_VIEWER_FILE_TRANSFER_DIALOG(user_data);
+    SpiceFileTransferTask *task = SPICE_FILE_TRANSFER_TASK(object);
+
+    self->priv->total_transfer_size += spice_file_transfer_task_get_total_bytes(task);
+    update_global_progress(self);
+}
+
+
 static void
 error_dialog_response(GtkDialog *dialog,
                       gint response_id G_GNUC_UNUSED,
@@ -222,11 +238,14 @@ static void task_finished(SpiceFileTransferTask *task,
     }
 
     self->priv->file_transfers = g_slist_remove(self->priv->file_transfers, task);
+    self->priv->completed_transfer_size += spice_file_transfer_task_get_total_bytes(task);
     g_object_unref(task);
     update_global_progress(self);
 
     /* if this is the last transfer, close the dialog */
     if (self->priv->file_transfers == NULL) {
+        self->priv->total_transfer_size = 0;
+        self->priv->completed_transfer_size = 0;
         /* cancel any pending 'show' operations if all tasks complete before
          * the dialog can be shown */
         if (self->priv->timer_show_src) {
@@ -274,6 +293,7 @@ void virt_viewer_file_transfer_dialog_add_task(VirtViewerFileTransferDialog *sel
 {
     self->priv->file_transfers = g_slist_prepend(self->priv->file_transfers, g_object_ref(task));
     g_signal_connect(task, "notify::progress", G_CALLBACK(task_progress_notify), self);
+    g_signal_connect(task, "notify::total-bytes", G_CALLBACK(task_total_bytes_notify), self);
     g_signal_connect(task, "finished", G_CALLBACK(task_finished), self);
 
     show_transfer_dialog(self);
-- 
2.12.2




More information about the virt-tools-list mailing list