diff --git a/ChangeLog b/ChangeLog index c972a11bd9..dd4e88c9cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2006-09-02 Kristian Rietveld + + First part of file chooser fixes. + + * gtk/gtkfilechooserbutton.c (model_add_special): also set the + handle in the model for the desktopdir case. + + * gtk/gtkfilechooserdefault.c (shortcuts_add_current_folder): free + volume in case we retrieved it but don't pass it on to insert_path, + (shortcuts_model_create): change the column type for the handles + to pointer instead of GObject so our handle ref counting is not + disturbed, + (show_and_select_paths_finished_loading): don't forget to unref + the dialog. + + * gtk/gtkfilesystemunix.c (gtk_file_system_unix_class_init), + (gtk_file_system_unix_init), (gtk_file_system_unix_dispose): + remove pending execute_callbacks_idle during dispose, also + execute all callbacks waiting to be run in the next idle, + (queue_*callback), (execute_callbacks_idle): refactor to maintain + a list of callbacks to call per file system instead of globally, + guard the file system during callback invocation, + (gtk_file_system_unix_get_folder): only add load folder idle if + none has been added yet. + 2006-09-01 Matthias Clasen * gtk/gtkentry.c: Don't unnecessarily reset the im context diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 0aaea8ebc9..c9d8809e13 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -1701,6 +1701,7 @@ model_add_special (GtkFileChooserButton *button) DISPLAY_NAME_COLUMN, _(DESKTOP_DISPLAY_NAME), DATA_COLUMN, path, IS_FOLDER_COLUMN, TRUE, + HANDLE_COLUMN, handle, -1); button->priv->n_special++; diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index e5b6e90602..ff7482527c 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -1905,7 +1905,11 @@ shortcuts_add_current_folder (GtkFileChooserDefault *impl) shortcuts_insert_path (impl, pos, TRUE, volume, NULL, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER); } else - shortcuts_insert_path (impl, pos, FALSE, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER); + { + shortcuts_insert_path (impl, pos, FALSE, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER); + if (volume) + gtk_file_system_volume_free (impl->file_system, volume); + } if (base_path) gtk_file_path_free (base_path); @@ -1965,7 +1969,7 @@ shortcuts_model_create (GtkFileChooserDefault *impl) G_TYPE_BOOLEAN, /* is the previous column a volume? */ G_TYPE_BOOLEAN, /* removable */ G_TYPE_BOOLEAN, /* pixbuf cell visibility */ - G_TYPE_OBJECT); /* GtkFileSystemHandle */ + G_TYPE_POINTER); /* GtkFileSystemHandle */ if (impl->file_system) { @@ -5783,6 +5787,7 @@ show_and_select_paths_finished_loading (GtkFileFolder *folder, browse_files_center_selected_row (data->impl); + g_object_unref (data->impl); gtk_file_paths_free (data->paths); g_free (data); } diff --git a/gtk/gtkfilesystemunix.c b/gtk/gtkfilesystemunix.c index 1a6ed04b8c..64ed3f7db6 100644 --- a/gtk/gtkfilesystemunix.c +++ b/gtk/gtkfilesystemunix.c @@ -75,6 +75,9 @@ struct _GtkFileSystemUnix GHashTable *handles; + guint execute_callbacks_idle_id; + GSList *callbacks; + guint have_afs : 1; guint have_net : 1; }; @@ -140,6 +143,7 @@ static const GtkFileInfoType STAT_NEEDED_MASK = (GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON); static void gtk_file_system_unix_iface_init (GtkFileSystemIface *iface); +static void gtk_file_system_unix_dispose (GObject *object); static void gtk_file_system_unix_finalize (GObject *object); static GSList * gtk_file_system_unix_list_volumes (GtkFileSystem *file_system); @@ -250,6 +254,8 @@ static GtkFileInfo *create_file_info (GtkFileFolderUnix *folder_uni struct stat *statbuf, const char *mime_type); +static gboolean execute_callbacks_idle (gpointer data); + static gboolean fill_in_names (GtkFileFolderUnix *folder_unix, GError **error); static void fill_in_stats (GtkFileFolderUnix *folder_unix); @@ -300,6 +306,7 @@ gtk_file_system_unix_class_init (GtkFileSystemUnixClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); + gobject_class->dispose = gtk_file_system_unix_dispose; gobject_class->finalize = gtk_file_system_unix_finalize; } @@ -348,6 +355,9 @@ gtk_file_system_unix_init (GtkFileSystemUnix *system_unix) system_unix->have_net = FALSE; system_unix->handles = g_hash_table_new (g_direct_hash, g_direct_equal); + + system_unix->execute_callbacks_idle_id = 0; + system_unix->callbacks = NULL; } static void @@ -380,6 +390,7 @@ check_handles_at_finalization (GtkFileSystemUnix *system_unix) #endif g_hash_table_destroy (system_unix->handles); + system_unix->handles = NULL; } #define GTK_TYPE_FILE_SYSTEM_HANDLE_UNIX (_gtk_file_system_handle_unix_get_type ()) @@ -419,6 +430,24 @@ _gtk_file_system_handle_unix_class_init (GtkFileSystemHandleUnixClass *class) gobject_class->finalize = _gtk_file_system_handle_unix_finalize; } +static void +gtk_file_system_unix_dispose (GObject *object) +{ + GtkFileSystemUnix *system_unix; + + system_unix = GTK_FILE_SYSTEM_UNIX (object); + + if (system_unix->execute_callbacks_idle_id) + { + g_source_remove (system_unix->execute_callbacks_idle_id); + system_unix->execute_callbacks_idle_id = 0; + + /* call pending callbacks */ + execute_callbacks_idle (system_unix); + } + + G_OBJECT_CLASS (gtk_file_system_unix_parent_class)->dispose (object); +} static void gtk_file_system_unix_finalize (GObject *object) @@ -479,7 +508,7 @@ enum callback_types CALLBACK_VOLUME_MOUNT }; -static void queue_callback (enum callback_types type, gpointer data); +static void queue_callback (GtkFileSystemUnix *system_unix, enum callback_types type, gpointer data); struct get_info_callback { @@ -522,7 +551,7 @@ queue_get_info_callback (GtkFileSystemGetInfoCallback callback, info->error = error; info->data = data; - queue_callback (CALLBACK_GET_INFO, info); + queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_GET_INFO, info); } @@ -564,7 +593,7 @@ queue_get_folder_callback (GtkFileSystemGetFolderCallback callback, info->error = error; info->data = data; - queue_callback (CALLBACK_GET_FOLDER, info); + queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_GET_FOLDER, info); } @@ -609,7 +638,7 @@ queue_create_folder_callback (GtkFileSystemCreateFolderCallback callback, info->error = error; info->data = data; - queue_callback (CALLBACK_CREATE_FOLDER, info); + queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_CREATE_FOLDER, info); } @@ -651,7 +680,7 @@ queue_volume_mount_callback (GtkFileSystemVolumeMountCallback callback, info->error = error; info->data = data; - queue_callback (CALLBACK_VOLUME_MOUNT, info); + queue_callback (GTK_FILE_SYSTEM_UNIX (handle->file_system), CALLBACK_VOLUME_MOUNT, info); } @@ -669,17 +698,22 @@ struct callback_info }; -static guint execute_callbacks_idle_id = 0; -static GSList *callbacks = NULL; static gboolean execute_callbacks_idle (gpointer data) { GSList *l; + gboolean unref_file_system = TRUE; + GtkFileSystemUnix *system_unix = GTK_FILE_SYSTEM_UNIX (data); GDK_THREADS_ENTER (); - for (l = callbacks; l; l = l->next) + if (!system_unix->execute_callbacks_idle_id) + unref_file_system = FALSE; + else + g_object_ref (system_unix); + + for (l = system_unix->callbacks; l; l = l->next) { struct callback_info *info = l->data; @@ -705,10 +739,13 @@ execute_callbacks_idle (gpointer data) g_free (info); } - g_slist_free (callbacks); - callbacks = NULL; + g_slist_free (system_unix->callbacks); + system_unix->callbacks = NULL; - execute_callbacks_idle_id = 0; + if (unref_file_system) + g_object_unref (system_unix); + + system_unix->execute_callbacks_idle_id = 0; GDK_THREADS_LEAVE (); @@ -716,7 +753,9 @@ execute_callbacks_idle (gpointer data) } static void -queue_callback (enum callback_types type, gpointer data) +queue_callback (GtkFileSystemUnix *system_unix, + enum callback_types type, + gpointer data) { struct callback_info *info; @@ -742,10 +781,10 @@ queue_callback (enum callback_types type, gpointer data) break; } - callbacks = g_slist_append (callbacks, info); + system_unix->callbacks = g_slist_append (system_unix->callbacks, info); - if (!execute_callbacks_idle_id) - execute_callbacks_idle_id = g_idle_add (execute_callbacks_idle, NULL); + if (!system_unix->execute_callbacks_idle_id) + system_unix->execute_callbacks_idle_id = g_idle_add (execute_callbacks_idle, system_unix); } static GtkFileSystemHandle * @@ -972,8 +1011,9 @@ gtk_file_system_unix_get_folder (GtkFileSystem *file_system, queue_get_folder_callback (callback, handle, GTK_FILE_FOLDER (folder_unix), NULL, data); /* Start loading the folder contents in an idle */ - folder_unix->load_folder_id = - g_idle_add ((GSourceFunc) load_folder, folder_unix); + if (!folder_unix->load_folder_id) + folder_unix->load_folder_id = + g_idle_add ((GSourceFunc) load_folder, folder_unix); return handle; }