Updating branch refs/heads/master to 8990efaf5a89afa3a47b9358b57aa0ffad64eff0 (commit) from 90b3d9fe2b4224103e67397db40f85c244bd1b55 (commit)
commit 8990efaf5a89afa3a47b9358b57aa0ffad64eff0 Author: Nick Schermer <n...@xfce.org> Date: Sat Oct 17 18:23:52 2009 +0200 Use the spawn code from libxfce4ui. thunar/thunar-exec.c | 369 -------------------------------------------------- thunar/thunar-exec.h | 13 -- thunar/thunar-file.c | 5 +- 3 files changed, 3 insertions(+), 384 deletions(-) diff --git a/thunar/thunar-exec.c b/thunar/thunar-exec.c index e4a2358..06ceb82 100644 --- a/thunar/thunar-exec.c +++ b/thunar/thunar-exec.c @@ -24,42 +24,12 @@ #include <config.h> #endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_MEMORY_H -#include <memory.h> -#endif -#ifdef HAVE_STDARG_H -#include <stdarg.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - #include <glib.h> #include <gio/gio.h> -#include <gdk/gdk.h> -#include <gtk/gtk.h> - -#include <libxfce4util/libxfce4util.h> - #include <thunar/thunar-exec.h> #include <thunar/thunar-private.h> -#ifdef GDK_WINDOWING_X11 -#include <X11/Xatom.h> -#include <gdk/gdkx.h> -#endif - static void te_string_append_quoted (GString *string, @@ -240,342 +210,3 @@ done: g_string_free (command_line, TRUE); return result; } - - - -#ifdef HAVE_LIBSTARTUP_NOTIFICATION -#include <libsn/sn.h> - -/* the max. timeout for an application to startup */ -#define TSN_STARTUP_TIMEOUT (30 * 1000) - -typedef struct -{ - SnLauncherContext *sn_launcher; - guint timeout_id; - guint watch_id; - GPid pid; -} TsnStartupData; - -static gboolean -tvsn_startup_timeout (gpointer data) -{ - TsnStartupData *startup_data = data; - GTimeVal now; - gdouble elapsed; - glong tv_sec; - glong tv_usec; - - GDK_THREADS_ENTER (); - - /* determine the amount of elapsed time */ - g_get_current_time (&now); - sn_launcher_context_get_last_active_time (startup_data->sn_launcher, &tv_sec, &tv_usec); - elapsed = (((gdouble) now.tv_sec - tv_sec) * G_USEC_PER_SEC + (now.tv_usec - tv_usec)) / 1000.0; - - /* check if the timeout was reached */ - if (elapsed >= TSN_STARTUP_TIMEOUT) - { - /* abort the startup notification */ - sn_launcher_context_complete (startup_data->sn_launcher); - sn_launcher_context_unref (startup_data->sn_launcher); - startup_data->sn_launcher = NULL; - } - - GDK_THREADS_LEAVE (); - - /* keep the startup timeout if not elapsed */ - return (elapsed < TSN_STARTUP_TIMEOUT); -} - -static void -tvsn_startup_timeout_destroy (gpointer data) -{ - TsnStartupData *startup_data = data; - - _thunar_return_if_fail (startup_data->sn_launcher == NULL); - - /* cancel the watch (if any) */ - if (startup_data->watch_id != 0) - g_source_remove (startup_data->watch_id); - - /* make sure we don't leave zombies (see bug #2983 for details) */ - g_child_watch_add_full (G_PRIORITY_LOW, startup_data->pid, - (GChildWatchFunc) g_spawn_close_pid, - NULL, NULL); - - /* release the startup data */ - g_slice_free (TsnStartupData, startup_data); -} - -static void -tvsn_startup_watch (GPid pid, - gint status, - gpointer data) -{ - TsnStartupData *startup_data = data; - - _thunar_return_if_fail (startup_data->sn_launcher != NULL); - _thunar_return_if_fail (startup_data->watch_id != 0); - _thunar_return_if_fail (startup_data->pid == pid); - - /* abort the startup notification (application exited) */ - sn_launcher_context_complete (startup_data->sn_launcher); - sn_launcher_context_unref (startup_data->sn_launcher); - startup_data->sn_launcher = NULL; - - /* cancel the startup notification timeout */ - g_source_remove (startup_data->timeout_id); -} - -static gint -tvsn_get_active_workspace_number (GdkScreen *screen) -{ - GdkWindow *root; - gulong bytes_after_ret = 0; - gulong nitems_ret = 0; - guint *prop_ret = NULL; - Atom _NET_CURRENT_DESKTOP; - Atom _WIN_WORKSPACE; - Atom type_ret = None; - gint format_ret; - gint ws_num = 0; - - gdk_error_trap_push (); - - root = gdk_screen_get_root_window (screen); - - /* determine the X atom values */ - _NET_CURRENT_DESKTOP = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_NET_CURRENT_DESKTOP", False); - _WIN_WORKSPACE = XInternAtom (GDK_WINDOW_XDISPLAY (root), "_WIN_WORKSPACE", False); - - if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root), - _NET_CURRENT_DESKTOP, 0, 32, False, XA_CARDINAL, - &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, - (gpointer) &prop_ret) != Success) - { - if (XGetWindowProperty (GDK_WINDOW_XDISPLAY (root), GDK_WINDOW_XWINDOW (root), - _WIN_WORKSPACE, 0, 32, False, XA_CARDINAL, - &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, - (gpointer) &prop_ret) != Success) - { - if (G_UNLIKELY (prop_ret != NULL)) - { - XFree (prop_ret); - prop_ret = NULL; - } - } - } - - if (G_LIKELY (prop_ret != NULL)) - { - if (G_LIKELY (type_ret != None && format_ret != 0)) - ws_num = *prop_ret; - XFree (prop_ret); - } - - gdk_error_trap_pop (); - - return ws_num; -} -#endif - - - -/** - * thunar_exec_on_screen: - * @screen : a #GdkScreen. - * @working_directory : child's current working directory or %NULL to inherit parent's. - * @argv : child's argument vector. - * @envp : child's environment vector or %NULL to inherit parent's. - * @flags : flags from #GSpawnFlags. - * @startup_notify : whether to use startup notification. - * @icon_name : application icon or %NULL. - * @error : return location for errors or %NULL. - * - * Like gdk_spawn_on_screen(), but also supports startup notification - * (if Thunar was built with startup notification support). - * - * Return value: %TRUE on success, %FALSE if @error is set. - **/ -gboolean -thunar_exec_on_screen (GdkScreen *screen, - const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - gboolean startup_notify, - const gchar *icon_name, - GError **error) -{ -#ifdef HAVE_LIBSTARTUP_NOTIFICATION - SnLauncherContext *sn_launcher = NULL; - TsnStartupData *startup_data; - SnDisplay *sn_display = NULL; - gint sn_workspace; -#endif -#ifndef HAVE_UNISTD_H - extern gchar **environ; -#endif - gboolean succeed; - gchar *display_name; - gchar **cenvp = envp; - gint n_cenvp, n; - GPid pid; - - /* setup the child environment (stripping $DESKTOP_STARTUP_ID and $DISPLAY) */ - if (G_LIKELY (envp == NULL)) - envp = (gchar **) environ; - for (n = 0; envp[n] != NULL; ++n) ; - cenvp = g_new0 (gchar *, n + 3); - for (n_cenvp = n = 0; envp[n] != NULL; ++n) - if (strncmp (envp[n], "DESKTOP_STARTUP_ID", 18) != 0 && strncmp (envp[n], "DISPLAY", 7) != 0) - cenvp[n_cenvp++] = g_strdup (envp[n]); - - /* add the real display name for the screen */ - display_name = gdk_screen_make_display_name (screen); - cenvp[n_cenvp++] = g_strconcat ("DISPLAY=", display_name, NULL); - g_free (display_name); - -#ifdef HAVE_LIBSTARTUP_NOTIFICATION - /* initialize the sn launcher context */ - if (G_LIKELY (startup_notify)) - { - sn_display = sn_display_new (GDK_SCREEN_XDISPLAY (screen), - (SnDisplayErrorTrapPush) gdk_error_trap_push, - (SnDisplayErrorTrapPop) gdk_error_trap_pop); - - if (G_LIKELY (sn_display != NULL)) - { - sn_launcher = sn_launcher_context_new (sn_display, GDK_SCREEN_XNUMBER (screen)); - - if (G_LIKELY (sn_launcher != NULL && !sn_launcher_context_get_initiated (sn_launcher))) - { - /* initiate the sn launcher context */ - sn_workspace = tvsn_get_active_workspace_number (screen); - sn_launcher_context_set_binary_name (sn_launcher, argv[0]); - sn_launcher_context_set_workspace (sn_launcher, sn_workspace); - sn_launcher_context_set_icon_name (sn_launcher, (icon_name != NULL) ? icon_name : "applications-other"); - sn_launcher_context_initiate (sn_launcher, g_get_prgname (), argv[0], gtk_get_current_event_time ()); - - /* add the real startup id to the child environment */ - cenvp[n_cenvp++] = g_strconcat ("DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id (sn_launcher), NULL); - - /* we want to watch the child process */ - flags |= G_SPAWN_DO_NOT_REAP_CHILD; - } - } - } -#endif - - /* try to spawn the new process */ - succeed = g_spawn_async (working_directory, argv, cenvp, flags, NULL, NULL, &pid, error); - -#ifdef HAVE_LIBSTARTUP_NOTIFICATION - /* handle the sn launcher context */ - if (G_LIKELY (sn_launcher != NULL)) - { - if (G_UNLIKELY (!succeed)) - { - /* abort the sn sequence */ - sn_launcher_context_complete (sn_launcher); - sn_launcher_context_unref (sn_launcher); - } - else - { - /* schedule a startup notification timeout */ - startup_data = g_slice_new (TsnStartupData); - startup_data->sn_launcher = sn_launcher; - startup_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, TSN_STARTUP_TIMEOUT, tvsn_startup_timeout, - startup_data, tvsn_startup_timeout_destroy); - startup_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, tvsn_startup_watch, startup_data, NULL); - startup_data->pid = pid; - } - } - else if (G_LIKELY (succeed)) - { - /* make sure we don't leave zombies (see bug #2983 for details) */ - g_child_watch_add_full (G_PRIORITY_LOW, pid, (GChildWatchFunc) g_spawn_close_pid, NULL, NULL); - - } - - /* release the sn display */ - if (G_LIKELY (sn_display != NULL)) - sn_display_unref (sn_display); -#endif - - /* release the child environment */ - g_strfreev (cenvp); - - return succeed; -} - - - -/** - * thunar_exec_sync: - * @command_fmt : the command to execute (can be a printf - * format string). - * @error : return location for errors or %NULL. - * @... : additional parameters to fill into - * @command_fmt. - * - * Executes the given @command_fmt and returns %TRUE if the - * command terminated successfully. Else, the @error is set - * to the standard error output. - * - * Return value: %TRUE if the @command_line was executed - * successfully, %FALSE if @error is set. - **/ -gboolean -thunar_exec_sync (const gchar *command_fmt, - GError **error, - ...) -{ - gboolean result; - va_list args; - gchar *standard_error; - gchar *command_line; - gint exit_status; - - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (command_fmt != NULL, FALSE); - - /* determine the command line */ - va_start (args, error); - command_line = g_strdup_vprintf (command_fmt, args); - va_end (args); - - /* try to execute the command line */ - result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, error); - if (G_UNLIKELY (result)) - { - /* check if the command failed */ - if (G_UNLIKELY (exit_status != 0)) - { - /* drop additional whitespace from the stderr output */ - g_strstrip (standard_error); - - /* strip all trailing dots from the stderr output */ - while (*standard_error != '\0' && standard_error[strlen (standard_error) - 1] == '.') - standard_error[strlen (standard_error) - 1] = '\0'; - - /* generate an error from the stderr output */ - if (G_LIKELY (*standard_error != '\0')) - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", standard_error); - else - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unknown error")); - - /* and yes, we failed */ - result = FALSE; - } - - /* release the stderr output */ - g_free (standard_error); - } - - /* cleanup */ - g_free (command_line); - - return result; -} diff --git a/thunar/thunar-exec.h b/thunar/thunar-exec.h index 1978f98..32b5b3c 100644 --- a/thunar/thunar-exec.h +++ b/thunar/thunar-exec.h @@ -36,19 +36,6 @@ gboolean thunar_exec_parse (const gchar *exec, gchar ***argv, GError **error); -gboolean thunar_exec_on_screen (GdkScreen *screen, - const gchar *working_directory, - gchar **argv, - gchar **envp, - GSpawnFlags flags, - gboolean startup_notify, - const gchar *icon_name, - GError **error); - -gboolean thunar_exec_sync (const gchar *command_line, - GError **error, - ...); - G_END_DECLS; #endif /* !__THUNAR_EXEC_H__ */ diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c index 4b91ac7..a633242 100644 --- a/thunar/thunar-file.c +++ b/thunar/thunar-file.c @@ -50,6 +50,7 @@ #endif #include <gio/gio.h> +#include <libxfce4ui/libxfce4ui.h> #include <thunarx/thunarx.h> @@ -1090,8 +1091,8 @@ thunar_file_execute (ThunarFile *file, } /* execute the command */ - result = thunar_exec_on_screen (screen, directory, argv, NULL, G_SPAWN_SEARCH_PATH, - snotify, icon, error); + result = xfce_spawn_on_screen (screen, directory, argv, NULL, G_SPAWN_SEARCH_PATH, + snotify, gtk_get_current_event_time (), icon, error); /* release the working directory */ g_free (directory); _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits