From 6362396978025a4291181e41a9a1998a5699e74a Mon Sep 17 00:00:00 2001
From: Benedikt Meurer <benny@xfce.org>
Date: Thu, 15 Sep 2005 21:41:36 +0000
Subject: [PATCH] 2005-09-15	Benedikt Meurer <benny@xfce.org>

	* thunar-vfs/thunar-vfs-interactive-job.{c,h},
	  thunar-vfs/thunar-vfs-job.{c,h},
	  thunar-vfs/thunar-vfs-listdir-job.{c,h},
	  thunar-vfs/thunar-vfs-transfer-job.{c,h},
	  thunar-vfs/thunar-vfs-unlink-job.{c,h}: Allocate a new main loop for
	  every running job so we can terminate them properly and be sure to
	  run the finalize method in the main thread. This enables us to use
	  arbitrary GObjects within a job without having to worry about the
	  reference counting problem in GLib 2.6. The jobs are GObjects as well
	  now to easily support language bindings and allow us to drop the
	  problematic ExoObject class.




(Old svn revision: 17633)
---
 ChangeLog                               |  14 ++
 thunar-vfs/thunar-vfs-interactive-job.c |  60 +++----
 thunar-vfs/thunar-vfs-interactive-job.h |   5 +
 thunar-vfs/thunar-vfs-job.c             | 213 +++++++++++++++---------
 thunar-vfs/thunar-vfs-job.h             |  27 +--
 thunar-vfs/thunar-vfs-listdir-job.c     |  83 +++++----
 thunar-vfs/thunar-vfs-listdir-job.h     |  15 +-
 thunar-vfs/thunar-vfs-transfer-job.c    |  69 ++++----
 thunar-vfs/thunar-vfs-transfer-job.h    |  15 +-
 thunar-vfs/thunar-vfs-unlink-job.c      |  89 +++++-----
 thunar-vfs/thunar-vfs-unlink-job.h      |  15 +-
 11 files changed, 343 insertions(+), 262 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 86c4119f8..da3811061 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-09-15	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-interactive-job.{c,h},
+	  thunar-vfs/thunar-vfs-job.{c,h},
+	  thunar-vfs/thunar-vfs-listdir-job.{c,h},
+	  thunar-vfs/thunar-vfs-transfer-job.{c,h},
+	  thunar-vfs/thunar-vfs-unlink-job.{c,h}: Allocate a new main loop for
+	  every running job so we can terminate them properly and be sure to
+	  run the finalize method in the main thread. This enables us to use
+	  arbitrary GObjects within a job without having to worry about the
+	  reference counting problem in GLib 2.6. The jobs are GObjects as well
+	  now to easily support language bindings and allow us to drop the
+	  problematic ExoObject class.
+
 2005-09-14	Benedikt Meurer <benny@xfce.org>
 
 	* thunar/thunar-launcher.c(thunar_launcher_open_files): Use
diff --git a/thunar-vfs/thunar-vfs-interactive-job.c b/thunar-vfs/thunar-vfs-interactive-job.c
index eab2138b9..4b0e20134 100644
--- a/thunar-vfs/thunar-vfs-interactive-job.c
+++ b/thunar-vfs/thunar-vfs-interactive-job.c
@@ -43,14 +43,13 @@ enum
 
 
 
-static void                            thunar_vfs_interactive_job_register_type (GType                          *type);
-static void                            thunar_vfs_interactive_job_class_init    (ThunarVfsInteractiveJobClass   *klass);
-static ThunarVfsInteractiveJobResponse thunar_vfs_interactive_job_real_ask      (ThunarVfsInteractiveJob        *interactive_job,
-                                                                                 const gchar                    *message,
-                                                                                 ThunarVfsInteractiveJobResponse choices);
-static ThunarVfsInteractiveJobResponse thunar_vfs_interactive_job_ask           (ThunarVfsInteractiveJob        *interactive_job,
-                                                                                 const gchar                    *message,
-                                                                                 ThunarVfsInteractiveJobResponse choices);
+static void                            thunar_vfs_interactive_job_class_init (ThunarVfsInteractiveJobClass   *klass);
+static ThunarVfsInteractiveJobResponse thunar_vfs_interactive_job_real_ask   (ThunarVfsInteractiveJob        *interactive_job,
+                                                                              const gchar                    *message,
+                                                                              ThunarVfsInteractiveJobResponse choices);
+static ThunarVfsInteractiveJobResponse thunar_vfs_interactive_job_ask        (ThunarVfsInteractiveJob        *interactive_job,
+                                                                              const gchar                    *message,
+                                                                              ThunarVfsInteractiveJobResponse choices);
 
 
 
@@ -62,38 +61,31 @@ GType
 thunar_vfs_interactive_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
-  static GOnce once = G_ONCE_INIT;
 
-  /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_interactive_job_register_type, &type);
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarVfsInteractiveJobClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunar_vfs_interactive_job_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsInteractiveJob),
+        0,
+        NULL,
+        NULL,
+      };
+
+      type = g_type_register_static (THUNAR_VFS_TYPE_JOB, "ThunarVfsInteractiveJob", &info, G_TYPE_FLAG_ABSTRACT);
+    }
 
   return type;
 }
 
 
 
-static void
-thunar_vfs_interactive_job_register_type (GType *type)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (ThunarVfsInteractiveJobClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) thunar_vfs_interactive_job_class_init,
-    NULL,
-    NULL,
-    sizeof (ThunarVfsInteractiveJob),
-    0,
-    NULL,
-    NULL,
-  };
-
-  *type = g_type_register_static (THUNAR_VFS_TYPE_JOB, "ThunarVfsInteractiveJob", &info, G_TYPE_FLAG_ABSTRACT);
-}
-
-
-
 static gboolean
 ask_accumulator (GSignalInvocationHint *ihint,
                  GValue                *return_accu,
@@ -256,7 +248,7 @@ thunar_vfs_interactive_job_percent (ThunarVfsInteractiveJob *interactive_job,
  *
  * The return value may be %TRUE to perform the overwrite, or %FALSE,
  * which means to either skip the file or cancel the @interactive_job.
- * The caller must check using #thunar_vfs_job_cancelled() if %FALSE
+ * The caller must check using thunar_vfs_job_cancelled() if %FALSE
  * is returned.
  *
  * Return value: %TRUE to overwrite or %FALSE to leave it or cancel
diff --git a/thunar-vfs/thunar-vfs-interactive-job.h b/thunar-vfs/thunar-vfs-interactive-job.h
index ebf8937ed..0f621206a 100644
--- a/thunar-vfs/thunar-vfs-interactive-job.h
+++ b/thunar-vfs/thunar-vfs-interactive-job.h
@@ -58,6 +58,11 @@ struct _ThunarVfsInteractiveJobClass
   ThunarVfsInteractiveJobResponse (*ask) (ThunarVfsInteractiveJob        *interactive_job,
                                           const gchar                    *message,
                                           ThunarVfsInteractiveJobResponse choices);
+
+  /*< private >*/
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
 };
 
 struct _ThunarVfsInteractiveJob
diff --git a/thunar-vfs/thunar-vfs-job.c b/thunar-vfs/thunar-vfs-job.c
index 7ed1cd359..46b838beb 100644
--- a/thunar-vfs/thunar-vfs-job.c
+++ b/thunar-vfs/thunar-vfs-job.c
@@ -29,13 +29,18 @@
 #include <string.h>
 #endif
 
-#include <gobject/gvaluecollector.h>
+#include <gdk/gdk.h>
 
 #include <thunar-vfs/thunar-vfs-job.h>
 #include <thunar-vfs/thunar-vfs-alias.h>
 
 
 
+#define THUNAR_VFS_JOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), THUNAR_VFS_TYPE_JOB, ThunarVfsJobPrivate))
+
+
+
+/* Signal identifiers */
 enum
 {
   ERROR,
@@ -43,6 +48,9 @@ enum
   LAST_SIGNAL,
 };
 
+
+
+/* signal emission details */
 typedef struct
 {
   ThunarVfsJob     *job;
@@ -54,19 +62,30 @@ typedef struct
 
 
 
-static void     thunar_vfs_job_register_type      (GType             *type);
-static void     thunar_vfs_job_class_init         (ThunarVfsJobClass *klass);
-static void     thunar_vfs_job_init               (ThunarVfsJob      *job);
-static void     thunar_vfs_job_finalize           (ExoObject         *object);
-static void     thunar_vfs_job_execute            (gpointer           data,
-                                                   gpointer           user_data);
-static gboolean thunar_vfs_job_idle               (gpointer           user_data);
+static void     thunar_vfs_job_class_init  (ThunarVfsJobClass *klass);
+static void     thunar_vfs_job_init        (ThunarVfsJob      *job);
+static void     thunar_vfs_job_finalize    (GObject           *object);
+static void     thunar_vfs_job_execute     (gpointer           data,
+                                            gpointer           user_data);
+static gboolean thunar_vfs_job_emit_idle   (gpointer           user_data);
+static gboolean thunar_vfs_job_launch_idle (gpointer           user_data);
+
 
 
+struct _ThunarVfsJobPrivate
+{
+  GCond     *cond;
+  GMutex    *mutex;
+  GMainLoop *loop;
+  gint       launch_idle_id;
+  gboolean   cancelled;
+};
+
 
-static ExoObjectClass *thunar_vfs_job_parent_class;
-static guint           job_signals[LAST_SIGNAL];
-static GThreadPool    *job_pool = NULL;
+
+static GObjectClass *thunar_vfs_job_parent_class;
+static guint         job_signals[LAST_SIGNAL];
+static GThreadPool  *job_pool = NULL;
 
 
 
@@ -74,47 +93,44 @@ GType
 thunar_vfs_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
-  static GOnce once = G_ONCE_INIT;
 
-  /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_job_register_type, &type);
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarVfsJobClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunar_vfs_job_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsJob),
+        0,
+        (GInstanceInitFunc) thunar_vfs_job_init,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_OBJECT, "ThunarVfsJob", &info, G_TYPE_FLAG_ABSTRACT);
+    }
 
   return type;
 }
 
 
 
-static void
-thunar_vfs_job_register_type (GType *type)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (ThunarVfsJobClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) thunar_vfs_job_class_init,
-    NULL,
-    NULL,
-    sizeof (ThunarVfsJob),
-    0,
-    (GInstanceInitFunc) thunar_vfs_job_init,
-    NULL,
-  };
-
-  *type = g_type_register_static (EXO_TYPE_OBJECT, "ThunarVfsJob", &info, G_TYPE_FLAG_ABSTRACT);
-}
-
-
-
 static void
 thunar_vfs_job_class_init (ThunarVfsJobClass *klass)
 {
-  ExoObjectClass *exoobject_class;
+  GObjectClass *gobject_class;
+
+  /* add our private data for this class */
+  g_type_class_add_private (klass, sizeof (ThunarVfsJobPrivate));
 
+  /* determine the parent class */
   thunar_vfs_job_parent_class = g_type_class_peek_parent (klass);
 
-  exoobject_class = EXO_OBJECT_CLASS (klass);
-  exoobject_class->finalize = thunar_vfs_job_finalize;
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_job_finalize;
 
   /**
    * ThunarVfsJob::error:
@@ -153,26 +169,32 @@ thunar_vfs_job_class_init (ThunarVfsJobClass *klass)
 static void
 thunar_vfs_job_init (ThunarVfsJob *job)
 {
-  job->cond = g_cond_new ();
-  job->mutex = g_mutex_new ();
+  job->priv = THUNAR_VFS_JOB_GET_PRIVATE (job);
+  job->priv->cond = g_cond_new ();
+  job->priv->mutex = g_mutex_new ();
+  job->priv->launch_idle_id = -1;
 }
 
 
 
 static void
-thunar_vfs_job_finalize (ExoObject *object)
+thunar_vfs_job_finalize (GObject *object)
 {
   ThunarVfsJob *job = THUNAR_VFS_JOB (object);
 
-  /* destroy the synchronization entities */
-  g_mutex_free (job->mutex);
-  g_cond_free (job->cond);
+  g_return_if_fail (THUNAR_VFS_IS_JOB (job));
+  g_return_if_fail (job->priv->loop == NULL);
+
+  /* drop the launch idle source if it's active */
+  if (G_LIKELY (job->priv->launch_idle_id >= 0))
+    g_source_remove (job->priv->launch_idle_id);
 
-  /* disconnect all handlers for this instance */
-  g_signal_handlers_destroy (job);
+  /* destroy the synchronization entities */
+  g_mutex_free (job->priv->mutex);
+  g_cond_free (job->priv->cond);
 
   /* invoke the parent's finalize method */
-  (*EXO_OBJECT_CLASS (thunar_vfs_job_parent_class)->finalize) (object);
+  (*G_OBJECT_CLASS (thunar_vfs_job_parent_class)->finalize) (object);
 }
 
 
@@ -183,27 +205,27 @@ thunar_vfs_job_execute (gpointer data,
 {
   ThunarVfsJob *job = THUNAR_VFS_JOB (data);
 
+  g_return_if_fail (THUNAR_VFS_IS_JOB (job));
+  g_return_if_fail (job->priv->loop != NULL);
+
   /* perform the real work */
   (*THUNAR_VFS_JOB_GET_CLASS (job)->execute) (job);
 
-  /* emit the "finished" signal (if not cancelled!) */
-  thunar_vfs_job_emit (job, job_signals[FINISHED], 0);
-
-  /* cleanup */
-  thunar_vfs_job_unref (job);
+  /* exit from the execution loop */
+  g_main_loop_quit (job->priv->loop);
 }
 
 
 
 static gboolean
-thunar_vfs_job_idle (gpointer user_data)
+thunar_vfs_job_emit_idle (gpointer user_data)
 {
   ThunarVfsJobEmitDetails *details = user_data;
   ThunarVfsJob            *job = details->job;
 
   g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE);
 
-  g_mutex_lock (job->mutex);
+  g_mutex_lock (job->priv->mutex);
 
   /* emit the signal */
   GDK_THREADS_ENTER ();
@@ -212,8 +234,8 @@ thunar_vfs_job_idle (gpointer user_data)
 
   /* tell the other thread, that we're done */
   details->pending = FALSE;
-  g_cond_signal (job->cond);
-  g_mutex_unlock (job->mutex);
+  g_cond_signal (job->priv->cond);
+  g_mutex_unlock (job->priv->mutex);
 
   /* remove the idle source */
   return FALSE;
@@ -221,6 +243,41 @@ thunar_vfs_job_idle (gpointer user_data)
 
 
 
+static gboolean
+thunar_vfs_job_launch_idle (gpointer user_data)
+{
+  ThunarVfsJob *job = THUNAR_VFS_JOB (user_data);
+
+  g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE);
+  g_return_val_if_fail (job_pool != NULL, FALSE);
+
+  /* take an additional reference on the job */
+  g_object_ref (G_OBJECT (job));
+
+  /* allocate a main loop for this job */
+  job->priv->loop = g_main_loop_new (NULL, FALSE);
+
+  /* schedule a thread to handle the job */
+  g_thread_pool_push (job_pool, job, NULL);
+
+  /* wait for the job to finish */
+  g_main_loop_run (job->priv->loop);
+
+  /* emit the "finished" signal */
+  g_signal_emit (G_OBJECT (job), job_signals[FINISHED], 0);
+
+  /* drop the main loop */
+  g_main_loop_unref (job->priv->loop);
+  job->priv->loop = NULL;
+
+  /* drop the additional reference on the job */
+  g_object_unref (G_OBJECT (job));
+
+  return FALSE;
+}
+
+
+
 /**
  * thunar_vfs_job_launch:
  * @job : a #ThunarVfsJob.
@@ -234,15 +291,11 @@ ThunarVfsJob*
 thunar_vfs_job_launch (ThunarVfsJob *job)
 {
   g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), NULL);
-  g_return_val_if_fail (!job->launched, NULL);
-  g_return_val_if_fail (!job->cancelled, NULL);
+  g_return_val_if_fail (job->priv->launch_idle_id < 0, NULL);
   g_return_val_if_fail (job_pool != NULL, NULL);
 
-  /* mark the job as launched */
-  job->launched = TRUE;
-
-  /* schedule the job on the thread pool */
-  g_thread_pool_push (job_pool, thunar_vfs_job_ref (job), NULL);
+  /* schedule the launch idle source */
+  job->priv->launch_idle_id = g_idle_add_full (G_PRIORITY_HIGH, thunar_vfs_job_launch_idle, job, NULL);
 
   return job;
 }
@@ -264,8 +317,7 @@ void
 thunar_vfs_job_cancel (ThunarVfsJob *job)
 {
   g_return_if_fail (THUNAR_VFS_IS_JOB (job));
-
-  job->cancelled = TRUE;
+  job->priv->cancelled = TRUE;
 }
 
 
@@ -275,7 +327,7 @@ thunar_vfs_job_cancel (ThunarVfsJob *job)
  * @job : a #ThunarVfsJob.
  *
  * Checks whether @job was previously cancelled
- * by a call to #thunar_vfs_job_cancel().
+ * by a call to thunar_vfs_job_cancel().
  *
  * Return value: %TRUE if @job is cancelled.
  **/
@@ -283,8 +335,7 @@ gboolean
 thunar_vfs_job_cancelled (const ThunarVfsJob *job)
 {
   g_return_val_if_fail (THUNAR_VFS_IS_JOB (job), FALSE);
-
-  return job->cancelled;
+  return job->priv->cancelled;
 }
 
 
@@ -296,7 +347,7 @@ thunar_vfs_job_cancelled (const ThunarVfsJob *job)
  * @signal_detail : the detail.
  * @var_args      : a list of paramters to be passed to the signal,
  *                  folled by a location for the return value. If
- *                  the return type of the signals is #G_TYPE_NONE,
+ *                  the return type of the signals is %G_TYPE_NONE,
  *                  the return value location can be omitted.
  *
  * Emits the signal identified by @signal_id on @job in
@@ -312,7 +363,7 @@ thunar_vfs_job_emit_valist (ThunarVfsJob *job,
   ThunarVfsJobEmitDetails details;
 
   g_return_if_fail (THUNAR_VFS_IS_JOB (job));
-  g_return_if_fail (job->launched);
+  g_return_if_fail (job->priv->loop != NULL);
 
   details.job = job;
   details.signal_id = signal_id;
@@ -322,11 +373,11 @@ thunar_vfs_job_emit_valist (ThunarVfsJob *job,
   /* copy the variable argument list (portable) */
   G_VA_COPY (details.var_args, var_args);
 
-  g_mutex_lock (job->mutex);
-  g_idle_add_full (G_PRIORITY_LOW, thunar_vfs_job_idle, &details, NULL);
+  g_mutex_lock (job->priv->mutex);
+  g_idle_add_full (G_PRIORITY_HIGH, thunar_vfs_job_emit_idle, &details, NULL);
   while (G_UNLIKELY (details.pending))
-    g_cond_wait (job->cond, job->mutex);
-  g_mutex_unlock (job->mutex);
+    g_cond_wait (job->priv->cond, job->priv->mutex);
+  g_mutex_unlock (job->priv->mutex);
 }
 
 
@@ -334,9 +385,11 @@ thunar_vfs_job_emit_valist (ThunarVfsJob *job,
 /**
  * thunar_vfs_job_emit:
  * @job           : a #ThunarVfsJob.
- * @signal_id     :
- * @signal_detail :
- * @...           :
+ * @signal_id     : the id of the signal to emit on qjob.
+ * @signal_detail : the signal detail.
+ * @...           : a list of parameters to be passed to the signal.
+ *
+ * Convenience wrapper for thunar_vfs_job_emit_valist().
  **/
 void
 thunar_vfs_job_emit (ThunarVfsJob *job,
@@ -379,7 +432,7 @@ thunar_vfs_job_error (ThunarVfsJob *job,
 /**
  * _thunar_vfs_job_init:
  *
- * Initializes the jobs module of the ThunarVFS
+ * Initializes the jobs module of the Thunar-VFS
  * library.
  **/
 void
@@ -395,7 +448,7 @@ _thunar_vfs_job_init (void)
 /**
  * _thunar_vfs_job_shutdown:
  *
- * Shuts down the jobs module of the ThunarVFS
+ * Shuts down the jobs module of the Thunar-VFS
  * library.
  **/
 void
diff --git a/thunar-vfs/thunar-vfs-job.h b/thunar-vfs/thunar-vfs-job.h
index 4a1f18c9a..ad8e18e80 100644
--- a/thunar-vfs/thunar-vfs-job.h
+++ b/thunar-vfs/thunar-vfs-job.h
@@ -21,12 +21,13 @@
 #ifndef __THUNAR_VFS_JOB_H__
 #define __THUNAR_VFS_JOB_H__
 
-#include <thunar-vfs/thunar-vfs-info.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS;
 
-typedef struct _ThunarVfsJobClass ThunarVfsJobClass;
-typedef struct _ThunarVfsJob      ThunarVfsJob;
+typedef struct _ThunarVfsJobPrivate ThunarVfsJobPrivate;
+typedef struct _ThunarVfsJobClass   ThunarVfsJobClass;
+typedef struct _ThunarVfsJob        ThunarVfsJob;
 
 #define THUNAR_VFS_TYPE_JOB             (thunar_vfs_job_get_type ())
 #define THUNAR_VFS_JOB(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_JOB, ThunarVfsJob))
@@ -37,23 +38,27 @@ typedef struct _ThunarVfsJob      ThunarVfsJob;
 
 struct _ThunarVfsJobClass
 {
-  ExoObjectClass __parent__;
+  GObjectClass __parent__;
 
   /* virtual methods */
   void (*execute)  (ThunarVfsJob *job);
 
   /* signals */
   void (*finished) (ThunarVfsJob *job);
+
+  /*< private >*/
+  void (*reserved1) (void);
+  void (*reserved2) (void);
+  void (*reserved3) (void);
+  void (*reserved4) (void);
 };
 
 struct _ThunarVfsJob
 {
-  ExoObject __parent__;
+  GObject __parent__;
 
-  GCond            *cond;
-  GMutex           *mutex;
-  volatile gboolean launched;
-  volatile gboolean cancelled;
+  /*< private >*/
+  ThunarVfsJobPrivate *priv;
 };
 
 GType         thunar_vfs_job_get_type     (void) G_GNUC_CONST;
@@ -72,7 +77,7 @@ gboolean      thunar_vfs_job_cancelled    (const ThunarVfsJob *job);
  *
  * Return value: a pointer to @job.
  **/
-#define thunar_vfs_job_ref exo_object_ref
+#define thunar_vfs_job_ref g_object_ref
 
 /**
  * thunar_vfs_job_unref:
@@ -83,7 +88,7 @@ gboolean      thunar_vfs_job_cancelled    (const ThunarVfsJob *job);
  * the resources allocated to @job will be
  * freed.
  **/
-#define thunar_vfs_job_unref exo_object_unref
+#define thunar_vfs_job_unref g_object_unref
 
 
 /* module API */
diff --git a/thunar-vfs/thunar-vfs-listdir-job.c b/thunar-vfs/thunar-vfs-listdir-job.c
index 5793e2876..4881e37bd 100644
--- a/thunar-vfs/thunar-vfs-listdir-job.c
+++ b/thunar-vfs/thunar-vfs-listdir-job.c
@@ -42,8 +42,10 @@
 #include <time.h>
 #endif
 
+#include <thunar-vfs/thunar-vfs-info.h>
 #include <thunar-vfs/thunar-vfs-listdir-job.h>
 #include <thunar-vfs/thunar-vfs-sysdep.h>
+#include <thunar-vfs/thunar-vfs-alias.h>
 
 
 
@@ -55,23 +57,26 @@ enum
 
 
 
-static void  thunar_vfs_listdir_job_register_type (GType             *type);
-static void  thunar_vfs_listdir_job_class_init    (ThunarVfsJobClass *klass);
-static void  thunar_vfs_listdir_job_finalize      (ExoObject         *object);
-static void  thunar_vfs_listdir_job_execute       (ThunarVfsJob      *job);
+static void  thunar_vfs_listdir_job_class_init (ThunarVfsJobClass *klass);
+static void  thunar_vfs_listdir_job_finalize   (GObject           *object);
+static void  thunar_vfs_listdir_job_execute    (ThunarVfsJob      *job);
 
 
+struct _ThunarVfsListdirJobClass
+{
+  ThunarVfsJobClass __parent__;
+};
+
 struct _ThunarVfsListdirJob
 {
   ThunarVfsJob __parent__;
-
   ThunarVfsURI *uri;
 };
 
 
 
-static guint           listdir_signals[LAST_SIGNAL];
-static ExoObjectClass *thunar_vfs_listdir_job_parent_class;
+static GObjectClass *thunar_vfs_listdir_job_parent_class;
+static guint         listdir_signals[LAST_SIGNAL];
 
 
 
@@ -79,49 +84,43 @@ GType
 thunar_vfs_listdir_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
-  static GOnce once = G_ONCE_INIT;
 
-  /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_listdir_job_register_type, &type);
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarVfsListdirJobClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunar_vfs_listdir_job_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsListdirJob),
+        0,
+        NULL,
+        NULL,
+      };
+
+      type = g_type_register_static (THUNAR_VFS_TYPE_JOB,
+                                     "ThunarVfsListdirJob",
+                                     &info, 0);
+    }
 
   return type;
 }
 
 
 
-static void
-thunar_vfs_listdir_job_register_type (GType *type)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (ThunarVfsJobClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) thunar_vfs_listdir_job_class_init,
-    NULL,
-    NULL,
-    sizeof (ThunarVfsListdirJob),
-    0,
-    NULL,
-    NULL,
-  };
-
-  *type = g_type_register_static (THUNAR_VFS_TYPE_JOB,
-                                  "ThunarVfsListdirJob",
-                                  &info, 0);
-}
-
-
-
 static void
 thunar_vfs_listdir_job_class_init (ThunarVfsJobClass *klass)
 {
-  ExoObjectClass *exoobject_class;
+  GObjectClass *gobject_class;
 
+  /* determine the parent class */
   thunar_vfs_listdir_job_parent_class = g_type_class_peek_parent (klass);
 
-  exoobject_class = EXO_OBJECT_CLASS (klass);
-  exoobject_class->finalize = thunar_vfs_listdir_job_finalize;
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_listdir_job_finalize;
 
   klass->execute = thunar_vfs_listdir_job_execute;
 
@@ -145,7 +144,7 @@ thunar_vfs_listdir_job_class_init (ThunarVfsJobClass *klass)
 
 
 static void
-thunar_vfs_listdir_job_finalize (ExoObject *object)
+thunar_vfs_listdir_job_finalize (GObject *object)
 {
   ThunarVfsListdirJob *listdir_job = THUNAR_VFS_LISTDIR_JOB (object);
 
@@ -154,7 +153,7 @@ thunar_vfs_listdir_job_finalize (ExoObject *object)
     thunar_vfs_uri_unref (listdir_job->uri);
 
   /* call the parents finalize method */
-  (*EXO_OBJECT_CLASS (thunar_vfs_listdir_job_parent_class)->finalize) (object);
+  (*G_OBJECT_CLASS (thunar_vfs_listdir_job_parent_class)->finalize) (object);
 }
 
 
@@ -249,11 +248,11 @@ thunar_vfs_listdir_job_execute (ThunarVfsJob *job)
  * Allocates a new #ThunarVfsListdirJob object, which can be used to
  * query the contents of the directory @folder_uri.
  *
- * You need to call #thunar_vfs_job_launch() in order to start the
+ * You need to call thunar_vfs_job_launch() in order to start the
  * job. You may want to connect to ::finished, ::error-occurred and
  * ::infos-ready prior to launching the job.
  *
- * The caller is responsible to call #thunar_vfs_job_unref() on the
+ * The caller is responsible to call g_object_unref() on the
  * returned object.
  *
  * Return value: the newly allocated #ThunarVfsJob, which performs the
@@ -266,7 +265,7 @@ thunar_vfs_listdir_job_new (ThunarVfsURI *folder_uri)
 
   g_return_val_if_fail (folder_uri != NULL, NULL);
 
-  listdir_job = exo_object_new (THUNAR_VFS_TYPE_LISTDIR_JOB);
+  listdir_job = g_object_new (THUNAR_VFS_TYPE_LISTDIR_JOB, NULL);
   listdir_job->uri = thunar_vfs_uri_ref (folder_uri);
 
   return THUNAR_VFS_JOB (listdir_job);
diff --git a/thunar-vfs/thunar-vfs-listdir-job.h b/thunar-vfs/thunar-vfs-listdir-job.h
index ce6844101..8d8fba816 100644
--- a/thunar-vfs/thunar-vfs-listdir-job.h
+++ b/thunar-vfs/thunar-vfs-listdir-job.h
@@ -22,18 +22,23 @@
 #define __THUNAR_VFS_LISTDIR_JOB_H__
 
 #include <thunar-vfs/thunar-vfs-job.h>
+#include <thunar-vfs/thunar-vfs-uri.h>
 
 G_BEGIN_DECLS;
 
-typedef struct _ThunarVfsListdirJob ThunarVfsListdirJob;
+typedef struct _ThunarVfsListdirJobClass ThunarVfsListdirJobClass;
+typedef struct _ThunarVfsListdirJob      ThunarVfsListdirJob;
 
-#define THUNAR_VFS_TYPE_LISTDIR_JOB     (thunar_vfs_listdir_job_get_type ())
-#define THUNAR_VFS_LISTDIR_JOB(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB, ThunarVfsListdirJob))
-#define THUNAR_VFS_IS_LISTDIR_JOB(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB))
+#define THUNAR_VFS_TYPE_LISTDIR_JOB             (thunar_vfs_listdir_job_get_type ())
+#define THUNAR_VFS_LISTDIR_JOB(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB, ThunarVfsListdirJob))
+#define THUNAR_VFS_LISTDIR_JOB_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_LISTDIR_JOB, ThunarVfsListdirJobClass))
+#define THUNAR_VFS_IS_LISTDIR_JOB(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB))
+#define THUNAR_VFS_IS_LISTDIR_JOB_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_LISTDIR_JOB))
+#define THUNAR_VFS_LISTDIR_JOB_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_LISTDIR_JOB, ThunarVfsListdirJobClass))
 
 GType         thunar_vfs_listdir_job_get_type (void) G_GNUC_CONST;
 
-ThunarVfsJob *thunar_vfs_listdir_job_new      (ThunarVfsURI *folder_uri);
+ThunarVfsJob *thunar_vfs_listdir_job_new      (ThunarVfsURI *folder_uri) G_GNUC_MALLOC;
 
 G_END_DECLS;
 
diff --git a/thunar-vfs/thunar-vfs-transfer-job.c b/thunar-vfs/thunar-vfs-transfer-job.c
index 84acb7284..a21869147 100644
--- a/thunar-vfs/thunar-vfs-transfer-job.c
+++ b/thunar-vfs/thunar-vfs-transfer-job.c
@@ -54,6 +54,7 @@
 #include <thunar-vfs/thunar-vfs-sysdep.h>
 #include <thunar-vfs/thunar-vfs-thumb.h>
 #include <thunar-vfs/thunar-vfs-transfer-job.h>
+#include <thunar-vfs/thunar-vfs-alias.h>
 
 #if GLIB_CHECK_VERSION(2,6,0)
 #include <glib/gstdio.h>
@@ -74,10 +75,9 @@ typedef struct _ThunarVfsTransferItem ThunarVfsTransferItem;
 
 
 
-static void     thunar_vfs_transfer_job_register_type   (GType                  *type);
 static void     thunar_vfs_transfer_job_class_init      (ThunarVfsJobClass      *klass);
 static void     thunar_vfs_transfer_job_init            (ThunarVfsTransferJob   *transfer_job);
-static void     thunar_vfs_transfer_job_finalize        (ExoObject              *object);
+static void     thunar_vfs_transfer_job_finalize        (GObject                *object);
 static void     thunar_vfs_transfer_job_execute         (ThunarVfsJob           *job);
 static gboolean thunar_vfs_transfer_job_skip            (ThunarVfsTransferJob   *job,
                                                          const gchar            *format,
@@ -105,6 +105,11 @@ static void     thunar_vfs_transfer_item_copy_symlink   (ThunarVfsTransferItem
 
 
 
+struct _ThunarVfsTransferJobClass
+{
+  ThunarVfsInteractiveJobClass __parent__;
+};
+
 struct _ThunarVfsTransferJob
 {
   ThunarVfsInteractiveJob __parent__;
@@ -151,7 +156,7 @@ struct _ThunarVfsTransferItem
 
 
 
-static ExoObjectClass *thunar_vfs_transfer_job_parent_class;
+static GObjectClass *thunar_vfs_transfer_job_parent_class;
 
 
 
@@ -159,48 +164,42 @@ GType
 thunar_vfs_transfer_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
-  static GOnce once = G_ONCE_INIT;
 
-  /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_transfer_job_register_type, &type);
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarVfsTransferJobClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunar_vfs_transfer_job_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsTransferJob),
+        0,
+        (GInstanceInitFunc) thunar_vfs_transfer_job_init,
+        NULL,
+      };
+
+      type = g_type_register_static (THUNAR_VFS_TYPE_INTERACTIVE_JOB,
+                                     "ThunarVfsTransferJob", &info, 0);
+    }
 
   return type;
 }
 
 
 
-static void
-thunar_vfs_transfer_job_register_type (GType *type)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (ThunarVfsInteractiveJobClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) thunar_vfs_transfer_job_class_init,
-    NULL,
-    NULL,
-    sizeof (ThunarVfsTransferJob),
-    0,
-    (GInstanceInitFunc) thunar_vfs_transfer_job_init,
-    NULL,
-  };
-
-  *type = g_type_register_static (THUNAR_VFS_TYPE_INTERACTIVE_JOB,
-                                  "ThunarVfsTransferJob", &info, 0);
-}
-
-
-
 static void
 thunar_vfs_transfer_job_class_init (ThunarVfsJobClass *klass)
 {
-  ExoObjectClass *exoobject_class;
+  GObjectClass *gobject_class;
 
+  /* determine the parent class */
   thunar_vfs_transfer_job_parent_class = g_type_class_peek_parent (klass);
 
-  exoobject_class = EXO_OBJECT_CLASS (klass);
-  exoobject_class->finalize = thunar_vfs_transfer_job_finalize;
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_transfer_job_finalize;
 
   klass->execute = thunar_vfs_transfer_job_execute;
 }
@@ -225,7 +224,7 @@ thunar_vfs_transfer_job_init (ThunarVfsTransferJob *transfer_job)
 
 
 static void
-thunar_vfs_transfer_job_finalize (ExoObject *object)
+thunar_vfs_transfer_job_finalize (GObject *object)
 {
   ThunarVfsTransferJob *transfer_job = THUNAR_VFS_TRANSFER_JOB (object);
 
@@ -235,7 +234,7 @@ thunar_vfs_transfer_job_finalize (ExoObject *object)
   g_string_chunk_free (transfer_job->string_chunk);
 
   /* call the parents finalize method */
-  (*EXO_OBJECT_CLASS (thunar_vfs_transfer_job_parent_class)->finalize) (object);
+  (*G_OBJECT_CLASS (thunar_vfs_transfer_job_parent_class)->finalize) (object);
 }
 
 
@@ -830,7 +829,7 @@ thunar_vfs_transfer_job_new (GList        *source_uri_list,
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   /* allocate the job instance */
-  job = exo_object_new (THUNAR_VFS_TYPE_TRANSFER_JOB);
+  job = g_object_new (THUNAR_VFS_TYPE_TRANSFER_JOB, NULL);
   job->move = move;
 
   /* process the source uris */
diff --git a/thunar-vfs/thunar-vfs-transfer-job.h b/thunar-vfs/thunar-vfs-transfer-job.h
index f2fb39941..4ecb66c4b 100644
--- a/thunar-vfs/thunar-vfs-transfer-job.h
+++ b/thunar-vfs/thunar-vfs-transfer-job.h
@@ -22,21 +22,26 @@
 #define __THUNAR_VFS_TRANSFER_JOB_H__
 
 #include <thunar-vfs/thunar-vfs-interactive-job.h>
+#include <thunar-vfs/thunar-vfs-uri.h>
 
 G_BEGIN_DECLS;
 
-typedef struct _ThunarVfsTransferJob ThunarVfsTransferJob;
+typedef struct _ThunarVfsTransferJobClass ThunarVfsTransferJobClass;
+typedef struct _ThunarVfsTransferJob      ThunarVfsTransferJob;
 
-#define THUNAR_VFS_TYPE_TRANSFER_JOB    (thunar_vfs_transfer_job_get_type ())
-#define THUNAR_VFS_TRANSFER_JOB(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJob))
-#define THUNAR_VFS_IS_TRANSFER_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB))
+#define THUNAR_VFS_TYPE_TRANSFER_JOB            (thunar_vfs_transfer_job_get_type ())
+#define THUNAR_VFS_TRANSFER_JOB(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJob))
+#define THUNAR_VFS_TRANSFER_JOB_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJobClass))
+#define THUNAR_VFS_IS_TRANSFER_JOB(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB))
+#define THUNAR_VFS_IS_TRANSFER_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_TRANSFER_JOB))
+#define THUNAR_VFS_TRANSFER_JOB_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_TRANSFER_JOB, ThunarVfsTransferJobClass))
 
 GType         thunar_vfs_transfer_job_get_type (void) G_GNUC_CONST;
 
 ThunarVfsJob *thunar_vfs_transfer_job_new      (GList        *source_uri_list,
                                                 ThunarVfsURI *target_uri,
                                                 gboolean      move,
-                                                GError      **error);
+                                                GError      **error) G_GNUC_MALLOC;
 
 G_END_DECLS;
 
diff --git a/thunar-vfs/thunar-vfs-unlink-job.c b/thunar-vfs/thunar-vfs-unlink-job.c
index f7deab306..81f8a0921 100644
--- a/thunar-vfs/thunar-vfs-unlink-job.c
+++ b/thunar-vfs/thunar-vfs-unlink-job.c
@@ -47,6 +47,7 @@
 #include <thunar-vfs/thunar-vfs-thumb.h>
 #include <thunar-vfs/thunar-vfs-trash.h>
 #include <thunar-vfs/thunar-vfs-unlink-job.h>
+#include <thunar-vfs/thunar-vfs-alias.h>
 
 #if GLIB_CHECK_VERSION(2,6,0)
 #include <glib/gstdio.h>
@@ -61,21 +62,25 @@ typedef struct _ThunarVfsUnlinkItem ThunarVfsUnlinkItem;
 
 
 
-static void thunar_vfs_unlink_job_register_type (GType               *type);
-static void thunar_vfs_unlink_job_class_init    (ThunarVfsJobClass   *klass);
-static void thunar_vfs_unlink_job_init          (ThunarVfsUnlinkJob  *unlink_job);
-static void thunar_vfs_unlink_job_finalize      (ExoObject           *object);
-static void thunar_vfs_unlink_job_execute       (ThunarVfsJob        *job);
-static void thunar_vfs_unlink_base_new          (ThunarVfsUnlinkJob  *unlink_job,
-                                                 const gchar         *path,
-                                                 const gchar         *trash_info);
-static void thunar_vfs_unlink_base_collect      (ThunarVfsUnlinkBase *base);
-static void thunar_vfs_unlink_base_remove       (ThunarVfsUnlinkBase *base);
-static void thunar_vfs_unlink_item_collect      (ThunarVfsUnlinkItem *item);
-static void thunar_vfs_unlink_item_remove       (ThunarVfsUnlinkItem *item);
+static void thunar_vfs_unlink_job_class_init (ThunarVfsJobClass   *klass);
+static void thunar_vfs_unlink_job_init       (ThunarVfsUnlinkJob  *unlink_job);
+static void thunar_vfs_unlink_job_finalize   (GObject             *object);
+static void thunar_vfs_unlink_job_execute    (ThunarVfsJob        *job);
+static void thunar_vfs_unlink_base_new       (ThunarVfsUnlinkJob  *unlink_job,
+                                              const gchar         *path,
+                                              const gchar         *trash_info);
+static void thunar_vfs_unlink_base_collect   (ThunarVfsUnlinkBase *base);
+static void thunar_vfs_unlink_base_remove    (ThunarVfsUnlinkBase *base);
+static void thunar_vfs_unlink_item_collect   (ThunarVfsUnlinkItem *item);
+static void thunar_vfs_unlink_item_remove    (ThunarVfsUnlinkItem *item);
 
 
 
+struct _ThunarVfsUnlinkJobClass
+{
+  ThunarVfsInteractiveJobClass __parent__;
+};
+
 struct _ThunarVfsUnlinkJob
 {
   ThunarVfsInteractiveJob __parent__;
@@ -112,7 +117,7 @@ struct _ThunarVfsUnlinkItem
 
 
 
-static ExoObjectClass *thunar_vfs_unlink_job_parent_class;
+static GObjectClass *thunar_vfs_unlink_job_parent_class;
 
 
 
@@ -120,48 +125,42 @@ GType
 thunar_vfs_unlink_job_get_type (void)
 {
   static GType type = G_TYPE_INVALID;
-  static GOnce once = G_ONCE_INIT;
 
-  /* thread-safe type registration */
-  g_once (&once, (GThreadFunc) thunar_vfs_unlink_job_register_type, &type);
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ThunarVfsUnlinkJobClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) thunar_vfs_unlink_job_class_init,
+        NULL,
+        NULL,
+        sizeof (ThunarVfsUnlinkJob),
+        0,
+        (GInstanceInitFunc) thunar_vfs_unlink_job_init,
+        NULL,
+      };
+
+      type = g_type_register_static (THUNAR_VFS_TYPE_INTERACTIVE_JOB,
+                                     "ThunarVfsUnlinkJob", &info, 0);
+    }
 
   return type;
 }
 
 
 
-static void
-thunar_vfs_unlink_job_register_type (GType *type)
-{
-  static const GTypeInfo info =
-  {
-    sizeof (ThunarVfsInteractiveJobClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) thunar_vfs_unlink_job_class_init,
-    NULL,
-    NULL,
-    sizeof (ThunarVfsUnlinkJob),
-    0,
-    (GInstanceInitFunc) thunar_vfs_unlink_job_init,
-    NULL,
-  };
-
-  *type = g_type_register_static (THUNAR_VFS_TYPE_INTERACTIVE_JOB,
-                                  "ThunarVfsUnlinkJob", &info, 0);
-}
-
-
-
 static void
 thunar_vfs_unlink_job_class_init (ThunarVfsJobClass *klass)
 {
-  ExoObjectClass *exoobject_class;
+  GObjectClass *gobject_class;
 
+  /* determine the parent class */
   thunar_vfs_unlink_job_parent_class = g_type_class_peek_parent (klass);
 
-  exoobject_class = EXO_OBJECT_CLASS (klass);
-  exoobject_class->finalize = thunar_vfs_unlink_job_finalize;
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = thunar_vfs_unlink_job_finalize;
 
   klass->execute = thunar_vfs_unlink_job_execute;
 }
@@ -185,7 +184,7 @@ thunar_vfs_unlink_job_init (ThunarVfsUnlinkJob *unlink_job)
 
 
 static void
-thunar_vfs_unlink_job_finalize (ExoObject *object)
+thunar_vfs_unlink_job_finalize (GObject *object)
 {
   ThunarVfsUnlinkJob *unlink_job = THUNAR_VFS_UNLINK_JOB (object);
 
@@ -195,7 +194,7 @@ thunar_vfs_unlink_job_finalize (ExoObject *object)
   g_string_chunk_free (unlink_job->string_chunk);
 
   /* call the parents finalize method */
-  (*EXO_OBJECT_CLASS (thunar_vfs_unlink_job_parent_class)->finalize) (object);
+  (*G_OBJECT_CLASS (thunar_vfs_unlink_job_parent_class)->finalize) (object);
 }
 
 
@@ -427,7 +426,7 @@ thunar_vfs_unlink_job_new (GList   *uris,
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   /* allocate the job instance */
-  job = exo_object_new (THUNAR_VFS_TYPE_UNLINK_JOB);
+  job = g_object_new (THUNAR_VFS_TYPE_UNLINK_JOB, NULL);
 
   /* process the uris */
   for (; uris != NULL; uris = uris->next)
diff --git a/thunar-vfs/thunar-vfs-unlink-job.h b/thunar-vfs/thunar-vfs-unlink-job.h
index 3f6623357..4b6d11de6 100644
--- a/thunar-vfs/thunar-vfs-unlink-job.h
+++ b/thunar-vfs/thunar-vfs-unlink-job.h
@@ -22,19 +22,24 @@
 #define __THUNAR_VFS_UNLINK_JOB_H__
 
 #include <thunar-vfs/thunar-vfs-interactive-job.h>
+#include <thunar-vfs/thunar-vfs-uri.h>
 
 G_BEGIN_DECLS;
 
-typedef struct _ThunarVfsUnlinkJob ThunarVfsUnlinkJob;
+typedef struct _ThunarVfsUnlinkJobClass ThunarVfsUnlinkJobClass;
+typedef struct _ThunarVfsUnlinkJob      ThunarVfsUnlinkJob;
 
-#define THUNAR_VFS_TYPE_UNLINK_JOB    (thunar_vfs_unlink_job_get_type ())
-#define THUNAR_VFS_UNLINK_JOB(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_UNLINK_JOB, ThunarVfsUnlinkJob))
-#define THUNAR_VFS_IS_UNLINK_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_UNLINK_JOB))
+#define THUNAR_VFS_TYPE_UNLINK_JOB            (thunar_vfs_unlink_job_get_type ())
+#define THUNAR_VFS_UNLINK_JOB(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_VFS_TYPE_UNLINK_JOB, ThunarVfsUnlinkJob))
+#define THUNAR_VFS_UNLINK_JOB_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_VFS_TYPE_UNLINK_JOB, ThunarVfsUnlinkJobClass))
+#define THUNAR_VFS_IS_UNLINK_JOB(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_VFS_TYPE_UNLINK_JOB))
+#define THUNAR_VFS_IS_UNLINK_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_VFS_TYPE_UNLINK_JOB))
+#define THUNAR_VFS_UNLINK_JOB_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_VFS_TYPE_UNLINK_JOB, ThunarVfsUnlinkJobClass))
 
 GType         thunar_vfs_unlink_job_get_type  (void) G_GNUC_CONST;
 
 ThunarVfsJob *thunar_vfs_unlink_job_new       (GList   *uris,
-                                               GError **error);
+                                               GError **error) G_GNUC_MALLOC;
 
 G_END_DECLS;
 
-- 
GitLab