From e5aa4256d2e54218ea10406541ce9cc6cff59059 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer <benny@xfce.org> Date: Sun, 26 Jun 2005 01:12:14 +0000 Subject: [PATCH] 2005-06-26 Benedikt Meurer <benny@xfce.org> * thunar-vfs/thunar-vfs-uri.{c,h}: Don't use a GObject for the ThunarVfsURI class. GObject is really overhead here, as we don't need anything of whats provided by GObject. * TODO: Add note about missing GValue handling for ThunarVfsURI. * TODO: Add note to fix ThunarVfsInfo to not implicitly query the link target. * thunar-vfs/*.[ch], thunar/*.[ch]: Use thunar_vfs_uri_unref() and thunar_vfs_uri_ref() instead of g_object_unref() and g_object_ref(), as ThunarVfsURI is no longer a GObject derived type. * thunar/thunar-window.c: Make loading new directories look and feel "smoother". Still not perfect. (Old svn revision: 16357) --- ChangeLog | 14 ++ TODO | 6 + thunar-vfs/thunar-vfs-info.c | 5 +- thunar-vfs/thunar-vfs-info.h | 2 +- thunar-vfs/thunar-vfs-trash.c | 2 +- thunar-vfs/thunar-vfs-uri.c | 198 ++++++++++++++++++++++++----- thunar-vfs/thunar-vfs-uri.h | 15 ++- thunar-vfs/thunar-vfs-volume-bsd.c | 11 +- thunar-vfs/thunar-vfs-volume.c | 19 +-- thunar/main.c | 2 +- thunar/thunar-computer-folder.c | 9 +- thunar/thunar-details-view.c | 1 + thunar/thunar-favourites-model.c | 8 +- thunar/thunar-file.c | 50 +++++++- thunar/thunar-icon-view.c | 1 + thunar/thunar-local-file.c | 2 +- thunar/thunar-local-folder.c | 4 +- thunar/thunar-trash-file.c | 8 +- thunar/thunar-trash-folder.c | 12 +- thunar/thunar-window.c | 110 ++++++++++++---- 20 files changed, 358 insertions(+), 121 deletions(-) diff --git a/ChangeLog b/ChangeLog index d94fdee6f..10d8c6d76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-06-26 Benedikt Meurer <benny@xfce.org> + + * thunar-vfs/thunar-vfs-uri.{c,h}: Don't use a GObject for the + ThunarVfsURI class. GObject is really overhead here, as we don't need + anything of whats provided by GObject. + * TODO: Add note about missing GValue handling for ThunarVfsURI. + * TODO: Add note to fix ThunarVfsInfo to not implicitly query the + link target. + * thunar-vfs/*.[ch], thunar/*.[ch]: Use thunar_vfs_uri_unref() and + thunar_vfs_uri_ref() instead of g_object_unref() and g_object_ref(), + as ThunarVfsURI is no longer a GObject derived type. + * thunar/thunar-window.c: Make loading new directories look and feel + "smoother". Still not perfect. + 2005-06-25 Benedikt Meurer <benny@xfce.org> * thunar/thunar-local-file.c: Use a static variable for the VFS monitor diff --git a/TODO b/TODO index 7ff80e5ff..0b8630b81 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,12 @@ Important for Thunar 1.0 ======================== + - Do NOT automatically determine the link target for ThunarVfsInfo objects. + Instead provide a method to do this on-demand. + + - ThunarVfsURI should have it's own parameter specification, that + can be used for GValue handling. + - The ThunarTrashFile constructor needs some rework, as it's currently mostly brain-dead. Should probably be splitted into several functions. In addition the ThunarTrashFile should enable the monitoring on the diff --git a/thunar-vfs/thunar-vfs-info.c b/thunar-vfs/thunar-vfs-info.c index f9d1c15de..ed135d377 100644 --- a/thunar-vfs/thunar-vfs-info.c +++ b/thunar-vfs/thunar-vfs-info.c @@ -62,12 +62,11 @@ thunar_vfs_info_query (ThunarVfsInfo *info, g_return_val_if_fail (info->target == NULL, FALSE); g_return_val_if_fail (THUNAR_VFS_IS_URI (uri), FALSE); - g_object_ref (G_OBJECT (uri)); - info->uri = uri; + info->uri = thunar_vfs_uri_ref (uri); if (thunar_vfs_info_update (info, error) == THUNAR_VFS_INFO_RESULT_ERROR) { - g_object_unref (G_OBJECT (info->uri)); + thunar_vfs_uri_unref (uri); info->uri = NULL; return FALSE; } diff --git a/thunar-vfs/thunar-vfs-info.h b/thunar-vfs/thunar-vfs-info.h index 92e1b72c8..3ccd8085a 100644 --- a/thunar-vfs/thunar-vfs-info.h +++ b/thunar-vfs/thunar-vfs-info.h @@ -202,7 +202,7 @@ G_STMT_START { \ } \ if (G_LIKELY ((info)->uri != NULL)) \ { \ - g_object_unref (G_OBJECT ((info)->uri)); \ + thunar_vfs_uri_unref ((info)->uri); \ (info)->uri = NULL; \ } \ (info)->type = THUNAR_VFS_FILE_TYPE_UNKNOWN; \ diff --git a/thunar-vfs/thunar-vfs-trash.c b/thunar-vfs/thunar-vfs-trash.c index b1a1402b4..84d9c7567 100644 --- a/thunar-vfs/thunar-vfs-trash.c +++ b/thunar-vfs/thunar-vfs-trash.c @@ -561,7 +561,7 @@ thunar_vfs_trash_get_path (ThunarVfsTrash *trash, * * Generates a 'trash://' URI that refers to the @file in @trash. * - * You'll need to call #g_object_unref() on the returned + * You'll need to call #thunar_vfs_uri_unref() on the returned * object when you are done with it. * * Return value: the generated #ThunarVfsURI. diff --git a/thunar-vfs/thunar-vfs-uri.c b/thunar-vfs/thunar-vfs-uri.c index 58b426bd7..c3d8feb02 100644 --- a/thunar-vfs/thunar-vfs-uri.c +++ b/thunar-vfs/thunar-vfs-uri.c @@ -35,15 +35,17 @@ -static void thunar_vfs_uri_class_init (ThunarVfsURIClass *klass); -static void thunar_vfs_uri_init (ThunarVfsURI *uri); -static void thunar_vfs_uri_finalize (GObject *object); +static void thunar_vfs_uri_base_init (ThunarVfsURIClass *klass); +static void thunar_vfs_uri_base_finalize (ThunarVfsURIClass *klass); +#ifndef G_DISABLE_CHECKS +static void thunar_vfs_uri_init (ThunarVfsURI *uri); +#endif struct _ThunarVfsURIClass { - GObjectClass __parent__; + GTypeClass __parent__; const gchar *home_path; gchar *localhost; @@ -51,8 +53,9 @@ struct _ThunarVfsURIClass struct _ThunarVfsURI { - GObject __parent__; + GTypeInstance __parent__; + guint ref_count; gchar *host; gchar *path; const gchar *name; @@ -70,47 +73,119 @@ static const gchar *scheme_names[] = -G_DEFINE_TYPE (ThunarVfsURI, thunar_vfs_uri, G_TYPE_OBJECT); +#ifndef G_DISABLE_CHECKS +G_LOCK_DEFINE_STATIC (debug_uris); +static GList *debug_uris = NULL; +#endif -static void -thunar_vfs_uri_class_init (ThunarVfsURIClass *klass) +GType +thunar_vfs_uri_get_type (void) { - GObjectClass *gobject_class; + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeFundamentalInfo finfo = + { + G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE + }; + + static const GTypeInfo info = + { + sizeof (ThunarVfsURIClass), + (GBaseInitFunc) thunar_vfs_uri_base_init, + (GBaseFinalizeFunc) thunar_vfs_uri_base_finalize, + NULL, + NULL, + NULL, + sizeof (ThunarVfsURI), + 256u, +#ifndef G_DISABLE_CHECKS + (GInstanceInitFunc) thunar_vfs_uri_init, +#else + NULL, +#endif + NULL, + }; + + type = g_type_register_fundamental (g_type_fundamental_next (), "ThunarVfsURI", &info, &finfo, 0); + } + + return type; +} + + +static void +thunar_vfs_uri_base_init (ThunarVfsURIClass *klass) +{ /* determine the path to the current user's homedir */ klass->home_path = xfce_get_homedir (); /* determine the local host's name */ klass->localhost = xfce_gethostname (); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_vfs_uri_finalize; } static void -thunar_vfs_uri_init (ThunarVfsURI *uri) +thunar_vfs_uri_base_finalize (ThunarVfsURIClass *klass) { + /* free class data */ + g_free (klass->localhost); } +#ifndef G_DISABLE_CHECKS static void -thunar_vfs_uri_finalize (GObject *object) +thunar_vfs_uri_atexit (void) { - ThunarVfsURI *uri = THUNAR_VFS_URI (object); + ThunarVfsURI *uri; + GList *lp; + gchar *s; - g_return_if_fail (THUNAR_VFS_IS_URI (uri)); + G_LOCK (debug_uris); - if (G_UNLIKELY (uri->host != NULL)) - g_free (uri->host); - g_free (uri->path); + if (G_UNLIKELY (debug_uris != NULL)) + { + g_print ("--- Leaked a total of %u ThunarVfsURI objects:\n", g_list_length (debug_uris)); + + for (lp = debug_uris; lp != NULL; lp = lp->next) + { + uri = THUNAR_VFS_URI (lp->data); + s = thunar_vfs_uri_to_string (uri, 0); + g_print ("--> %s (%u)\n", s, uri->ref_count); + g_free (s); + } + + g_print ("\n"); + } + + G_UNLOCK (debug_uris); +} + +static void +thunar_vfs_uri_init (ThunarVfsURI *uri) +{ + static gboolean registered = FALSE; - G_OBJECT_CLASS (thunar_vfs_uri_parent_class)->finalize (object); + G_LOCK (debug_uris); + + /* register the check function to be called at program exit */ + if (!registered) + { + g_atexit (thunar_vfs_uri_atexit); + registered = TRUE; + } + + debug_uris = g_list_prepend (debug_uris, uri); + + G_UNLOCK (debug_uris); } +#endif @@ -155,7 +230,8 @@ thunar_vfs_uri_new (const gchar *identifier, return NULL; /* allocate the URI instance */ - uri = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + uri = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + uri->ref_count = 1; uri->scheme = THUNAR_VFS_URI_SCHEME_FILE; uri->path = path; @@ -202,7 +278,8 @@ thunar_vfs_uri_new (const gchar *identifier, } /* allocate the URI instance */ - uri = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + uri = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + uri->ref_count = 1; uri->scheme = THUNAR_VFS_URI_SCHEME_TRASH; uri->path = g_strdup ((*p == '/') ? p : "/"); } @@ -235,7 +312,8 @@ thunar_vfs_uri_new (const gchar *identifier, } /* allocate the URI instance */ - uri = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + uri = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + uri->ref_count = 1; uri->scheme = THUNAR_VFS_URI_SCHEME_COMPUTER; uri->path = g_strdup ((*p == '/') ? p : "/"); } @@ -277,7 +355,8 @@ thunar_vfs_uri_new_for_path (const gchar *path) g_return_val_if_fail (g_path_is_absolute (path), NULL); /* allocate the URI instance */ - uri = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + uri = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + uri->ref_count = 1; uri->scheme = THUNAR_VFS_URI_SCHEME_FILE; uri->path = g_strdup (path); @@ -307,6 +386,64 @@ thunar_vfs_uri_new_for_path (const gchar *path) +/** + * thunar_vfs_uri_ref: + * @uri : a #ThunarVfsURI instance. + * + * Increments the reference count on @uri by 1 and + * returns @uri. + * + * Return value: pointer to @uri. + **/ +ThunarVfsURI* +thunar_vfs_uri_ref (ThunarVfsURI *uri) +{ + g_return_val_if_fail (THUNAR_VFS_IS_URI (uri), NULL); + g_return_val_if_fail (uri->ref_count > 0, NULL); + + ++uri->ref_count; + + return uri; +} + + + +/** + * thunar_vfs_uri_unref: + * @uri : a #ThunarVfsURI instance. + * + * Decreases the reference count on @uri by 1. If the + * reference count drops to 0, the resources allocated + * for @uri will be freed. + **/ +void +thunar_vfs_uri_unref (ThunarVfsURI *uri) +{ + g_return_if_fail (THUNAR_VFS_IS_URI (uri)); + g_return_if_fail (uri->ref_count > 0); + + if (--uri->ref_count == 0) + { +#ifndef G_DISABLE_CHECKS + G_LOCK (debug_uris); + if (G_UNLIKELY (uri->host != NULL)) + memset (uri->host, 0xaa, strlen (uri->host)); + memset (uri->path, 0xaa, strlen (uri->path)); + debug_uris = g_list_remove (debug_uris, uri); + G_UNLOCK (debug_uris); +#endif + + if (G_UNLIKELY (uri->host != NULL)) + g_free (uri->host); + + g_free (uri->path); + + g_type_free_instance ((GTypeInstance *) uri); + } +} + + + /** * thunar_vfs_uri_is_home: * @uri : a #ThunarVfsURI instance. @@ -483,7 +620,8 @@ thunar_vfs_uri_parent (ThunarVfsURI *uri) return NULL; /* allocate the new object */ - parent = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + parent = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + parent->ref_count = 1; parent->host = g_strdup (uri->host); parent->path = g_path_get_dirname (uri->path); parent->scheme = uri->scheme; @@ -516,7 +654,8 @@ thunar_vfs_uri_relative (ThunarVfsURI *uri, g_return_val_if_fail (name != NULL, NULL); /* allocate the new object */ - relative = g_object_new (THUNAR_VFS_TYPE_URI, NULL); + relative = (ThunarVfsURI *) g_type_create_instance (THUNAR_VFS_TYPE_URI); + relative->ref_count = 1; relative->host = g_strdup (uri->host); relative->path = g_build_filename (uri->path, name, NULL); relative->scheme = uri->scheme; @@ -788,8 +927,6 @@ thunar_vfs_uri_list_to_string (GList *uri_list, */ for (lp = uri_list; lp != NULL; lp = lp->next) { - g_assert (THUNAR_VFS_IS_URI (lp->data)); - uri_string = thunar_vfs_uri_to_string (THUNAR_VFS_URI (lp->data), hide_options); new_list = g_strconcat (string_list, uri_string, "\r\n", NULL); g_free (string_list); @@ -815,10 +952,7 @@ thunar_vfs_uri_list_free (GList *uri_list) GList *lp; for (lp = uri_list; lp != NULL; lp = lp->next) - { - g_assert (THUNAR_VFS_IS_URI (lp->data)); - g_object_unref (G_OBJECT (lp->data)); - } + thunar_vfs_uri_unref (lp->data); g_list_free (uri_list); } diff --git a/thunar-vfs/thunar-vfs-uri.h b/thunar-vfs/thunar-vfs-uri.h index 70603fb6f..6590379eb 100644 --- a/thunar-vfs/thunar-vfs-uri.h +++ b/thunar-vfs/thunar-vfs-uri.h @@ -66,8 +66,11 @@ typedef enum GType thunar_vfs_uri_get_type (void) G_GNUC_CONST; ThunarVfsURI *thunar_vfs_uri_new (const gchar *identifier, - GError **error); -ThunarVfsURI *thunar_vfs_uri_new_for_path (const gchar *path); + GError **error) G_GNUC_MALLOC; +ThunarVfsURI *thunar_vfs_uri_new_for_path (const gchar *path) G_GNUC_MALLOC; + +ThunarVfsURI *thunar_vfs_uri_ref (ThunarVfsURI *uri); +void thunar_vfs_uri_unref (ThunarVfsURI *uri); gboolean thunar_vfs_uri_is_home (ThunarVfsURI *uri); gboolean thunar_vfs_uri_is_local (ThunarVfsURI *uri); @@ -79,9 +82,9 @@ const gchar *thunar_vfs_uri_get_name (ThunarVfsURI *uri const gchar *thunar_vfs_uri_get_path (ThunarVfsURI *uri); ThunarVfsURIScheme thunar_vfs_uri_get_scheme (ThunarVfsURI *uri); -ThunarVfsURI *thunar_vfs_uri_parent (ThunarVfsURI *uri); +ThunarVfsURI *thunar_vfs_uri_parent (ThunarVfsURI *uri) G_GNUC_MALLOC; ThunarVfsURI *thunar_vfs_uri_relative (ThunarVfsURI *uri, - const gchar *name); + const gchar *name) G_GNUC_MALLOC; gchar *thunar_vfs_uri_to_string (ThunarVfsURI *uri, ThunarVfsURIHideOptions hide_options); @@ -98,9 +101,9 @@ gchar *thunar_vfs_uri_list_to_string (GList *uri void thunar_vfs_uri_list_free (GList *uri_list); #define thunar_vfs_uri_list_append(uri_list, uri) \ - g_list_append ((uri_list), g_object_ref (G_OBJECT ((uri)))) + g_list_append ((uri_list), thunar_vfs_uri_ref ((uri))) #define thunar_vfs_uri_list_prepend(uri_list, uri) \ - g_list_prepend ((uri_list), g_object_ref (G_OBJECT ((uri)))) + g_list_prepend ((uri_list), thunar_vfs_uri_ref ((uri))) G_END_DECLS; diff --git a/thunar-vfs/thunar-vfs-volume-bsd.c b/thunar-vfs/thunar-vfs-volume-bsd.c index a4246dcc8..0379cc721 100644 --- a/thunar-vfs/thunar-vfs-volume-bsd.c +++ b/thunar-vfs/thunar-vfs-volume-bsd.c @@ -54,7 +54,6 @@ enum PROP_KIND, PROP_NAME, PROP_STATUS, - PROP_MOUNT_POINT, }; @@ -128,10 +127,6 @@ thunar_vfs_volume_bsd_class_init (ThunarVfsVolumeBSDClass *klass) g_object_class_override_property (gobject_class, PROP_STATUS, "status"); - - g_object_class_override_property (gobject_class, - PROP_MOUNT_POINT, - "mount-point"); } @@ -162,7 +157,7 @@ thunar_vfs_volume_bsd_finalize (GObject *object) g_return_if_fail (THUNAR_VFS_IS_VOLUME_BSD (volume_bsd)); if (G_LIKELY (volume_bsd->mount_point != NULL)) - g_object_unref (G_OBJECT (volume_bsd->mount_point)); + thunar_vfs_uri_unref (volume_bsd->mount_point); g_free (volume_bsd->device_path); G_OBJECT_CLASS (thunar_vfs_volume_bsd_parent_class)->finalize (object); @@ -192,10 +187,6 @@ thunar_vfs_volume_bsd_get_property (GObject *object, g_value_set_enum (value, thunar_vfs_volume_get_status (volume)); break; - case PROP_MOUNT_POINT: - g_value_set_object (value, thunar_vfs_volume_get_mount_point (volume)); - break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/thunar-vfs/thunar-vfs-volume.c b/thunar-vfs/thunar-vfs-volume.c index c884f3354..aa957ee21 100644 --- a/thunar-vfs/thunar-vfs-volume.c +++ b/thunar-vfs/thunar-vfs-volume.c @@ -120,7 +120,7 @@ thunar_vfs_volume_class_init (gpointer klass) _("The kind of the volume"), THUNAR_VFS_TYPE_VFS_VOLUME_KIND, THUNAR_VFS_VOLUME_KIND_UNKNOWN, - G_PARAM_READABLE)); + EXO_PARAM_READABLE)); /** * ThunarVfsVolume:name: @@ -133,7 +133,7 @@ thunar_vfs_volume_class_init (gpointer klass) _("Name"), _("The name of the volume"), NULL, - G_PARAM_READABLE)); + EXO_PARAM_READABLE)); /** * ThunarVfsVolume:status: @@ -146,20 +146,7 @@ thunar_vfs_volume_class_init (gpointer klass) _("Status"), _("The status of the volume"), THUNAR_VFS_TYPE_VFS_VOLUME_STATUS, - 0, G_PARAM_READABLE)); - - /** - * ThunarVfsVolume:mount-point: - * - * The path in the file system where this volume is mounted - * or will be mounted. - **/ - g_object_interface_install_property (klass, - g_param_spec_object ("mount-point", - _("Mount point"), - _("The mount point of the volume"), - THUNAR_VFS_TYPE_URI, - G_PARAM_READABLE)); + 0, EXO_PARAM_READABLE)); } diff --git a/thunar/main.c b/thunar/main.c index 931b3491f..9b3ee446d 100644 --- a/thunar/main.c +++ b/thunar/main.c @@ -61,7 +61,7 @@ main (int argc, char **argv) if (G_LIKELY (uri != NULL)) { file = thunar_file_get_for_uri (uri, &error); - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); } if (uri == NULL || file == NULL) diff --git a/thunar/thunar-computer-folder.c b/thunar/thunar-computer-folder.c index 15b31c73a..195cb1157 100644 --- a/thunar/thunar-computer-folder.c +++ b/thunar/thunar-computer-folder.c @@ -120,7 +120,7 @@ thunar_computer_folder_finalize (GObject *object) g_slist_free (computer_folder->files); /* release the folder's URI */ - g_object_unref (G_OBJECT (computer_folder->uri)); + thunar_vfs_uri_unref (computer_folder->uri); G_OBJECT_CLASS (thunar_computer_folder_parent_class)->finalize (object); } @@ -217,7 +217,7 @@ thunar_computer_folder_get_files (ThunarFolder *folder) file = thunar_file_get_for_uri (uri, NULL); if (G_LIKELY (file != NULL)) computer_folder->files = g_slist_append (computer_folder->files, file); - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); } } } @@ -259,10 +259,7 @@ thunar_computer_folder_new (ThunarVfsURI *uri, /* allocate the new object */ computer_folder = g_object_new (THUNAR_TYPE_COMPUTER_FOLDER, NULL); - computer_folder->uri = uri; - - /* take an additional reference on the uri */ - g_object_ref (G_OBJECT (uri)); + computer_folder->uri = thunar_vfs_uri_ref (uri); return THUNAR_FILE (computer_folder); } diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c index bf2f41f37..ba35e6198 100644 --- a/thunar/thunar-details-view.c +++ b/thunar/thunar-details-view.c @@ -224,6 +224,7 @@ thunar_details_view_row_activated (GtkTreeView *tree_view, gtk_tree_model_get_iter (model, &iter, path); file = thunar_list_model_get_file (THUNAR_LIST_MODEL (model), &iter); thunar_view_file_activated (THUNAR_VIEW (tree_view), file); + g_object_unref (G_OBJECT (file)); /* invoke the row activated method on the parent class */ if (GTK_TREE_VIEW_CLASS (thunar_details_view_parent_class)->row_activated != NULL) diff --git a/thunar/thunar-favourites-model.c b/thunar/thunar-favourites-model.c index 5f6b3bffb..c4ecd85af 100644 --- a/thunar/thunar-favourites-model.c +++ b/thunar/thunar-favourites-model.c @@ -189,7 +189,7 @@ thunar_favourites_model_init (ThunarFavouritesModel *model) thunar_favourites_model_add_favourite (model, favourite, path); gtk_tree_path_next (path); } - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); /* append the 'Trash' favourite */ uri = thunar_vfs_uri_new ("trash:", NULL); @@ -205,7 +205,7 @@ thunar_favourites_model_init (ThunarFavouritesModel *model) thunar_favourites_model_add_favourite (model, favourite, path); gtk_tree_path_next (path); } - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); /* append the 'Filesystem' favourite */ uri = thunar_vfs_uri_new_for_path ("/"); @@ -221,7 +221,7 @@ thunar_favourites_model_init (ThunarFavouritesModel *model) thunar_favourites_model_add_favourite (model, favourite, path); gtk_tree_path_next (path); } - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); /* prepend the removable media volumes */ volumes = thunar_vfs_volume_manager_get_volumes (model->volume_manager); @@ -284,7 +284,7 @@ thunar_favourites_model_init (ThunarFavouritesModel *model) /* try to open the file corresponding to the uri */ file = thunar_file_get_for_uri (uri, NULL); - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); if (G_UNLIKELY (file == NULL)) continue; diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c index 6654253e2..9a6f8a877 100644 --- a/thunar/thunar-file.c +++ b/thunar/thunar-file.c @@ -87,6 +87,7 @@ thunar_file_get_type (void) sizeof (ThunarFile), 0, NULL, + NULL, }; type = g_type_register_static (GTK_TYPE_OBJECT, @@ -99,11 +100,51 @@ thunar_file_get_type (void) +#ifndef G_DISABLE_CHECKS +static gboolean thunar_file_atexit_registered = FALSE; + +static void +thunar_file_atexit_foreach (gpointer key, + gpointer value, + gpointer user_data) +{ + gchar *s; + + s = thunar_vfs_uri_to_string (THUNAR_VFS_URI (key), 0); + g_print ("--> %s (%u)\n", s, G_OBJECT (value)->ref_count); + g_free (s); +} + +static void +thunar_file_atexit (void) +{ + if (file_cache == NULL || g_hash_table_size (file_cache) == 0) + return; + + g_print ("--- Leaked a total of %u ThunarFile objects:\n", + g_hash_table_size (file_cache)); + + g_hash_table_foreach (file_cache, thunar_file_atexit_foreach, NULL); + + g_print ("\n"); +} +#endif + + + static void thunar_file_class_init (ThunarFileClass *klass) { GObjectClass *gobject_class; +#ifndef G_DISABLE_CHECKS + if (G_UNLIKELY (!thunar_file_atexit_registered)) + { + g_atexit (thunar_file_atexit); + thunar_file_atexit_registered = TRUE; + } +#endif + thunar_file_parent_class = g_type_class_peek_parent (klass); gobject_class = G_OBJECT_CLASS (klass); @@ -189,7 +230,7 @@ thunar_file_real_get_parent (ThunarFile *file, parent_file = thunar_file_get_for_uri (parent_uri, error); /* release the reference on the parent_uri */ - g_object_unref (G_OBJECT (parent_uri)); + thunar_vfs_uri_unref (parent_uri); return parent_file; } @@ -283,7 +324,7 @@ thunar_file_destroyed (gpointer data, g_hash_table_remove (file_cache, uri); /* drop the reference on the uri */ - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); } @@ -335,8 +376,7 @@ thunar_file_get_for_uri (ThunarVfsURI *uri, /* insert the file into the cache */ g_object_weak_ref (G_OBJECT (file), thunar_file_destroyed, uri); - g_hash_table_insert (file_cache, uri, file); - g_object_ref (G_OBJECT (uri)); + g_hash_table_insert (file_cache, thunar_vfs_uri_ref (uri), file); } } else @@ -436,7 +476,7 @@ thunar_file_open_as_folder (ThunarFile *file, * Note, that there's no reference taken for the caller on the * returned #ThunarVfsURI, so if you need the object for a longer * period, you'll need to take a reference yourself using the - * #g_object_ref() function. + * #thunar_vfs_uri_ref() function. * * Return value: the URI to the @file. **/ diff --git a/thunar/thunar-icon-view.c b/thunar/thunar-icon-view.c index c5816f13b..b53fbd34f 100644 --- a/thunar/thunar-icon-view.c +++ b/thunar/thunar-icon-view.c @@ -127,6 +127,7 @@ thunar_icon_view_item_activated (ExoIconView *view, gtk_tree_model_get_iter (model, &iter, path); file = thunar_list_model_get_file (THUNAR_LIST_MODEL (model), &iter); thunar_view_file_activated (THUNAR_VIEW (view), file); + g_object_unref (G_OBJECT (file)); /* invoke the item_activated method on the parent class */ if (EXO_ICON_VIEW_CLASS (thunar_icon_view_parent_class)->item_activated != NULL) diff --git a/thunar/thunar-local-file.c b/thunar/thunar-local-file.c index 936c9e8af..dc5884482 100644 --- a/thunar/thunar-local-file.c +++ b/thunar/thunar-local-file.c @@ -159,7 +159,7 @@ thunar_local_file_get_parent (ThunarFile *file, if (G_LIKELY (computer_uri != NULL)) { computer_file = thunar_file_get_for_uri (computer_uri, error); - g_object_unref (G_OBJECT (computer_uri)); + thunar_vfs_uri_unref (computer_uri); } else { diff --git a/thunar/thunar-local-folder.c b/thunar/thunar-local-folder.c index 906650e71..f5a9f7741 100644 --- a/thunar/thunar-local-folder.c +++ b/thunar/thunar-local-folder.c @@ -198,7 +198,7 @@ thunar_local_folder_rescan (ThunarLocalFolder *local_folder, /* we discovered a new file */ file_uri = thunar_vfs_uri_relative (folder_uri, name); file = thunar_file_get_for_uri (file_uri, NULL); - g_object_unref (G_OBJECT (file_uri)); + thunar_vfs_uri_unref (file_uri); if (G_UNLIKELY (file == NULL)) continue; @@ -348,7 +348,7 @@ thunar_local_folder_get_for_file (ThunarLocalFile *local_file, /* try to scan the new folder */ if (G_UNLIKELY (!thunar_local_folder_rescan (local_folder, error))) { - gtk_object_sink (GTK_OBJECT (local_folder)); + g_object_unref (G_OBJECT (local_folder)); return NULL; } } diff --git a/thunar/thunar-trash-file.c b/thunar/thunar-trash-file.c index 65d9f0e63..04481c3eb 100644 --- a/thunar/thunar-trash-file.c +++ b/thunar/thunar-trash-file.c @@ -121,7 +121,7 @@ thunar_trash_file_finalize (GObject *object) g_object_unref (G_OBJECT (trash_file->real_file)); g_object_unref (G_OBJECT (trash_file->manager)); g_object_unref (G_OBJECT (trash_file->trash)); - g_object_unref (G_OBJECT (trash_file->uri)); + thunar_vfs_uri_unref (trash_file->uri); g_free (trash_file->display_name); G_OBJECT_CLASS (thunar_trash_file_parent_class)->finalize (object); @@ -279,8 +279,8 @@ thunar_trash_file_new (ThunarVfsURI *uri, if (G_UNLIKELY (real_file == NULL)) { g_object_unref (G_OBJECT (trash_manager)); - g_object_unref (G_OBJECT (real_uri)); g_object_unref (G_OBJECT (trash)); + thunar_vfs_uri_unref (real_uri); thunar_vfs_trash_info_free (info); g_free (path); return NULL; @@ -291,7 +291,7 @@ thunar_trash_file_new (ThunarVfsURI *uri, trash_file->display_name = g_path_get_basename (thunar_vfs_trash_info_get_path (info)); trash_file->manager = trash_manager; trash_file->real_file = real_file; - trash_file->uri = g_object_ref (G_OBJECT (uri)); + trash_file->uri = thunar_vfs_uri_ref (uri); trash_file->trash = trash; /* watch the real file */ @@ -300,8 +300,8 @@ thunar_trash_file_new (ThunarVfsURI *uri, thunar_file_watch (real_file); /* cleanup */ - g_object_unref (G_OBJECT (real_uri)); thunar_vfs_trash_info_free (info); + thunar_vfs_uri_unref (real_uri); g_free (path); return THUNAR_FILE (trash_file); diff --git a/thunar/thunar-trash-folder.c b/thunar/thunar-trash-folder.c index d45d9814a..b32eae5f2 100644 --- a/thunar/thunar-trash-folder.c +++ b/thunar/thunar-trash-folder.c @@ -128,6 +128,9 @@ thunar_trash_folder_finalize (GObject *object) g_signal_handlers_disconnect_by_func (G_OBJECT (trash_folder->manager), thunar_file_changed, trash_folder); g_object_unref (G_OBJECT (trash_folder->manager)); + /* release the trash URI */ + thunar_vfs_uri_unref (trash_folder->uri); + G_OBJECT_CLASS (thunar_trash_folder_parent_class)->finalize (object); } @@ -145,7 +148,7 @@ thunar_trash_folder_get_parent (ThunarFile *file, if (G_LIKELY (computer_uri != NULL)) { computer_file = thunar_file_get_for_uri (computer_uri, error); - g_object_unref (G_OBJECT (computer_uri)); + thunar_vfs_uri_unref (computer_uri); } else { @@ -267,7 +270,7 @@ thunar_trash_folder_get_files (ThunarFolder *folder) file = thunar_file_get_for_uri (uri, NULL); if (file != NULL) trash_folder->files = g_slist_prepend (trash_folder->files, file); - g_object_unref (G_OBJECT (uri)); + thunar_vfs_uri_unref (uri); } g_object_unref (G_OBJECT (trash)); } @@ -311,10 +314,7 @@ thunar_trash_folder_new (ThunarVfsURI *uri, /* allocate the new object */ trash_folder = g_object_new (THUNAR_TYPE_TRASH_FOLDER, NULL); - trash_folder->uri = uri; - - /* take an additional reference on the uri */ - g_object_ref (G_OBJECT (uri)); + trash_folder->uri = thunar_vfs_uri_ref (uri); return THUNAR_FILE (trash_folder); } diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index e7d381199..24e76fb48 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -39,25 +39,27 @@ enum -static void thunar_window_class_init (ThunarWindowClass *klass); -static void thunar_window_init (ThunarWindow *window); -static void thunar_window_dispose (GObject *object); -static void thunar_window_finalize (GObject *object); -static void thunar_window_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_window_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_window_action_close (GtkAction *action, - ThunarWindow *window); -static void thunar_window_action_go_up (GtkAction *action, - ThunarWindow *window); -static void thunar_window_file_activated (ThunarView *view, - ThunarFile *file, - ThunarWindow *window); +static void thunar_window_class_init (ThunarWindowClass *klass); +static void thunar_window_init (ThunarWindow *window); +static void thunar_window_dispose (GObject *object); +static void thunar_window_finalize (GObject *object); +static void thunar_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_window_action_close (GtkAction *action, + ThunarWindow *window); +static void thunar_window_action_go_up (GtkAction *action, + ThunarWindow *window); +static void thunar_window_file_activated (ThunarView *view, + ThunarFile *file, + ThunarWindow *window); +static gboolean thunar_window_cursor_idle (gpointer user_data); +static void thunar_window_cursor_idle_destroy (gpointer user_data); @@ -79,6 +81,8 @@ struct _ThunarWindow GtkWidget *statusbar; ThunarFile *current_directory; + + gint cursor_idle_id; }; @@ -152,6 +156,8 @@ thunar_window_init (ThunarWindow *window) GtkWidget *swin; GtkWidget *box; + window->cursor_idle_id = -1; + window->action_group = gtk_action_group_new ("thunar-window"); gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), @@ -243,6 +249,10 @@ thunar_window_finalize (GObject *object) { ThunarWindow *window = THUNAR_WINDOW (object); + /* stop the reset cursor idle source */ + if (G_UNLIKELY (window->cursor_idle_id >= 0)) + g_source_remove (window->cursor_idle_id); + g_object_unref (G_OBJECT (window->action_group)); g_object_unref (G_OBJECT (window->ui_manager)); @@ -299,7 +309,7 @@ static void thunar_window_action_close (GtkAction *action, ThunarWindow *window) { - gtk_main_quit (); + gtk_object_destroy (GTK_OBJECT (window)); } @@ -336,6 +346,33 @@ thunar_window_file_activated (ThunarView *view, +static gboolean +thunar_window_cursor_idle (gpointer user_data) +{ + GtkWidget *widget = user_data; + + GDK_THREADS_ENTER (); + + if (GTK_WIDGET_REALIZED (widget)) + gdk_window_set_cursor (widget->window, NULL); + + GDK_THREADS_LEAVE (); + + return FALSE; +} + + + +static void +thunar_window_cursor_idle_destroy (gpointer user_data) +{ + GDK_THREADS_ENTER (); + THUNAR_WINDOW (user_data)->cursor_idle_id = -1; + GDK_THREADS_LEAVE (); +} + + + /** * thunar_window_new: * @@ -385,6 +422,7 @@ thunar_window_set_current_directory (ThunarWindow *window, GtkAction *action; GtkWidget *dialog; GdkPixbuf *icon; + GdkCursor *cursor; GError *error = NULL; g_return_if_fail (THUNAR_IS_WINDOW (window)); @@ -423,6 +461,12 @@ thunar_window_set_current_directory (ThunarWindow *window, NULL); } + /* tell everybody that we have a new "current-directory", + * we do this first so other widgets display the new + * state already while the folder view is loading. + */ + g_object_notify (G_OBJECT (window), "current-directory"); + /* setup the folder for the view, we use a simple but very effective * trick here to speed up the folder change: we completely disconnect * the model from the view, load the folder into the model and afterwards @@ -436,6 +480,29 @@ thunar_window_set_current_directory (ThunarWindow *window, thunar_view_set_model (THUNAR_VIEW (window->view), NULL); if (G_LIKELY (current_directory != NULL)) { + if (GTK_WIDGET_REALIZED (window)) + { + /* set watch cursor */ + cursor = gdk_cursor_new (GDK_WATCH); + gdk_window_set_cursor (GTK_WIDGET (window)->window, cursor); + gdk_cursor_unref (cursor); + + /* be sure to display the watch cursor and the empty view + * (FIXME: This seems to cause some ugly flickering!) + */ + while (gtk_events_pending ()) + gtk_main_iteration (); + + /* register an idle function to reset the cursor once + * everything below is done. + */ + if (G_LIKELY (window->cursor_idle_id < 0)) + { + window->cursor_idle_id = g_idle_add_full (G_PRIORITY_LOW + 100, thunar_window_cursor_idle, + window, thunar_window_cursor_idle_destroy); + } + } + /* try to open the directory */ folder = thunar_file_open_as_folder (current_directory, &error); if (G_LIKELY (folder != NULL)) @@ -473,9 +540,6 @@ thunar_window_set_current_directory (ThunarWindow *window, } thunar_view_set_model (THUNAR_VIEW (window->view), model); g_object_unref (G_OBJECT (model)); - - /* tell everybody that we have a new "current-directory" */ - g_object_notify (G_OBJECT (window), "current-directory"); } -- GitLab