[Xfce4-commits] <libxfce4ui:master> Add new function xfce_spawn_on_screen_with_child_watch().
Nick Schermer
noreply at xfce.org
Thu Dec 17 22:08:01 CET 2009
Updating branch refs/heads/master
to 198674ebaa599a086e52dd1b37b5457bd8ebb72c (commit)
from 43abf64e7606ddffabe66814ffac07d5c1596be2 (commit)
commit 198674ebaa599a086e52dd1b37b5457bd8ebb72c
Author: Nick Schermer <nick at xfce.org>
Date: Thu Dec 17 22:00:51 2009 +0100
Add new function xfce_spawn_on_screen_with_child_watch().
New function to spawn a command with child watch. For the callback
a closure is used (void__int). Although the PID is not returned,
this is good enough for most implementations.
Internal change to use environ again instead of the glib code,
which only resulted in a lot of string copying.
Use seconds timeout to the startup expire time.
configure.in.in | 6 +-
docs/libxfce4ui-sections.txt | 1 +
docs/tmpl/xfce-spawn.sgml | 18 ++-
libxfce4ui/libxfce4ui.symbols | 1 +
libxfce4ui/xfce-spawn.c | 415 ++++++++++++++++++++++++++++-------------
libxfce4ui/xfce-spawn.h | 41 +++--
6 files changed, 330 insertions(+), 152 deletions(-)
diff --git a/configure.in.in b/configure.in.in
index 7158fba..e82ba23 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -106,8 +106,10 @@ dnl ***************************************
dnl *** Check for standard header files ***
dnl ***************************************
AC_HEADER_STDC()
-AC_CHECK_HEADERS([errno.h fcntl.h limits.h locale.h math.h memory.h \
- signal.h stdarg.h stdlib.h string.h unistd.h])
+AC_CHECK_HEADERS([crt_externs.h errno.h fcntl.h limits.h locale.h math.h \
+ memory.h signal.h stdarg.h stdlib.h string.h unistd.h])
+AC_CHECK_DECLS([environ])
+AC_CHECK_FUNCS([_NSGetEnviron])
dnl ******************************
dnl *** Check for i18n support ***
diff --git a/docs/libxfce4ui-sections.txt b/docs/libxfce4ui-sections.txt
index cc44425..31bb41c 100644
--- a/docs/libxfce4ui-sections.txt
+++ b/docs/libxfce4ui-sections.txt
@@ -15,6 +15,7 @@ LIBXFCE4UI_CHECK_VERSION
<SECTION>
<FILE>xfce-spawn</FILE>
+xfce_spawn_on_screen_with_child_watch
xfce_spawn_on_screen
xfce_spawn_command_line_on_screen
</SECTION>
diff --git a/docs/tmpl/xfce-spawn.sgml b/docs/tmpl/xfce-spawn.sgml
index 0aca5cb..6167d5b 100644
--- a/docs/tmpl/xfce-spawn.sgml
+++ b/docs/tmpl/xfce-spawn.sgml
@@ -17,6 +17,22 @@ startup notification and they show up on the correct screen and workspace.
<!-- ##### SECTION Stability_Level ##### -->
+<!-- ##### FUNCTION xfce_spawn_on_screen_with_child_watch ##### -->
+<para>
+
+</para>
+
+ at screen:
+ at working_directory:
+ at argv:
+ at envp:
+ at flags:
+ at startup_notify:
+ at startup_timestamp:
+ at startup_icon_name:
+ at child_watch_closure:
+ at error:
+ at Returns:
<!-- ##### FUNCTION xfce_spawn_on_screen ##### -->
<para>
@@ -30,7 +46,7 @@ startup notification and they show up on the correct screen and workspace.
@flags:
@startup_notify:
@startup_timestamp:
- at icon_name:
+ at startup_icon_name:
@error:
@Returns:
diff --git a/libxfce4ui/libxfce4ui.symbols b/libxfce4ui/libxfce4ui.symbols
index 304b589..9e9b9fe 100644
--- a/libxfce4ui/libxfce4ui.symbols
+++ b/libxfce4ui/libxfce4ui.symbols
@@ -87,6 +87,7 @@ xfce_gtk_window_center_on_active_screen
/* xfce-spawn functions */
#if IN_HEADER(__XFCE_SPAWN_H__)
#if IN_SOURCE(__XFCE_SPAWN_C__)
+xfce_spawn_on_screen_with_child_watch
xfce_spawn_on_screen
xfce_spawn_command_line_on_screen
#endif
diff --git a/libxfce4ui/xfce-spawn.c b/libxfce4ui/xfce-spawn.c
index 2ba5fc5..6c29c64 100644
--- a/libxfce4ui/xfce-spawn.c
+++ b/libxfce4ui/xfce-spawn.c
@@ -29,12 +29,18 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
+#ifdef HAVE_CRT_EXTERNS_H
+#include <crt_externs.h> /* for _NSGetEnviron */
+#endif
#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_X11
#include <X11/Xatom.h>
#include <gdk/gdkx.h>
+#else
+/* no x11, no sn */
+#undef HAVE_LIBSTARTUP_NOTIFICATION
#endif
#ifdef HAVE_LIBSTARTUP_NOTIFICATION
@@ -46,23 +52,36 @@
#include <libxfce4ui/libxfce4ui-private.h>
#include <libxfce4ui/libxfce4ui-alias.h>
-/* the maximum time for an application to startup */
-#define XFCE_SPAWN_STARTUP_TIMEOUT (30 * 1000)
+#ifdef HAVE__NSGETENVIRON
+/* for support under apple/darwin */
+#define environ (*_NSGetEnviron())
+#elif !HAVE_DECL_ENVIRON
+/* try extern if environ is not defined in unistd.h */
+extern gchar **environ;
+#endif
+
+/* the maximum time (seconds) for an application to startup */
+#define XFCE_SPAWN_STARTUP_TIMEOUT (30)
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
typedef struct
{
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+ /* startup notification data */
SnLauncherContext *sn_launcher;
guint timeout_id;
+#endif
+
+ /* child watch data */
guint watch_id;
GPid pid;
+ GClosure *closure;
} XfceSpawnData;
-
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
static gboolean
xfce_spawn_startup_timeout (gpointer user_data)
{
@@ -72,74 +91,103 @@ xfce_spawn_startup_timeout (gpointer user_data)
glong tv_sec;
glong tv_usec;
- GDK_THREADS_ENTER ();
+ g_return_val_if_fail (spawn_data->sn_launcher != NULL, FALSE);
/* determine the amount of elapsed time */
g_get_current_time (&now);
sn_launcher_context_get_last_active_time (spawn_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;
+ elapsed = now.tv_sec - tv_sec + ((gdouble) (now.tv_usec - tv_usec) / G_USEC_PER_SEC);
- /* check if the timeout was reached */
- if (elapsed >= XFCE_SPAWN_STARTUP_TIMEOUT)
- {
- /* abort the startup notification */
- sn_launcher_context_complete (spawn_data->sn_launcher);
- sn_launcher_context_unref (spawn_data->sn_launcher);
- spawn_data->sn_launcher = NULL;
- }
+ return elapsed < XFCE_SPAWN_STARTUP_TIMEOUT;
+}
- GDK_THREADS_LEAVE ();
- /* keep the startup timeout if not elapsed */
- return (elapsed < XFCE_SPAWN_STARTUP_TIMEOUT);
+
+static void
+xfce_spawn_startup_timeout_destroy (gpointer user_data)
+{
+ XfceSpawnData *spawn_data = user_data;
+ GPid pid;
+
+ spawn_data->timeout_id = 0;
+
+ if (G_LIKELY (spawn_data->sn_launcher != NULL))
+ {
+ /* abort the startup notification */
+ sn_launcher_context_complete (spawn_data->sn_launcher);
+ sn_launcher_context_unref (spawn_data->sn_launcher);
+ spawn_data->sn_launcher = NULL;
+ }
+
+ /* if there is no closure to watch the child, also stop
+ * the child watch */
+ if (G_LIKELY (spawn_data->closure == NULL
+ && spawn_data->watch_id != 0))
+ {
+ pid = spawn_data->pid;
+ g_source_remove (spawn_data->watch_id);
+ g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
+ }
}
+#endif
static void
-xfce_spawn_startup_timeout_destroy (gpointer user_data)
+xfce_spawn_startup_watch (GPid pid,
+ gint status,
+ gpointer user_data)
{
XfceSpawnData *spawn_data = user_data;
+ GValue instance_and_params[2] = { { 0, }, { 0, } };
- g_return_if_fail (spawn_data->sn_launcher == NULL);
+ g_return_if_fail (spawn_data->pid == pid);
- /* cancel the watch (if any) */
- if (spawn_data->watch_id != 0)
- g_source_remove (spawn_data->watch_id);
+ if (G_UNLIKELY (spawn_data->closure != NULL))
+ {
+ /* xfce spawn has no instance */
+ g_value_init (&instance_and_params[0], G_TYPE_POINTER);
+ g_value_set_pointer (&instance_and_params[0], NULL);
- /* make sure we don't leave zombies */
- g_child_watch_add_full (G_PRIORITY_LOW, spawn_data->pid,
- (GChildWatchFunc) g_spawn_close_pid,
- NULL, NULL);
+ g_value_init (&instance_and_params[1], G_TYPE_INT);
+ g_value_set_int (&instance_and_params[1], status);
- /* release the startup data */
- g_slice_free (XfceSpawnData, spawn_data);
+ g_closure_set_marshal (spawn_data->closure, g_cclosure_marshal_VOID__INT);
+
+ g_closure_invoke (spawn_data->closure, NULL,
+ 2, instance_and_params, NULL);
+ }
+
+ /* don't leave zombies */
+ g_spawn_close_pid (pid);
}
static void
-xfce_spawn_startup_watch (GPid pid,
- gint status,
- gpointer user_data)
+xfce_spawn_startup_watch_destroy (gpointer user_data)
{
XfceSpawnData *spawn_data = user_data;
- g_return_if_fail (spawn_data->sn_launcher != NULL);
- g_return_if_fail (spawn_data->watch_id != 0);
- g_return_if_fail (spawn_data->pid == pid);
+ spawn_data->watch_id = 0;
+
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+ if (spawn_data->timeout_id != 0)
+ g_source_remove (spawn_data->timeout_id);
+#endif
- /* abort the startup notification (application exited) */
- sn_launcher_context_complete (spawn_data->sn_launcher);
- sn_launcher_context_unref (spawn_data->sn_launcher);
- spawn_data->sn_launcher = NULL;
+ if (G_UNLIKELY (spawn_data->closure != NULL))
+ {
+ g_closure_invalidate (spawn_data->closure);
+ g_closure_unref (spawn_data->closure);
+ }
- /* cancel the startup notification timeout */
- g_source_remove (spawn_data->timeout_id);
+ g_slice_free (XfceSpawnData, spawn_data);
}
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
static gint
xfce_spawn_get_active_workspace_number (GdkScreen *screen)
{
@@ -195,87 +243,108 @@ xfce_spawn_get_active_workspace_number (GdkScreen *screen)
/**
- * xfce_spawn_on_screen:
- * @screen : a #GdkScreen or %NULL to use the active screen,
- * see xfce_gdk_screen_get_active().
- * @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.
- * @startup_timestamp : the timestamp to pass to startup notification, use
- * the event time here if possible to make focus
- * stealing prevention work property. If you don't
- * have direct access to the event time you could use
- * gtk_get_current_event_time() or if nothing is
- * available 0 is valid too.
- * @icon_name : application icon or %NULL.
- * @error : return location for errors or %NULL.
+ * xfce_spawn_on_screen_with_closure:
+ * @screen : a #GdkScreen or %NULL to use the active screen,
+ * see xfce_gdk_screen_get_active().
+ * @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. #G_SPAWN_DO_NOT_REAP_CHILD
+ * is not allowed, you should use the
+ * @child_watch_closure for this.
+ * @startup_notify : whether to use startup notification.
+ * @startup_timestamp : the timestamp to pass to startup notification, use
+ * the event time here if possible to make focus
+ * stealing prevention work property. If you don't
+ * have direct access to the event time you could use
+ * gtk_get_current_event_time() or if nothing is
+ * available 0 is valid too.
+ * @startup_icon_name : application icon or %NULL.
+ * @child_watch_closure : closure that is triggered when the child exists
+ * or %NULL.
+ * @error : return location for errors or %NULL.
*
- * Like gdk_spawn_on_screen(), but also supports startup notification
- * (if Libxfce4ui was built with startup notification support).
+ * Like xfce_spawn_on_screen(), but allows to attach a closure to watch the
+ * child's exit status. This because only one g_child_watch_add() is allowed on
+ * Unix (per PID) and this is already internally needed for a proper
+ * startup notification implementation.
+ *
+ * <example>
+ * <title>Spawning with a child watch</title>
+ * <programlisting>
+ * static void
+ * child_watch_callback (GObject *object,
+ * gint status)
+ * {
+ * g_message ("Child exit status is %d", status);
+ * }
+ *
+ * static void
+ * spawn_something (void)
+ * {
+ * GClosure *child_watch;
+ *
+ * child_watch = g_cclosure_new_swap (G_CALLBACK (child_watch_callback),
+ * object, NULL);
+ * xfce_spawn_on_screen_with_child_watch (...,
+ * child_watch,
+ * ...);
+ * }
+ * </programlisting>
+ * </example>
*
* Return value: %TRUE on success, %FALSE if @error is set.
**/
gboolean
-xfce_spawn_on_screen (GdkScreen *screen,
- const gchar *working_directory,
- gchar **argv,
- gchar **envp,
- GSpawnFlags flags,
- gboolean startup_notify,
- guint32 startup_timestamp,
- const gchar *icon_name,
- GError **error)
+xfce_spawn_on_screen_with_child_watch (GdkScreen *screen,
+ const gchar *working_directory,
+ gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ gboolean startup_notify,
+ guint32 startup_timestamp,
+ const gchar *startup_icon_name,
+ GClosure *child_watch_closure,
+ GError **error)
{
- gboolean succeed;
- gchar **cenvp;
- gint n;
- gint n_cenvp;
- gchar *display_name;
- GPid pid;
+ gboolean succeed;
+ gchar **cenvp;
+ guint n;
+ guint n_cenvp;
+ gchar *display_name;
+ GPid pid;
+ XfceSpawnData *spawn_data;
#ifdef HAVE_LIBSTARTUP_NOTIFICATION
- SnLauncherContext *sn_launcher = NULL;
- XfceSpawnData *spawn_data;
- SnDisplay *sn_display = NULL;
- gint sn_workspace;
+ SnLauncherContext *sn_launcher = NULL;
+ SnDisplay *sn_display = NULL;
+ gint sn_workspace;
+ const gchar *startup_id;
+ const gchar *prgname;
#endif
g_return_val_if_fail (screen == NULL || GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* lookup the screen with the pointer */
if (screen == NULL)
screen = xfce_gdk_screen_get_active (NULL);
- /* setup the child environment, without startup id and display */
+ /* 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)
{
- /* use the portable g_listenv, but note that this function only returns the
- * variable names, not with values, therefore the call to g_getenv */
- envp = g_listenv ();
- cenvp = g_new0 (gchar *, g_strv_length (envp) + 3);
- for (n = n_cenvp = 0; envp[n] != NULL; n++)
- if (strcmp (envp[n], "DESKTOP_STARTUP_ID") != 0
- && strcmp (envp[n], "DISPLAY") != 0)
- cenvp[n_cenvp++] = g_strconcat (envp[n], "=", g_getenv (envp[n]), NULL);
-
- /* cleanup */
- g_strfreev (envp);
- envp = NULL;
- }
- else
- {
- cenvp = g_new0 (gchar *, g_strv_length (envp) + 3);
- for (n = n_cenvp = 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]);
+ 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 */
+ /* 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);
@@ -291,18 +360,27 @@ xfce_spawn_on_screen (GdkScreen *screen,
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)))
+ if (G_LIKELY (sn_launcher != NULL))
{
/* initiate the sn launcher context */
sn_workspace = xfce_spawn_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], startup_timestamp);
+ sn_launcher_context_set_binary_name (sn_launcher, argv[0]);
+ sn_launcher_context_set_icon_name (sn_launcher, startup_icon_name != NULL ?
+ startup_icon_name : "applications-other");
+
+ if (G_LIKELY (!sn_launcher_context_get_initiated (sn_launcher)))
+ {
+ prgname = g_get_prgname ();
+ sn_launcher_context_initiate (sn_launcher, prgname != NULL ?
+ prgname : "unknown", argv[0],
+ startup_timestamp);
+ }
/* 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);
+ startup_id = sn_launcher_context_get_startup_id (sn_launcher);
+ if (G_LIKELY (startup_id != NULL))
+ cenvp[n_cenvp++] = g_strconcat ("DESKTOP_STARTUP_ID=", startup_id, NULL);
/* we want to watch the child process */
flags |= G_SPAWN_DO_NOT_REAP_CHILD;
@@ -311,49 +389,120 @@ xfce_spawn_on_screen (GdkScreen *screen,
}
#endif
+ /* watch the child when the user supplied a closure too */
+ if (child_watch_closure != NULL)
+ flags |= G_SPAWN_DO_NOT_REAP_CHILD;
+
/* try to spawn the new process */
- succeed = g_spawn_async (working_directory, argv, cenvp, flags, NULL, NULL, &pid, error);
+ succeed = g_spawn_async (working_directory, argv, cenvp, flags, NULL,
+ NULL, &pid, error);
-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
- if (G_LIKELY (sn_launcher != NULL))
+ g_strfreev (cenvp);
+
+ if (G_LIKELY (succeed))
{
- if (G_UNLIKELY (!succeed))
+ if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) != 0)
{
- /* abort the startup notification sequence */
- sn_launcher_context_complete (sn_launcher);
- sn_launcher_context_unref (sn_launcher);
- }
- else
- {
- /* schedule a startup notification timeout */
+ /* setup data to watch the child */
spawn_data = g_slice_new0 (XfceSpawnData);
- spawn_data->sn_launcher = sn_launcher;
- spawn_data->timeout_id = g_timeout_add_full (G_PRIORITY_LOW, XFCE_SPAWN_STARTUP_TIMEOUT, xfce_spawn_startup_timeout,
- spawn_data, xfce_spawn_startup_timeout_destroy);
- spawn_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, xfce_spawn_startup_watch, spawn_data, NULL);
spawn_data->pid = pid;
+ if (child_watch_closure != NULL)
+ {
+ spawn_data->closure = g_closure_ref (child_watch_closure);
+ g_closure_sink (spawn_data->closure);
+ }
+
+ spawn_data->watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid,
+ xfce_spawn_startup_watch,
+ spawn_data,
+ xfce_spawn_startup_watch_destroy);
+
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+ if (G_LIKELY (sn_launcher != NULL))
+ {
+ /* start a timeout to stop the startup notification sequence after
+ * a certain about of time, to handle applications that do not
+ * properly implement startup notify */
+ spawn_data->sn_launcher = sn_launcher;
+ spawn_data->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_LOW,
+ XFCE_SPAWN_STARTUP_TIMEOUT,
+ xfce_spawn_startup_timeout,
+ spawn_data,
+ xfce_spawn_startup_timeout_destroy);
+ }
+#endif
}
}
- else if (G_LIKELY (succeed))
+ else
{
- /* make sure we don't leave zombies */
- g_child_watch_add_full (G_PRIORITY_LOW, pid, (GChildWatchFunc) g_spawn_close_pid, NULL, NULL);
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
+ if (G_LIKELY (sn_launcher != NULL))
+ {
+ /* abort the startup notification sequence */
+ sn_launcher_context_complete (sn_launcher);
+ sn_launcher_context_unref (sn_launcher);
+ }
+#endif
}
+#ifdef HAVE_LIBSTARTUP_NOTIFICATION
/* release the sn display */
if (G_LIKELY (sn_display != NULL))
sn_display_unref (sn_display);
#endif
- /* cleanup */
- g_strfreev (cenvp);
-
return succeed;
}
/**
+ * xfce_spawn_on_screen:
+ * @screen : a #GdkScreen or %NULL to use the active screen,
+ * see xfce_gdk_screen_get_active().
+ * @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. #G_SPAWN_DO_NOT_REAP_CHILD
+ * is not allowed, use xfce_spawn_on_screen_with_child_watch()
+ * if you want a child watch.
+ * @startup_notify : whether to use startup notification.
+ * @startup_timestamp : the timestamp to pass to startup notification, use
+ * the event time here if possible to make focus
+ * stealing prevention work property. If you don't
+ * have direct access to the event time you could use
+ * gtk_get_current_event_time() or if nothing is
+ * available 0 is valid too.
+ * @startup_icon_name : application icon or %NULL.
+ * @error : return location for errors or %NULL.
+ *
+ * Like gdk_spawn_on_screen(), but also supports startup notification
+ * (if Libxfce4ui was built with startup notification support).
+ *
+ * Return value: %TRUE on success, %FALSE if @error is set.
+ **/
+gboolean
+xfce_spawn_on_screen (GdkScreen *screen,
+ const gchar *working_directory,
+ gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ gboolean startup_notify,
+ guint32 startup_timestamp,
+ const gchar *startup_icon_name,
+ GError **error)
+{
+ return xfce_spawn_on_screen_with_child_watch (screen, working_directory, argv,
+ envp, flags, startup_notify,
+ startup_timestamp, startup_icon_name,
+ NULL, error);
+}
+
+
+
+/**
* xfce_spawn_command_line_on_screen:
* @screen : a #GdkScreen or %NULL to use the active screen, see xfce_gdk_screen_get_active().
* @command_line : command line to run.
@@ -382,7 +531,6 @@ xfce_spawn_command_line_on_screen (GdkScreen *screen,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (command_line != NULL, FALSE);
- /* parse the command */
if (in_terminal == FALSE)
{
/* parse the command, retrun false with error when this fails */
@@ -400,12 +548,11 @@ xfce_spawn_command_line_on_screen (GdkScreen *screen,
argv[4] = NULL;
}
- /* execute the function */
- succeed = xfce_spawn_on_screen (screen, NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH, startup_notify,
- gtk_get_current_event_time (), NULL, error);
+ succeed = xfce_spawn_on_screen_with_child_watch (screen, NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH, startup_notify,
+ gtk_get_current_event_time (),
+ NULL, NULL, error);
- /* cleanup */
g_strfreev (argv);
return succeed;
diff --git a/libxfce4ui/xfce-spawn.h b/libxfce4ui/xfce-spawn.h
index e262206..486f30e 100644
--- a/libxfce4ui/xfce-spawn.h
+++ b/libxfce4ui/xfce-spawn.h
@@ -29,21 +29,32 @@
G_BEGIN_DECLS
-gboolean xfce_spawn_on_screen (GdkScreen *screen,
- const gchar *working_directory,
- gchar **argv,
- gchar **envp,
- GSpawnFlags flags,
- gboolean startup_notify,
- guint32 startup_timestamp,
- const gchar *icon_name,
- GError **error);
-
-gboolean xfce_spawn_command_line_on_screen (GdkScreen *screen,
- const gchar *command_line,
- gboolean in_terminal,
- gboolean startup_notify,
- GError **error);
+gboolean xfce_spawn_on_screen_with_child_watch (GdkScreen *screen,
+ const gchar *working_directory,
+ gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ gboolean startup_notify,
+ guint32 startup_timestamp,
+ const gchar *startup_icon_name,
+ GClosure *child_watch_closure,
+ GError **error);
+
+gboolean xfce_spawn_on_screen (GdkScreen *screen,
+ const gchar *working_directory,
+ gchar **argv,
+ gchar **envp,
+ GSpawnFlags flags,
+ gboolean startup_notify,
+ guint32 startup_timestamp,
+ const gchar *startup_icon_name,
+ GError **error);
+
+gboolean xfce_spawn_command_line_on_screen (GdkScreen *screen,
+ const gchar *command_line,
+ gboolean in_terminal,
+ gboolean startup_notify,
+ GError **error);
G_END_DECLS
More information about the Xfce4-commits
mailing list