[Xfce4-commits] <thunar:use-libxfce4ui> Use the spawn code from libxfce4ui.
Nick Schermer
noreply at xfce.org
Sat Oct 17 18:26:03 CEST 2009
Updating branch refs/heads/nick/use-libxfce4ui
to 8990efaf5a89afa3a47b9358b57aa0ffad64eff0 (commit)
from 90b3d9fe2b4224103e67397db40f85c244bd1b55 (commit)
commit 8990efaf5a89afa3a47b9358b57aa0ffad64eff0
Author: Nick Schermer <nick at 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);
More information about the Xfce4-commits
mailing list