Nautilus property dialog refresh bounding patch -- not good



hi all,

The attached patch implements a timeout-base refresh of the property
dialog which should make the dialog a bit more responsive when changing
the permissions of a group of files.

I am very little convinced about the usefulness of the patch: the update
functions in the property dialog are horribly inefficient and bounding
the number of times they can be called per second with a timeout is not
the solution. If you disable completely the timeout (remove the
g_timeout_add in the schedule function), you will notice that changing
the permissions of a group of files (around 40) is almost instantaneous
which shows what a scary burden these update functions put on the
machine.

This patch is orthogonal to the previous wait cursor patch, has been
extensively tested and should work smoothly without leaks.

regards,
Mathieu
-- 
Mathieu Lacage <mathieu gnu org>
? patch
? patch.other
Index: file-manager/fm-properties-window.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-properties-window.c,v
retrieving revision 1.177
diff -u -r1.177 fm-properties-window.c
--- file-manager/fm-properties-window.c	2 Aug 2003 20:19:58 -0000	1.177
+++ file-manager/fm-properties-window.c	12 Sep 2003 08:10:11 -0000
@@ -100,7 +100,7 @@
 
 	GtkLabel *directory_contents_title_field;
 	GtkLabel *directory_contents_value_field;
-	guint update_directory_contents_timeout_id;
+	guint update_contents_timeout_id;
 
 	GList *directory_contents_widgets;
 	int directory_contents_row;
@@ -119,10 +119,13 @@
 
 	GList *mime_list;
 
+	gboolean deep_count_started;
 	gboolean deep_count_finished;
 
 	guint total_count;
 	GnomeVFSFileSize total_size;
+
+	GList *changed_files;
 };
 
 enum {
@@ -174,10 +177,11 @@
 	{ "x-special/gnome-reset-background", 0, TARGET_RESET_BACKGROUND }
 };
 
-#define DIRECTORY_CONTENTS_UPDATE_INTERVAL	200 /* milliseconds */
+#define CONTENTS_UPDATE_INTERVAL	200 /* milliseconds */
 #define STANDARD_EMBLEM_HEIGHT			52
 #define EMBLEM_LABEL_SPACING			2
 
+static void file_changed_cb (NautilusFile *file, gpointer user_data);
 static void permission_button_update (FMPropertiesWindow *window,
 				      GtkToggleButton *button);
 static void value_field_update (FMPropertiesWindow *window,
@@ -968,10 +972,10 @@
 	g_hash_table_remove (window->details->initial_permissions, target_file);
 
 	g_signal_handlers_disconnect_by_func (original_file,
-					      G_CALLBACK (properties_window_update),
+					      G_CALLBACK (file_changed_cb),
 					      window);
 	g_signal_handlers_disconnect_by_func (target_file,
-					      G_CALLBACK (properties_window_update),
+					      G_CALLBACK (file_changed_cb),
 					      window);
 
 	nautilus_file_monitor_remove (original_file, window);
@@ -1781,16 +1785,48 @@
 }
 
 static gboolean
-update_directory_contents_callback (gpointer data)
+update_contents_callback (gpointer data)
 {
 	FMPropertiesWindow *window;
 
 	window = FM_PROPERTIES_WINDOW (data);
 
-	window->details->update_directory_contents_timeout_id = 0;
-	directory_contents_value_field_update (window);
+	{
+		GList *tmp, *unique;
+		unique = 0;
+		for (tmp = window->details->changed_files; tmp != NULL; tmp = tmp->next) {
+			if (g_list_find (unique, tmp->data)) {
+				nautilus_file_unref (NAUTILUS_FILE (tmp->data));
+				continue;
+			}
+			unique = g_list_prepend (unique, tmp->data);
+		}
+		g_list_free (window->details->changed_files);
+		window->details->changed_files = NULL;
+		for (tmp = unique; tmp != NULL; tmp = tmp->next) {
+			NautilusFile *file = NAUTILUS_FILE (tmp->data);
+			properties_window_update (window, file);
+			nautilus_file_unref (file);
+		}
+		g_list_free (unique);
+	}
 
-	return FALSE;
+	if (window->details->deep_count_started) {
+		directory_contents_value_field_update (window);
+	}
+
+	return TRUE;
+}
+
+static void
+schedule_window_timeout_update (FMPropertiesWindow *window)
+{
+	if (window->details->update_contents_timeout_id == 0) {
+		window->details->update_contents_timeout_id
+			= g_timeout_add (CONTENTS_UPDATE_INTERVAL,
+					 update_contents_callback,
+					 window);
+	}
 }
 
 static void
@@ -1798,12 +1834,7 @@
 {
 	g_assert (FM_IS_PROPERTIES_WINDOW (window));
 
-	if (window->details->update_directory_contents_timeout_id == 0) {
-		window->details->update_directory_contents_timeout_id
-			= g_timeout_add (DIRECTORY_CONTENTS_UPDATE_INTERVAL,
-					 update_directory_contents_callback,
-					 window);
-	}
+	window->details->deep_count_started = TRUE;
 }
 
 static GtkLabel *
@@ -2437,7 +2468,7 @@
 permission_change_callback (NautilusFile *file, GnomeVFSResult result, gpointer callback_data)
 {
 	g_assert (callback_data == NULL);
-	
+
 	/* Report the error if it's an error. */
 	fm_report_error_setting_permissions (file, result, NULL);
 }
@@ -2529,7 +2560,6 @@
 				 permission_change_callback,
 				 NULL);
 		}
-		
 	}
 	
 	for (l = files_off; l != NULL; l = l->next) {
@@ -3291,6 +3321,15 @@
 	}
 }
 
+static void
+file_changed_cb (NautilusFile *file, gpointer user_data)
+{
+	FMPropertiesWindow *window = FM_PROPERTIES_WINDOW (user_data);
+
+	nautilus_file_ref (file);
+	window->details->changed_files = g_list_prepend (window->details->changed_files, file);
+}
+
 static FMPropertiesWindow *
 create_properties_window (StartupData *startup_data)
 {
@@ -3351,17 +3390,17 @@
 	for (l = window->details->target_files; l != NULL; l = l->next) {
 		g_signal_connect_object (NAUTILUS_FILE (l->data),
 					 "changed",
-					 G_CALLBACK (properties_window_update),
+					 G_CALLBACK (file_changed_cb),
 					 G_OBJECT (window),
-					 G_CONNECT_SWAPPED);
+					 0);
 	}
 
 	for (l = window->details->original_files; l != NULL; l = l->next) {
 		g_signal_connect_object (NAUTILUS_FILE (l->data),
 					 "changed",
-					 G_CALLBACK (properties_window_update),
+					 G_CALLBACK (file_changed_cb),
 					 G_OBJECT (window),
-					 G_CONNECT_SWAPPED);
+					 0);
 	}
 
 	/* Create box for notebook and button box. */
@@ -3416,6 +3455,8 @@
 	/* Update from initial state */
 	properties_window_update (window, NULL);
 
+	schedule_window_timeout_update (window);
+
 	return window;
 }
 
@@ -3657,6 +3698,9 @@
 	nautilus_file_list_free (window->details->target_files);
 	window->details->target_files = NULL;
 
+	nautilus_file_list_free (window->details->changed_files);
+	window->details->changed_files = NULL;
+
 	window->details->name_field = NULL;
 	
 	g_list_free (window->details->directory_contents_widgets);
@@ -3684,9 +3728,9 @@
 	g_list_free (window->details->value_fields);
 	window->details->value_fields = NULL;
 
-	if (window->details->update_directory_contents_timeout_id != 0) {
-		g_source_remove (window->details->update_directory_contents_timeout_id);
-		window->details->update_directory_contents_timeout_id = 0;
+	if (window->details->update_contents_timeout_id != 0) {
+		g_source_remove (window->details->update_contents_timeout_id);
+		window->details->update_contents_timeout_id = 0;
 	}
 	GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }


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