Re: PATCH: use timeouts for progress dialogs



Here is a slightly updated patch that also makes sure the dialog is
shown before we display an overwrite confirm window (not only a xfer
error window).

- Frank


On Sun, 2002-07-28 at 22:36, Frank Worsley wrote:
> Hi all,
> 
> one of the main reasons I think Nautilus feels sluggish sometimes is
> that it pops up a progress dialog for every copy/move/link I perform,
> even if it's just a single file being moved. That's quite annoying since
> the dialog appears only to disappear again right away.
> 
> The attached patch makes nautilus-file-operations-progress use a timeout
> for displaying itself. If the operation isn't done within 1200
> milliseconds a dialog will be displayed. This also makes sure we don't
> actually do the work to build the dialog UI if it isn't going to be
> displayed, the UI is only created when the dialog receives a 'realize'
> event.
> 
> This patch makes simple file operations feel a whole lot snappier on my
> machine. Ok to commit as is?
> 
> - Frank

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus/ChangeLog,v
retrieving revision 1.5464
diff -u -p -r1.5464 ChangeLog
--- ChangeLog	28 Jul 2002 03:06:22 -0000	1.5464
+++ ChangeLog	29 Jul 2002 05:50:09 -0000
@@ -1,3 +1,23 @@
+2002-07-28  Frank Worsley  <fworsley shaw ca>
+
+	* libnautilus-private/nautilus-file-operations-progress.h:
+	* libnautilus-private/nautilus-file-operations-progress.c:
+	(nautilus_file_operations_progress_update_icon),
+	(nautilus_file_operations_progress_update),
+	(nautilus_file_operations_progress_destroy), (create_ui),
+	(nautilus_file_operations_progress_init), (delayed_show_callback),
+	(nautilus_file_operations_progress_new),
+	(nautilus_file_operations_progress_set_operation_string),
+	(nautilus_file_operations_progress_new_file),
+	(nautilus_file_operations_progress_clear):
+	use a timeout to display the progress dialog, this makes it more
+	consistent as to when we show a dialog
+
+	* libnautilus-private/nautilus-file-operations.c:
+	(create_transfer_dialog), (nautilus_file_operations_copy_move),
+	(nautilus_file_operations_delete), (do_empty_trash):
+	use timeout instead of explicitly showing progress dialog
+
 2002-07-27  Dave Camp  <dave ximian com>
 
 	* libnautilus-private/nautilus-icon-factory.c
Index: libnautilus-private/nautilus-file-operations-progress.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.c,v
retrieving revision 1.36
diff -u -p -r1.36 nautilus-file-operations-progress.c
--- libnautilus-private/nautilus-file-operations-progress.c	17 Apr 2002 12:29:10 -0000	1.36
+++ libnautilus-private/nautilus-file-operations-progress.c	29 Jul 2002 05:50:10 -0000
@@ -87,8 +87,26 @@ struct NautilusFileOperationsProgressDet
 	gint64 start_time;
 
 	guint delayed_close_timeout_id;
+	guint delayed_show_timeout_id;
 
 	int progress_jar_position;
+	
+	/* this is set to true when the widget is first shown and
+	 * the ui is created. ideally the operation is fast and the
+	 * widget is never shown so we don't waste time building
+	 * its ui.
+	 */
+	gboolean ui_ready;
+	
+	/* stuff we might need at ui creation time */
+	char *operation_string;
+	char *progress_verb;
+	char *file_item_name;
+	char *from_path;
+	char *to_path;
+	gulong file_index;
+	gulong size;
+	gboolean new_file;	
 };
 
 /* Private functions. */
@@ -100,6 +118,10 @@ nautilus_file_operations_progress_update
 	GdkPixbuf *pixbuf;
 	int position;
 
+	if (!progress->details->ui_ready) {
+		return;
+	}
+
 	position = gdk_pixbuf_get_height (empty_jar_pixbuf) * (1 - fraction);
 
 	if (position == progress->details->progress_jar_position) {
@@ -124,6 +146,10 @@ static void
 nautilus_file_operations_progress_update (NautilusFileOperationsProgress *progress)
 {
 	double fraction;
+
+	if (!progress->details->ui_ready) {
+		return;
+	}
 	
 	if (progress->details->bytes_total == 0) {
 		/* We haven't set up the file count yet, do not update
@@ -191,6 +217,11 @@ nautilus_file_operations_progress_destro
 		progress->details->delayed_close_timeout_id = 0;
 	}
 	
+	if (progress->details->delayed_show_timeout_id != 0) {
+		g_source_remove (progress->details->delayed_show_timeout_id);
+		progress->details->delayed_show_timeout_id = 0;
+	}
+	
 	EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
 }
 
@@ -242,13 +273,20 @@ delete_event_callback (GtkWidget *widget
 }
 
 static void
-nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
+create_ui (NautilusFileOperationsProgress *progress, gpointer callback_data)
 {
 	GtkWidget *hbox, *vbox;
 	GtkTable *titled_label_table;
 
-	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
-
+	if (progress->details->ui_ready) {
+		return;
+	}
+	
+	if (progress->details->delayed_show_timeout_id != 0) {
+		g_source_remove (progress->details->delayed_show_timeout_id);
+		progress->details->delayed_show_timeout_id = 0;
+	}
+	
 	vbox = gtk_vbox_new (FALSE, VERTICAL_SPACING);
 	gtk_container_set_border_width (GTK_CONTAINER (vbox), OUTER_BORDER);
 	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (progress)->vbox), vbox, TRUE, TRUE, VERTICAL_SPACING);
@@ -298,7 +336,44 @@ nautilus_file_operations_progress_init (
 	/* Set progress jar position */
 	progress->details->progress_jar_position = gdk_pixbuf_get_height (empty_jar_pixbuf);
 
+	progress->details->ui_ready = TRUE;
+	
+	if (progress->details->operation_string != NULL) {
+		nautilus_file_operations_progress_set_operation_string
+				(progress, progress->details->operation_string);
+		g_free (progress->details->operation_string);
+	}
+	
+	if (progress->details->new_file) {
+		nautilus_file_operations_progress_new_file
+				(progress,
+				 progress->details->progress_verb,
+				 progress->details->file_item_name,
+				 progress->details->from_path,
+				 progress->details->to_path,
+				 progress->details->from_prefix,
+				 progress->details->to_prefix,
+				 progress->details->file_index,
+				 progress->details->size);
+
+		g_free (progress->details->progress_verb);
+		g_free (progress->details->file_item_name);
+		g_free (progress->details->from_path);
+		g_free (progress->details->to_path);
+	}		 
+
 	gtk_widget_show_all (vbox);
+}	
+
+
+static void
+nautilus_file_operations_progress_init (NautilusFileOperationsProgress *progress)
+{
+	progress->details = g_new0 (NautilusFileOperationsProgressDetails, 1);
+
+	progress->details->ui_ready = FALSE;
+	
+	g_signal_connect (progress, "realize", G_CALLBACK (create_ui), NULL);
 }
 
 static void
@@ -335,13 +410,29 @@ nautilus_file_operations_progress_class_
 	
 }
 
+static gboolean
+delayed_show_callback (gpointer callback_data)
+{
+	NautilusFileOperationsProgress *progress;
+	
+	progress = NAUTILUS_FILE_OPERATIONS_PROGRESS (callback_data);
+	
+	progress->details->delayed_show_timeout_id = 0;
+	
+	create_ui (progress, NULL);
+	gtk_widget_show (GTK_WIDGET (progress));
+	
+	return FALSE;
+}
+
 NautilusFileOperationsProgress *
 nautilus_file_operations_progress_new (const char *title,
 				       const char *operation_string,
 				       const char *from_prefix,
 				       const char *to_prefix,
 				       gulong total_files,
-				       gulong total_bytes)
+				       gulong total_bytes,
+				       gboolean use_timeout)
 {
 	GtkWidget *widget;
 	NautilusFileOperationsProgress *progress;
@@ -359,6 +450,11 @@ nautilus_file_operations_progress_new (c
 
 	progress->details->from_prefix = from_prefix;
 	progress->details->to_prefix = to_prefix;
+
+	if (use_timeout) {
+		progress->details->delayed_show_timeout_id =
+			g_timeout_add (1200, delayed_show_callback, progress);
+	}
 	
 	return progress;
 }
@@ -382,6 +478,12 @@ nautilus_file_operations_progress_set_op
 {
 	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
 
+	if (!progress->details->ui_ready) {
+		g_free (progress->details->operation_string);	
+		progress->details->operation_string = g_strdup (operation_string);
+		return;
+	}
+
 	gtk_label_set_text (GTK_LABEL (progress->details->progress_title_label),
 			    operation_string);
 }
@@ -400,11 +502,25 @@ nautilus_file_operations_progress_new_fi
 	char *progress_count;
 
 	g_return_if_fail (NAUTILUS_IS_FILE_OPERATIONS_PROGRESS (progress));
-	g_return_if_fail (GTK_WIDGET_REALIZED (progress));
 
 	progress->details->from_prefix = from_prefix;
 	progress->details->to_prefix = to_prefix;
 
+	if (!progress->details->ui_ready) {
+		g_free (progress->details->progress_verb);
+		g_free (progress->details->file_item_name);
+		g_free (progress->details->from_path);
+		g_free (progress->details->to_path);
+		progress->details->progress_verb = g_strdup (progress_verb);
+		progress->details->file_item_name = g_strdup (item_name);
+		progress->details->from_path = g_strdup (from_path);
+		progress->details->to_path = g_strdup (to_path);
+		progress->details->file_index = file_index;
+		progress->details->size = size;
+		progress->details->new_file = TRUE;
+		return;
+	}
+
 	if (progress->details->bytes_total > 0) {
 		/* we haven't set up the file count yet, do not update the progress
 		 * count until we do
@@ -438,6 +554,10 @@ nautilus_file_operations_progress_new_fi
 void
 nautilus_file_operations_progress_clear (NautilusFileOperationsProgress *progress)
 {
+	if (!progress->details->ui_ready) {
+		return;
+	}
+
 	gtk_label_set_text (GTK_LABEL (progress->details->from_label), "");
 	gtk_label_set_text (GTK_LABEL (progress->details->from_path_label), "");
 	gtk_label_set_text (GTK_LABEL (progress->details->to_label), "");
Index: libnautilus-private/nautilus-file-operations-progress.h
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations-progress.h,v
retrieving revision 1.10
diff -u -p -r1.10 nautilus-file-operations-progress.h
--- libnautilus-private/nautilus-file-operations-progress.h	27 Nov 2001 01:46:16 -0000	1.10
+++ libnautilus-private/nautilus-file-operations-progress.h	29 Jul 2002 05:50:10 -0000
@@ -55,7 +55,8 @@ NautilusFileOperationsProgress *nautilus
 											const char                     *from_prefix,
 											const char                     *to_prefix,
 											gulong                          files_total,
-											gulong                          bytes_total);
+											gulong                          bytes_total,
+											gboolean			use_timeout);
 void                            nautilus_file_operations_progress_done                 (NautilusFileOperationsProgress *dialog);
 void                            nautilus_file_operations_progress_set_progress_title   (NautilusFileOperationsProgress *dialog,
 											const char                     *progress_title);
Index: libnautilus-private/nautilus-file-operations.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-file-operations.c,v
retrieving revision 1.153
diff -u -p -r1.153 nautilus-file-operations.c
--- libnautilus-private/nautilus-file-operations.c	12 Jul 2002 18:36:13 -0000	1.153
+++ libnautilus-private/nautilus-file-operations.c	29 Jul 2002 05:50:10 -0000
@@ -73,7 +73,6 @@ typedef struct {
 	GnomeVFSXferOverwriteMode overwrite_mode;
 	GtkWidget *parent_view;
 	TransferKind kind;
-	gboolean show_progress_dialog;
 	void (* done_callback) (GHashTable *debuting_uris, gpointer data);
 	gpointer done_callback_data;
 	GHashTable *debuting_uris;
@@ -280,14 +279,10 @@ static void
 create_transfer_dialog (const GnomeVFSXferProgressInfo *progress_info,
 			TransferInfo *transfer_info)
 {
-	if (!transfer_info->show_progress_dialog) {
-		return;
-	}
-
 	g_return_if_fail (transfer_info->progress_dialog == NULL);
 
 	transfer_info->progress_dialog = nautilus_file_operations_progress_new 
-		(transfer_info->operation_title, "", "", "", 0, 0);
+		(transfer_info->operation_title, "", "", "", 0, 0, TRUE);
 
 	/* Treat clicking on the close box or use of the escape key
 	 * the same as clicking cancel.
@@ -307,8 +302,6 @@ create_transfer_dialog (const GnomeVFSXf
 			GTK_WINDOW (transfer_info->progress_dialog), 
 			GTK_WINDOW (gtk_widget_get_toplevel (transfer_info->parent_view)));
 	}
-
-	gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
 }
 
 static void
@@ -800,6 +793,12 @@ handle_transfer_vfs_error (const GnomeVF
 
 		/* transfer error, prompt the user to continue or stop */
 
+		/* make sure the progress dialog is shown at this point,
+		 * otherwise it might show up behind the error window 
+		 * which looks stupid.
+		 */
+		gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
+
 		formatted_source_name = NULL;
 		formatted_target_name = NULL;
 
@@ -999,6 +998,9 @@ handle_transfer_overwrite (const GnomeVF
 	int result;
 	char *text, *formatted_name;
 
+	/* make sure progress dialog is shown at this point */
+	gtk_widget_show (GTK_WIDGET (transfer_info->progress_dialog));
+
 	/* Handle special case files such as Trash, mount links and home directory */	
 	if (is_special_link (progress_info->target_name)) {
 		formatted_name = extract_and_ellipsize_file_name_for_dialog
@@ -1688,7 +1690,6 @@ nautilus_file_operations_copy_move (cons
 	gboolean target_is_trash;
 	gboolean is_desktop_trash_link;
 	gboolean duplicate;
-	gboolean all_local;
 	
 	IconPositionIterator *icon_position_iterator;
 
@@ -1712,7 +1713,6 @@ nautilus_file_operations_copy_move (cons
 	 */
 	source_uri_list = NULL;
 	target_uri_list = NULL;
-	all_local = TRUE;
 	duplicate = copy_action != GDK_ACTION_MOVE;
 	for (p = item_uris; p != NULL; p = p->next) {
 		/* Filter out special Nautilus link files */
@@ -1750,11 +1750,6 @@ nautilus_file_operations_copy_move (cons
 			target_uri_list = g_list_prepend (target_uri_list, target_uri);
 			source_uri_list = g_list_prepend (source_uri_list, source_uri);
 
-			if (all_local && (!gnome_vfs_uri_is_local (source_uri)
-					  || !gnome_vfs_uri_is_local (target_uri))) {
-				all_local = FALSE;
-			}
-
 			if (duplicate
 			    && !gnome_vfs_uri_equal (source_dir_uri, target_dir_uri)) {
 				duplicate = FALSE;
@@ -1823,11 +1818,6 @@ nautilus_file_operations_copy_move (cons
 
 		transfer_info->kind = TRANSFER_MOVE_TO_TRASH;
 
-		/* Do an arbitrary guess that an operation will take very little
-		 * time and the progress shouldn't be shown.
-		 */
-		transfer_info->show_progress_dialog = 
-			!all_local || g_list_length ((GList *) item_uris) > 20;
 	} else if ((move_options & GNOME_VFS_XFER_REMOVESOURCE) != 0) {
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Moving files");
@@ -1840,11 +1830,6 @@ nautilus_file_operations_copy_move (cons
 
 		transfer_info->kind = TRANSFER_MOVE;
 
-		/* Do an arbitrary guess that an operation will take very little
-		 * time and the progress shouldn't be shown.
-		 */
-		transfer_info->show_progress_dialog = 
-			!all_local || g_list_length ((GList *) item_uris) > 20;
 	} else if ((move_options & GNOME_VFS_XFER_LINK_ITEMS) != 0) {
 		/* when creating links, handle name conflicts automatically */
 		move_options |= GNOME_VFS_XFER_USE_UNIQUE_NAMES;
@@ -1858,8 +1843,7 @@ nautilus_file_operations_copy_move (cons
 		transfer_info->cleanup_name = _("Finishing Creating Links...");
 
 		transfer_info->kind = TRANSFER_LINK;
-		transfer_info->show_progress_dialog =
-			g_list_length ((GList *)item_uris) > 20;
+
 	} else {
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Copying files");
@@ -1871,8 +1855,6 @@ nautilus_file_operations_copy_move (cons
 		transfer_info->cleanup_name = "";
 
 		transfer_info->kind = TRANSFER_COPY;
-		/* always show progress during copy */
-		transfer_info->show_progress_dialog = TRUE;
 	}
 
 	/* we'll need to check for copy into Trash and for moving/copying the Trash itself */
@@ -2140,7 +2122,6 @@ nautilus_file_operations_delete (const G
 	uri_list = g_list_reverse (uri_list);
 
 	transfer_info = transfer_info_new (parent_view);
-	transfer_info->show_progress_dialog = TRUE;
 
 	/* localizers: progress dialog title */
 	transfer_info->operation_title = _("Deleting files");
@@ -2176,7 +2157,6 @@ do_empty_trash (GtkWidget *parent_view)
 	if (trash_dir_list != NULL) {
 		/* set up the move parameters */
 		transfer_info = transfer_info_new (parent_view);
-		transfer_info->show_progress_dialog = TRUE;
 
 		/* localizers: progress dialog title */
 		transfer_info->operation_title = _("Emptying the Trash");


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