The Nautilus/EEL preferences interaction used to be quite buggy.
Identical callbacks were deregistered in different places, and EEL
didn't catch bogus calls properly (i.e. double (de)registrations, and
calls after shutdown).
Proposed patch attached.
--
Christian Neumair <[EMAIL PROTECTED]>
Index: eel/eel-preferences.c
===================================================================
RCS file: /cvs/gnome/eel/eel/eel-preferences.c,v
retrieving revision 1.17
diff -u -p -r1.17 eel-preferences.c
--- eel/eel-preferences.c 10 Jun 2005 00:49:54 -0000 1.17
+++ eel/eel-preferences.c 6 Oct 2006 22:38:03 -0000
@@ -251,6 +251,32 @@ preferences_get_default_value (const cha
return result;
}
+static int
+preferences_callback_entry_compare (gconstpointer a,
+ gconstpointer b)
+{
+ const PreferencesCallbackEntry *a_entry = a;
+ const PreferencesCallbackEntry *b_entry = b;
+
+ if (a_entry->callback < b_entry->callback) {
+ return -1;
+ }
+
+ if (a_entry->callback > b_entry->callback) {
+ return +1;
+ }
+
+ if (a_entry->callback_data < b_entry->callback_data) {
+ return -1;
+ }
+
+ if (a_entry->callback_data > b_entry->callback_data) {
+ return +1;
+ }
+
+ return 0;
+}
+
/* Public preferences functions */
gboolean
@@ -793,6 +819,7 @@ preferences_entry_add_callback (Preferen
gpointer callback_data)
{
PreferencesCallbackEntry *callback_entry;
+ GList *l;
g_return_if_fail (entry != NULL);
g_return_if_fail (callback != NULL);
@@ -800,12 +827,14 @@ preferences_entry_add_callback (Preferen
callback_entry = g_new0 (PreferencesCallbackEntry, 1);
callback_entry->callback = callback;
callback_entry->callback_data = callback_data;
-
- g_return_if_fail (callback_entry != NULL);
-
- entry->callback_list = g_list_append (entry->callback_list, callback_entry);
- preferences_entry_ensure_gconf_connection (entry);
+ l = g_list_find_custom (entry->callback_list, callback_entry, preferences_callback_entry_compare);
+ if (l == NULL) {
+ entry->callback_list = g_list_append (entry->callback_list, callback_entry);
+ preferences_entry_ensure_gconf_connection (entry);
+ } else {
+ g_warning ("Trying to add a callback for %s that already exists.", entry->name);
+ }
}
/**
@@ -826,7 +855,10 @@ preferences_entry_add_auto_storage (Pref
g_return_if_fail (entry != NULL);
g_return_if_fail (storage != NULL);
g_return_if_fail (entry->type == 0 || entry->type == type);
- g_return_if_fail (g_list_find (entry->auto_storage_list, storage) == NULL);
+ if (g_list_find (entry->auto_storage_list, storage) != NULL) {
+ g_warning ("Trying to add an auto storage for %s that already exists.", entry->name);
+ return;
+ }
entry->type = type;
@@ -864,32 +896,25 @@ preferences_entry_remove_callback (Prefe
EelPreferencesCallback callback,
gpointer callback_data)
{
- GList *new_list;
- const GList *node;
+ PreferencesCallbackEntry cb_entry;
+ GList *l;
g_return_if_fail (entry != NULL);
g_return_if_fail (callback != NULL);
- g_return_if_fail (entry->callback_list != NULL);
-
- new_list = g_list_copy (entry->callback_list);
-
- for (node = new_list; node != NULL; node = node->next) {
- PreferencesCallbackEntry *callback_entry = node->data;
-
- g_return_if_fail (callback_entry != NULL);
-
- if (callback_entry->callback == callback &&
- callback_entry->callback_data == callback_data) {
- entry->callback_list = g_list_remove (entry->callback_list,
- callback_entry);
-
- preferences_callback_entry_free (callback_entry);
- }
- }
- g_list_free (new_list);
+ cb_entry.callback = callback;
+ cb_entry.callback_data = callback_data;
- preferences_entry_check_remove_connection (entry);
+ l = g_list_find_custom (entry->callback_list, &cb_entry, preferences_callback_entry_compare);
+ if (l != NULL) {
+ preferences_callback_entry_free (l->data);
+ entry->callback_list = g_list_delete_link (entry->callback_list, l);
+ preferences_entry_check_remove_connection (entry);
+ } else {
+ g_warning ("Trying to remove a callback for %s without adding it first.", entry->name);
+ }
+
+ g_assert (g_list_find_custom (entry->callback_list, &cb_entry, preferences_callback_entry_compare) == NULL);
}
/**
@@ -1043,6 +1068,12 @@ preferences_global_table_free (void)
storage_path = NULL;
}
+static void
+preferences_uninitialize (void)
+{
+ initialized = FALSE;
+}
+
static GHashTable *
preferences_global_table_get_global (void)
{
@@ -1054,6 +1085,8 @@ preferences_global_table_get_global (voi
if (!at_exit_handler_added) {
at_exit_handler_added = TRUE;
eel_debug_call_at_shutdown (preferences_global_table_free);
+ /* ensure that we catch calls to preferences functions after eel shutdown */
+ eel_debug_call_at_shutdown (preferences_uninitialize);
}
}
@@ -1341,9 +1374,13 @@ preferences_while_alive_disconnector (gp
data = callback_data;
- eel_preferences_remove_callback (data->name,
- data->callback,
- data->callback_data);
+ /* we might have survived an eel shutdown, which
+ * already cleared all the callbacks */
+ if (preferences_is_initialized ()) {
+ eel_preferences_remove_callback (data->name,
+ data->callback,
+ data->callback_data);
+ }
g_free (data->name);
g_free (data);
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.750
diff -u -p -r1.750 fm-directory-view.c
--- src/file-manager/fm-directory-view.c 8 Aug 2006 14:43:25 -0000 1.750
+++ src/file-manager/fm-directory-view.c 6 Oct 2006 22:33:58 -0000
@@ -2062,8 +2062,6 @@ fm_directory_view_destroy (GtkObject *ob
view->details->directory_as_file = NULL;
}
- fm_directory_view_ignore_hidden_file_preferences (view);
-
EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
}
@@ -2074,10 +2072,15 @@ fm_directory_view_finalize (GObject *obj
view = FM_DIRECTORY_VIEW (object);
- eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
- filtering_changed_callback, view);
- eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
- filtering_changed_callback, view);
+ if (!view->details->ignore_hidden_file_preferences) {
+ /* fm_directory_view_ignore_hidden_file_preferences is a one-way switch,
+ * and may have removed these callbacks already.
+ */
+ eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
+ filtering_changed_callback, view);
+ eel_preferences_remove_callback (NAUTILUS_PREFERENCES_SHOW_BACKUP_FILES,
+ filtering_changed_callback, view);
+ }
eel_preferences_remove_callback (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
schedule_update_menus_callback, view);
eel_preferences_remove_callback (NAUTILUS_PREFERENCES_ENABLE_DELETE,
--
nautilus-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/nautilus-list