Commit c70f4313 authored by Jannis Pohlmann's avatar Jannis Pohlmann
Browse files

Change CWD before spawning applications in ThunarLauncher.

Before launching files with a GAppInfo, ThunarLauncher now changes the
current working directory of the Thunar process to its own current
directory, which usually also is the current directory of the window. It
remembers the original directory Thunar was launched from and resets the
CWD right after the files have been launched.

This is done transparently by adding a function
thunar_g_app_info_launch() that handles the CWD state internally. It
calls another new function, thunar_util_change_working_directory() that
is based on getcwd/_getcwd (the latter being used on Windows) and
chdir().
parent ad4d0cf0
...@@ -119,8 +119,8 @@ dnl *** Check for standard headers *** ...@@ -119,8 +119,8 @@ dnl *** Check for standard headers ***
dnl ********************************** dnl **********************************
AC_CHECK_HEADERS([ctype.h errno.h fcntl.h grp.h limits.h locale.h memory.h \ AC_CHECK_HEADERS([ctype.h errno.h fcntl.h grp.h limits.h locale.h memory.h \
paths.h pwd.h sched.h signal.h stdarg.h stdlib.h string.h \ paths.h pwd.h sched.h signal.h stdarg.h stdlib.h string.h \
sys/mman.h sys/stat.h sys/time.h sys/types.h sys/uio.h \ sys/mman.h sys/param.h sys/stat.h sys/time.h sys/types.h \
sys/wait.h time.h]) sys/uio.h sys/wait.h time.h])
dnl ************************************ dnl ************************************
dnl *** Check for standard functions *** dnl *** Check for standard functions ***
......
...@@ -27,8 +27,10 @@ ...@@ -27,8 +27,10 @@
#include <exo/exo.h> #include <exo/exo.h>
#include <libxfce4util/libxfce4util.h> #include <libxfce4util/libxfce4util.h>
#include <thunar/thunar-file.h>
#include <thunar/thunar-gio-extensions.h> #include <thunar/thunar-gio-extensions.h>
#include <thunar/thunar-private.h> #include <thunar/thunar-private.h>
#include <thunar/thunar-util.h>
...@@ -467,3 +469,56 @@ thunar_g_volume_is_present (GVolume *volume) ...@@ -467,3 +469,56 @@ thunar_g_volume_is_present (GVolume *volume)
return has_media; return has_media;
} }
gboolean
thunar_g_app_info_launch (GAppInfo *info,
GFile *working_directory,
GList *path_list,
GAppLaunchContext *context,
GError **error)
{
gboolean result = FALSE;
gchar *new_path = NULL;
gchar *old_path = NULL;
_thunar_return_val_if_fail (G_IS_APP_INFO (info), FALSE);
_thunar_return_val_if_fail (working_directory == NULL || G_IS_FILE (working_directory), FALSE);
_thunar_return_val_if_fail (path_list != NULL, FALSE);
_thunar_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), FALSE);
_thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* check if we want to set the working directory of the spawned app */
if (working_directory != NULL)
{
/* determine the working directory path */
new_path = g_file_get_path (working_directory);
if (new_path != NULL)
{
/* switch to the desired working directory, remember that of Thunar itself */
old_path = thunar_util_change_working_directory (new_path);
/* forget about the new working directory path */
g_free (new_path);
}
}
/* launch the paths with the specified app info */
result = g_app_info_launch (info, path_list, context, error);
/* check if we need to reset the working directory to the one Thunar was
* opened from */
if (old_path != NULL)
{
/* switch to Thunar's original working directory */
new_path = thunar_util_change_working_directory (old_path);
/* clean up */
g_free (new_path);
g_free (old_path);
}
return result;
}
...@@ -29,23 +29,23 @@ GFile *thunar_g_file_new_for_home (void); ...@@ -29,23 +29,23 @@ GFile *thunar_g_file_new_for_home (void);
GFile *thunar_g_file_new_for_root (void); GFile *thunar_g_file_new_for_root (void);
GFile *thunar_g_file_new_for_trash (void); GFile *thunar_g_file_new_for_trash (void);
GFile *thunar_g_file_new_for_desktop (void); GFile *thunar_g_file_new_for_desktop (void);
GFile *thunar_g_file_new_for_user_special_dir (GUserDirectory dir); GFile *thunar_g_file_new_for_user_special_dir (GUserDirectory dir);
gboolean thunar_g_file_is_root (GFile *file); gboolean thunar_g_file_is_root (GFile *file);
gboolean thunar_g_file_is_trashed (GFile *file); gboolean thunar_g_file_is_trashed (GFile *file);
gboolean thunar_g_file_is_desktop (GFile *file); gboolean thunar_g_file_is_desktop (GFile *file);
GKeyFile *thunar_g_file_query_key_file (GFile *file, GKeyFile *thunar_g_file_query_key_file (GFile *file,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gboolean thunar_g_file_write_key_file (GFile *file, gboolean thunar_g_file_write_key_file (GFile *file,
GKeyFile *key_file, GKeyFile *key_file,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gchar *thunar_g_file_get_location (GFile *file); gchar *thunar_g_file_get_location (GFile *file);
gboolean thunar_g_vfs_is_uri_scheme_supported (const gchar *scheme); gboolean thunar_g_vfs_is_uri_scheme_supported (const gchar *scheme);
/** /**
* THUNAR_TYPE_G_FILE_LIST: * THUNAR_TYPE_G_FILE_LIST:
...@@ -57,18 +57,24 @@ gboolean thunar_g_vfs_is_uri_scheme_supported (const gchar *scheme); ...@@ -57,18 +57,24 @@ gboolean thunar_g_vfs_is_uri_scheme_supported (const gchar *scheme);
GType thunar_g_file_list_get_type (void); GType thunar_g_file_list_get_type (void);
GList *thunar_g_file_list_new_from_string (const gchar *string); GList *thunar_g_file_list_new_from_string (const gchar *string);
gchar *thunar_g_file_list_to_string (GList *list); gchar *thunar_g_file_list_to_string (GList *list);
GList *thunar_g_file_list_append (GList *list, GList *thunar_g_file_list_append (GList *list,
GFile *file); GFile *file);
GList *thunar_g_file_list_prepend (GList *list, GList *thunar_g_file_list_prepend (GList *list,
GFile *file); GFile *file);
GList *thunar_g_file_list_copy (GList *list); GList *thunar_g_file_list_copy (GList *list);
void thunar_g_file_list_free (GList *list); void thunar_g_file_list_free (GList *list);
gboolean thunar_g_volume_is_removable (GVolume *volume);
gboolean thunar_g_volume_is_mounted (GVolume *volume);
gboolean thunar_g_volume_is_present (GVolume *volume);
gboolean thunar_g_volume_is_removable (GVolume *volume); gboolean thunar_g_app_info_launch (GAppInfo *info,
gboolean thunar_g_volume_is_mounted (GVolume *volume); GFile *working_directory,
gboolean thunar_g_volume_is_present (GVolume *volume); GList *path_list,
GAppLaunchContext *context,
GError **error);
G_END_DECLS G_END_DECLS
......
...@@ -605,6 +605,7 @@ thunar_launcher_open_paths (GAppInfo *app_info, ...@@ -605,6 +605,7 @@ thunar_launcher_open_paths (GAppInfo *app_info,
GdkAppLaunchContext *context; GdkAppLaunchContext *context;
GdkScreen *screen; GdkScreen *screen;
GError *error = NULL; GError *error = NULL;
GFile *working_directory = NULL;
gchar *message; gchar *message;
gchar *name; gchar *name;
guint n; guint n;
...@@ -616,8 +617,12 @@ thunar_launcher_open_paths (GAppInfo *app_info, ...@@ -616,8 +617,12 @@ thunar_launcher_open_paths (GAppInfo *app_info,
context = gdk_app_launch_context_new (); context = gdk_app_launch_context_new ();
gdk_app_launch_context_set_screen (context, screen); gdk_app_launch_context_set_screen (context, screen);
/* determine the working directory */
if (launcher->current_directory != NULL)
working_directory = thunar_file_get_file (launcher->current_directory);
/* try to execute the application with the given URIs */ /* try to execute the application with the given URIs */
if (!g_app_info_launch (app_info, path_list, G_APP_LAUNCH_CONTEXT (context), &error)) if (!thunar_g_app_info_launch (app_info, working_directory, path_list, G_APP_LAUNCH_CONTEXT (context), &error))
{ {
/* figure out the appropriate error message */ /* figure out the appropriate error message */
n = g_list_length (path_list); n = g_list_length (path_list);
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_MEMORY_H #ifdef HAVE_MEMORY_H
#include <memory.h> #include <memory.h>
...@@ -41,6 +44,14 @@ ...@@ -41,6 +44,14 @@
#ifdef HAVE_TIME_H #ifdef HAVE_TIME_H
#include <time.h> #include <time.h>
#endif #endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef G_PLATFORM_WIN32
#include <direct.h>
#include <glib/gwin32.h>
#endif
#include <thunar/thunar-private.h> #include <thunar/thunar-private.h>
#include <thunar/thunar-util.h> #include <thunar/thunar-util.h>
...@@ -352,3 +363,40 @@ thunar_util_time_from_rfc3339 (const gchar *date_string) ...@@ -352,3 +363,40 @@ thunar_util_time_from_rfc3339 (const gchar *date_string)
} }
gchar *
thunar_util_change_working_directory (const gchar *new_directory)
{
gchar *old_directory;
_thunar_return_val_if_fail (new_directory != NULL && *new_directory != '\0', NULL);
/* allocate a path buffer for the old working directory */
old_directory = g_malloc0 (sizeof (gchar) * MAXPATHLEN);
/* try to determine the current working directory */
#ifdef G_PLATFORM_WIN32
if (_getcwd (old_directory, MAXPATHLEN) == NULL)
#else
if (getcwd (old_directory, MAXPATHLEN) == NULL)
#endif
{
/* working directory couldn't be determined, reset the buffer */
g_free (old_directory);
old_directory = NULL;
}
/* try switching to the new working directory */
#ifdef G_PLATFORM_WIN32
if (_chdir (new_directory) != 0)
#else
if (chdir (new_directory) != 0)
#endif
{
/* switching failed, we don't need to return the old directory */
g_free (old_directory);
old_directory = NULL;
}
return old_directory;
}
...@@ -25,18 +25,20 @@ ...@@ -25,18 +25,20 @@
G_BEGIN_DECLS; G_BEGIN_DECLS;
gboolean thunar_util_looks_like_an_uri (const gchar *string) G_GNUC_WARN_UNUSED_RESULT; gboolean thunar_util_looks_like_an_uri (const gchar *string) G_GNUC_WARN_UNUSED_RESULT;
gchar *thunar_util_expand_filename (const gchar *filename, gchar *thunar_util_expand_filename (const gchar *filename,
GError **error); GError **error);
gchar *thunar_util_humanize_file_time (guint64 file_time, gchar *thunar_util_humanize_file_time (guint64 file_time,
ThunarDateStyle date_style) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; ThunarDateStyle date_style) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
GdkScreen *thunar_util_parse_parent (gpointer parent, GdkScreen *thunar_util_parse_parent (gpointer parent,
GtkWindow **window_return) G_GNUC_WARN_UNUSED_RESULT; GtkWindow **window_return) G_GNUC_WARN_UNUSED_RESULT;
time_t thunar_util_time_from_rfc3339 (const gchar *date_string) G_GNUC_WARN_UNUSED_RESULT; time_t thunar_util_time_from_rfc3339 (const gchar *date_string) G_GNUC_WARN_UNUSED_RESULT;
gchar *thunar_util_change_working_directory (const gchar *new_directory) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS; G_END_DECLS;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment