diff --git a/ChangeLog b/ChangeLog
index 52f9ec9aa1b0b258046fa68c163cfa660a4348ee..c0dd2655e4109604648f0b6ea9ff9934489a2a54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2006-02-15	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-unlink-job.c(thunar_vfs_unlink_job_execute):
+	  Ignore ENOENT errors returned by thunar_vfs_scandir() as well, to
+	  fix the problem with not being able to delete broken links on
+	  Linux.
+	* thunar/thunar-application.c: Generate unique roles for the Thunar
+	  toplevel windows in preparation of session management support.
+	* thunar/thunar-dbus-service-infos.xml, thunar/thunar-dbus-service.c:
+	  Add Terminate() method to the org.xfce.Thunar interface, which allows
+	  to properly shutdown a daemon instance.
+	* thunar/main.c, thunar/thunar-dbus-client.{c,h}: Add -q/--quit command
+	  line option, which terminates a running daemon instance. Also cleanup
+	  the --daemon handling.
+
 2006-02-15	Benedikt Meurer <benny@xfce.org>
 
 	* FAQ, thunar/thunar-icon-view.c: Add mouse gesture for "Reload" as
diff --git a/thunar-vfs/thunar-vfs-unlink-job.c b/thunar-vfs/thunar-vfs-unlink-job.c
index 9c5ad5af392b9f01c542cbca4749245bb27735c8..066481e8cd321da4e30a126daac411d56ea768a8 100644
--- a/thunar-vfs/thunar-vfs-unlink-job.c
+++ b/thunar-vfs/thunar-vfs-unlink-job.c
@@ -168,8 +168,8 @@ thunar_vfs_unlink_job_execute (ThunarVfsJob *job)
       paths = thunar_vfs_scandir (lp->data, &job->cancelled, THUNAR_VFS_SCANDIR_RECURSIVE, NULL, &error);
       if (G_UNLIKELY (error != NULL))
         {
-          /* we can safely ignore ENOTDIR errors here */
-          if (error->domain != G_FILE_ERROR || error->code != G_FILE_ERROR_NOTDIR)
+          /* we can safely ignore ENOENT/ENOTDIR errors here */
+          if (error->domain != G_FILE_ERROR || (error->code != G_FILE_ERROR_NOENT && error->code != G_FILE_ERROR_NOTDIR))
             {
               /* inform the user about the problem and abort the job */
               thunar_vfs_job_error (job, error);
diff --git a/thunar/main.c b/thunar/main.c
index 3358e1b83e46cda474e1a0c54325c1a2e1bee18d..e80e0189a6919ae1d01c5c3c490e9bea0128a420 100644
--- a/thunar/main.c
+++ b/thunar/main.c
@@ -39,12 +39,22 @@
 
 /* --- globals --- */
 static gboolean opt_daemon = FALSE;
+static gboolean opt_quit = FALSE;
 
 
 /* --- command line options --- */
 static GOptionEntry option_entries[] =
 {
+#ifdef HAVE_DBUS
   { "daemon", 0, 0, G_OPTION_ARG_NONE, &opt_daemon, N_ ("Run in daemon mode"), NULL, },
+#else
+  { "daemon", 0, 0, G_OPTION_ARG_NONE, &opt_daemon, N_ ("Run in daemon mode (not supported)"), NULL, },
+#endif
+#ifdef HAVE_DBUS
+  { "quit", 'q', 0, G_OPTION_ARG_NONE, &opt_quit, N_ ("Quit a running Thunar instance"), NULL, },
+#else
+  { "quit", 'q', 0, G_OPTION_ARG_NONE, &opt_quit, N_ ("Quit a running Thunar instance (not supported)"), NULL, },
+#endif
   { NULL, },
 };
 
@@ -58,7 +68,7 @@ main (int argc, char **argv)
 #endif
   ThunarApplication *application;
   GError            *error = NULL;
-  gchar             *working_directory = NULL;
+  gchar             *working_directory;
   gchar            **filenames = NULL;
 
   /* setup translation domain */
@@ -93,42 +103,55 @@ main (int argc, char **argv)
       return EXIT_FAILURE;
     }
 
-  /* do not try to connect to a running instance, or
-   * open any windows if run as daemon.
-   */
-  if (G_LIKELY (!opt_daemon))
+#ifdef HAVE_DBUS
+  /* check if we should terminate a running Thunar instance */
+  if (G_UNLIKELY (opt_quit))
     {
-      /* determine the current working directory */
-      working_directory = g_get_current_dir ();
-
-      /* check if atleast one filename was specified */
-      if (G_LIKELY (argc > 1))
+      /* try to terminate whatever is running */
+      if (!thunar_dbus_client_terminate (&error))
         {
-          /* use the specified filenames */
-          filenames = g_strdupv (argv + 1);
-        }
-      else
-        {
-          /* use the current working directory */
-          filenames = g_new (gchar *, 2);
-          filenames[0] = g_strdup (working_directory);
-          filenames[1] = NULL;
+          g_fprintf (stderr, "Thunar: Failed to terminate running instance: %s\n", error->message);
+          g_error_free (error);
+          return EXIT_FAILURE;
         }
 
+      return EXIT_SUCCESS;
+    }
+#endif
+
+  /* determine the current working directory */
+  working_directory = g_get_current_dir ();
+
+  /* check if atleast one filename was specified, else
+   * fall back to opening the current working directory
+   * if daemon mode is not requested.
+   */
+  if (G_LIKELY (argc > 1))
+    {
+      /* use the specified filenames */
+      filenames = g_strdupv (argv + 1);
+    }
+  else if (!opt_daemon)
+    {
+      /* use the current working directory */
+      filenames = g_new (gchar *, 2);
+      filenames[0] = g_strdup (working_directory);
+      filenames[1] = NULL;
+    }
+
 #ifdef HAVE_DBUS
-      /* try to reuse an existing instance */
-      if (thunar_dbus_client_launch_files (working_directory, filenames, NULL, NULL))
-        {
-          /* stop any running startup notification */
-          gdk_notify_startup_complete ();
+  /* try to reuse an existing instance (if any files were specified) */
+  if (filenames != NULL && thunar_dbus_client_launch_files (working_directory, filenames, NULL, NULL))
+    {
+      /* stop any running startup notification */
+      gdk_notify_startup_complete ();
 
-          /* that worked, let's get outa here */
-          g_free (working_directory);
-          g_strfreev (filenames);
-          return EXIT_SUCCESS;
-        }
-#endif
+      /* that worked, let's get outa here */
+      g_free (working_directory);
+      g_strfreev (filenames);
+      return EXIT_SUCCESS;
     }
+#endif
 
   /* initialize the ThunarVFS library */
   thunar_vfs_init ();
@@ -139,32 +162,28 @@ main (int argc, char **argv)
   /* acquire a reference on the global application */
   application = thunar_application_get ();
 
+#ifdef HAVE_DBUS
+  /* setup daemon mode if requested and supported */
+  thunar_application_set_daemon (application, opt_daemon);
+#endif
+
   /* use the Thunar icon as default for new windows */
   gtk_window_set_default_icon_name ("Thunar");
 
-  /* if not in daemon mode, try to process the filenames here */
-  if (G_LIKELY (!opt_daemon))
+  /* try to process the given filenames (if any files were specified) */
+  if (filenames != NULL && !thunar_application_process_filenames (application, working_directory, filenames, NULL, &error))
     {
-      /* try to process the given filenames */
-      if (!thunar_application_process_filenames (application, working_directory, filenames, NULL, &error))
-        {
-          g_fprintf (stderr, "Thunar: %s\n", error->message);
-          g_object_unref (G_OBJECT (application));
-          thunar_vfs_shutdown ();
-          g_error_free (error);
-          return EXIT_FAILURE;
-        }
-
-      /* release working directory and filenames */
-      g_free (working_directory);
-      g_strfreev (filenames);
-    }
-  else
-    {
-      /* run in daemon mode, since we were started by the message bus */
-      thunar_application_set_daemon (application, TRUE);
+      g_fprintf (stderr, "Thunar: %s\n", error->message);
+      g_object_unref (G_OBJECT (application));
+      thunar_vfs_shutdown ();
+      g_error_free (error);
+      return EXIT_FAILURE;
     }
 
+  /* release working directory and filenames */
+  g_free (working_directory);
+  g_strfreev (filenames);
+
   /* do not enter the main loop, unless we have atleast one window or we are in daemon mode */
   if (thunar_application_has_windows (application) || thunar_application_get_daemon (application))
     {
diff --git a/thunar/thunar-application.c b/thunar/thunar-application.c
index 6fd6c5980348ce68308fe90f5b22df428c4362d7..8c7a2722a40070d0cb354408ecf5b3d3b6e812e8 100644
--- a/thunar/thunar-application.c
+++ b/thunar/thunar-application.c
@@ -22,6 +22,10 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
 #include <thunar/thunar-application.h>
 #include <thunar/thunar-dialogs.h>
 #include <thunar/thunar-gobject-extensions.h>
@@ -46,37 +50,41 @@ enum
 
 
 
-static void     thunar_application_class_init           (ThunarApplicationClass *klass);
-static void     thunar_application_init                 (ThunarApplication      *application);
-static void     thunar_application_finalize             (GObject                *object);
-static void     thunar_application_get_property         (GObject                *object,
-                                                         guint                   prop_id,
-                                                         GValue                 *value,
-                                                         GParamSpec             *pspec);
-static void     thunar_application_set_property         (GObject                *object,
-                                                         guint                   prop_id,
-                                                         const GValue           *value,
-                                                         GParamSpec             *pspec);
-static void     thunar_application_collect_and_launch   (ThunarApplication      *application,
-                                                         GtkWidget              *widget,
-                                                         const gchar            *icon_name,
-                                                         const gchar            *title,
-                                                         Launcher                launcher,
-                                                         GList                  *source_path_list,
-                                                         ThunarVfsPath          *target_path,
-                                                         GClosure               *new_files_closure);
-static void     thunar_application_launch               (ThunarApplication      *application,
-                                                         GtkWidget              *widget,
-                                                         const gchar            *icon_name,
-                                                         const gchar            *title,
-                                                         Launcher                launcher,
-                                                         GList                  *source_path_list,
-                                                         GList                  *target_path_list,
-                                                         GClosure               *new_files_closure);
-static void     thunar_application_window_destroyed     (GtkWidget              *window,
-                                                         ThunarApplication      *application);
-static gboolean thunar_application_show_dialogs         (gpointer                user_data);
-static void     thunar_application_show_dialogs_destroy (gpointer                user_data);
+static void     thunar_application_class_init             (ThunarApplicationClass *klass);
+static void     thunar_application_init                   (ThunarApplication      *application);
+static void     thunar_application_finalize               (GObject                *object);
+static void     thunar_application_get_property           (GObject                *object,
+                                                           guint                   prop_id,
+                                                           GValue                 *value,
+                                                           GParamSpec             *pspec);
+static void     thunar_application_set_property           (GObject                *object,
+                                                           guint                   prop_id,
+                                                           const GValue           *value,
+                                                           GParamSpec             *pspec);
+static void     thunar_application_collect_and_launch     (ThunarApplication      *application,
+                                                           GtkWidget              *widget,
+                                                           const gchar            *icon_name,
+                                                           const gchar            *title,
+                                                           Launcher                launcher,
+                                                           GList                  *source_path_list,
+                                                           ThunarVfsPath          *target_path,
+                                                           GClosure               *new_files_closure);
+static void     thunar_application_launch                 (ThunarApplication      *application,
+                                                           GtkWidget              *widget,
+                                                           const gchar            *icon_name,
+                                                           const gchar            *title,
+                                                           Launcher                launcher,
+                                                           GList                  *source_path_list,
+                                                           GList                  *target_path_list,
+                                                           GClosure               *new_files_closure);
+static void     thunar_application_open_window_with_role  (ThunarApplication      *application,
+                                                           const gchar            *role,
+                                                           ThunarFile             *directory,
+                                                           GdkScreen              *screen);
+static void     thunar_application_window_destroyed       (GtkWidget              *window,
+                                                           ThunarApplication      *application);
+static gboolean thunar_application_show_dialogs           (gpointer                user_data);
+static void     thunar_application_show_dialogs_destroy   (gpointer                user_data);
 
 
 
@@ -345,6 +353,35 @@ thunar_application_launch (ThunarApplication *application,
 
 
 
+static void
+thunar_application_open_window_with_role (ThunarApplication *application,
+                                          const gchar       *role,
+                                          ThunarFile        *directory,
+                                          GdkScreen         *screen)
+{
+  GtkWidget *window;
+
+  if (G_UNLIKELY (screen == NULL))
+    screen = gdk_screen_get_default ();
+
+  /* allocate the window */
+  window = g_object_new (THUNAR_TYPE_WINDOW,
+                         "role", role,
+                         "screen", screen,
+                         NULL);
+
+  /* hook up the window */
+  thunar_application_take_window (application, GTK_WINDOW (window));
+
+  /* show the new window */
+  gtk_widget_show (window);
+
+  /* change the directory */
+  thunar_window_set_current_directory (THUNAR_WINDOW (window), directory);
+}
+
+
+
 static void
 thunar_application_window_destroyed (GtkWidget         *window,
                                      ThunarApplication *application)
@@ -545,28 +582,16 @@ thunar_application_open_window (ThunarApplication *application,
                                 ThunarFile        *directory,
                                 GdkScreen         *screen)
 {
-  GtkWidget *window;
+  gchar *role;
 
   g_return_if_fail (THUNAR_IS_APPLICATION (application));
   g_return_if_fail (THUNAR_IS_FILE (directory));
   g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
 
-  if (G_UNLIKELY (screen == NULL))
-    screen = gdk_screen_get_default ();
-
-  /* allocate the window */
-  window = g_object_new (THUNAR_TYPE_WINDOW,
-                         "screen", screen,
-                         NULL);
-
-  /* hook up the window */
-  thunar_application_take_window (application, GTK_WINDOW (window));
-
-  /* show the new window */
-  gtk_widget_show (window);
-
-  /* change the directory */
-  thunar_window_set_current_directory (THUNAR_WINDOW (window), directory);
+  /* generate a unique role for the new window (for session management) */
+  role = g_strdup_printf ("Thunar-%u-%u", (guint) time (NULL), (guint) g_random_int ());
+  thunar_application_open_window_with_role (application, role, directory, screen);
+  g_free (role);
 }
 
 
diff --git a/thunar/thunar-dbus-client.c b/thunar/thunar-dbus-client.c
index 0f5586e3f54664fb26827e50791a56711df4d3a4..3df2107b7d3315527f2e0fb5843bc605a6202fac 100644
--- a/thunar/thunar-dbus-client.c
+++ b/thunar/thunar-dbus-client.c
@@ -121,3 +121,75 @@ thunar_dbus_client_launch_files (const gchar *working_directory,
   return TRUE;
 }
 
+
+
+/**
+ * thunar_dbus_client_terminate:
+ * @error : Return location for errors or %NULL.
+ *
+ * Tells a running Thunar instance, connected to the D-BUS
+ * session bus, to terminate immediately.
+ *
+ * Return value: %TRUE if any instance was terminated, else
+ *               %FALSE and @error is set.
+ **/
+gboolean
+thunar_dbus_client_terminate (GError **error)
+{
+  DBusConnection *connection;
+  DBusMessage    *message;
+  DBusMessage    *result;
+  DBusError       derror;
+
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* initialize the DBusError struct */
+  dbus_error_init (&derror);
+
+  /* try to connect to the session bus */
+  connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+  if (G_UNLIKELY (connection == NULL))
+    {
+      dbus_set_g_error (error, &derror);
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* generate the LaunchFiles() method (disable activation!) */
+  message = dbus_message_new_method_call ("org.xfce.Thunar", "/org/xfce/FileManager", "org.xfce.Thunar", "Terminate");
+  dbus_message_set_auto_start (message, FALSE);
+
+  /* send the message and release our references on connection and message */
+  result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &derror);
+  dbus_message_unref (message);
+
+  /* check if no reply was received */
+  if (G_UNLIKELY (result == NULL))
+    {
+      /* check if there was nothing to terminate */
+      if (dbus_error_has_name (&derror, DBUS_ERROR_NAME_HAS_NO_OWNER))
+        {
+          dbus_error_free (&derror);
+          return TRUE;
+        }
+
+      /* Looks like there was a real error */
+      dbus_set_g_error (error, &derror);
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* but maybe we received an error */
+  if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      dbus_set_error_from_message (&derror, result);
+      dbus_set_g_error (error, &derror);
+      dbus_message_unref (result);
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* let's asume that it worked */
+  dbus_message_unref (result);
+  return TRUE;
+}
diff --git a/thunar/thunar-dbus-client.h b/thunar/thunar-dbus-client.h
index e053ab3c9f41fa70b2cd53ae98078a9ec156a00c..449a3c8046a0f430cee002135ff4f66aaf22331d 100644
--- a/thunar/thunar-dbus-client.h
+++ b/thunar/thunar-dbus-client.h
@@ -29,6 +29,8 @@ gboolean thunar_dbus_client_launch_files (const gchar *working_directory,
                                           GdkScreen   *screen,
                                           GError     **error);
 
+gboolean thunar_dbus_client_terminate    (GError     **error);
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_DBUS_CLIENT_H__ */
diff --git a/thunar/thunar-dbus-service-infos.xml b/thunar/thunar-dbus-service-infos.xml
index 64cd668c8d4f47a3da149c5c91a07c48f178710a..4959fc1ff69a6ae8431ebeb9a41da33f3cae2e41 100644
--- a/thunar/thunar-dbus-service-infos.xml
+++ b/thunar/thunar-dbus-service-infos.xml
@@ -110,5 +110,15 @@
       <arg direction="in" name="filenames" type="as" />
       <arg direction="in" name="display" type="s" />
     </method>
+
+    <!--
+      Terminate () : VOID
+
+      Tells a running Thunar instance to terminate immediately.
+    -->
+    <method name="Terminate">
+    </method>
   </interface>
 </node>
+
+<!-- vi:set ts=2 sw=2 et ai: -->
diff --git a/thunar/thunar-dbus-service.c b/thunar/thunar-dbus-service.c
index c9d04d74c70a7b90f379043afbadf435d94ccffd..46616d596c4622a77a3d1ffbc0134334551e559a 100644
--- a/thunar/thunar-dbus-service.c
+++ b/thunar/thunar-dbus-service.c
@@ -65,6 +65,8 @@ static gboolean thunar_dbus_service_launch_files                (ThunarDBusServi
                                                                  gchar                 **filenames,
                                                                  const gchar            *display,
                                                                  GError                **error);
+static gboolean thunar_dbus_service_terminate                   (ThunarDBusService      *dbus_service,
+                                                                 GError                **error);
 
 
 
@@ -380,4 +382,17 @@ thunar_dbus_service_launch_files (ThunarDBusService *dbus_service,
 
 
 
+static gboolean
+thunar_dbus_service_terminate (ThunarDBusService *dbus_service,
+                               GError           **error)
+{
+  /* leave the Gtk main loop as soon as possible */
+  gtk_main_quit ();
+
+  /* we cannot fail */
+  return TRUE;
+}
+
+
+
 #include <thunar/thunar-dbus-service-infos.h>