Beispiel #1
0
static void
maybe_lock_screen (ShellStatusMenu *status)
{
  char *args[3];
  GError *err;
  GdkScreen *screen;
  gboolean use_gscreensaver = TRUE;
  gboolean res;

  g_debug ("Attempting to lock screen");

  args[0] = g_find_program_in_path ("gnome-screensaver-command");
  if (args[0] == NULL)
    {
      args[0] = g_find_program_in_path ("xscreensaver-command");
      use_gscreensaver = FALSE;
    }

  if (args[0] == NULL)
    return;

  if (use_gscreensaver)
    args[1] = "--lock";
  else
    args[1] = "-lock";
  args[2] = NULL;

  screen = gdk_screen_get_default ();

  err = NULL;
  res = gdk_spawn_on_screen (screen, g_get_home_dir (), args, NULL, 0, NULL,
      NULL, NULL, &err);
  if (!res)
    {
      g_warning (_("Can't lock screen: %s"), err->message);
      g_error_free (err);
    }

  if (use_gscreensaver)
    args[1] = "--throttle";
  else
    args[1] = "-throttle";

  err = NULL;
  res = gdk_spawn_on_screen (screen, g_get_home_dir (), args, NULL,
      (G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_STDOUT_TO_DEV_NULL), NULL, NULL,
      NULL, &err);
  if (!res)
    {
      g_warning (_("Can't temporarily set screensaver to blank screen: %s"),
          err->message);
      g_error_free (err);
    }

  g_free (args[0]);
}
void
panel_launch_desktop_file (const char  *desktop_file,
			   const char  *fallback_exec,
			   GdkScreen   *screen,
			   GError     **error)
{
	GnomeDesktopItem *ditem;

	if (g_path_is_absolute (desktop_file))
		ditem = gnome_desktop_item_new_from_file (desktop_file, 0,
							  error);
	else
		ditem = gnome_desktop_item_new_from_basename (desktop_file, 0,
							      error);

	if (ditem != NULL) {
		panel_ditem_launch (ditem, NULL, screen, error);
		gnome_desktop_item_unref (ditem);
	} else if (fallback_exec != NULL) {
		char *argv [2] = {(char *)fallback_exec, NULL};

		if (*error) {
			g_error_free (*error);
			*error = NULL;
		}

		gdk_spawn_on_screen (screen, NULL, argv, NULL,
				     G_SPAWN_SEARCH_PATH,
				     NULL, NULL, NULL, error);
	}
}
Beispiel #3
0
static void
on_quit_session_activate (GtkMenuItem   *item,
                          ShellStatusMenu *status)
{
  char      *args[3];
  GError    *error;
  GdkScreen *screen;
  gboolean   res;

  args[0] = g_find_program_in_path ("gnome-session-save");
  if (args[0] == NULL)
    return;

  args[1] = "--logout-dialog";
  args[2] = NULL;

  screen = gdk_screen_get_default ();

  error = NULL;
  res = gdk_spawn_on_screen (screen, g_get_home_dir (), args, NULL, 0, NULL,
      NULL, NULL, &error);
  if (!res)
    {
      g_warning (_("Can't logout: %s"), error->message);
      g_error_free (error);
    }

  g_free (args[0]);
}
Beispiel #4
0
static gboolean
spawn_synaptic (GtkWindow   *window,
		const gchar *path,
		gint        *child_pid)
{
  gchar **argv;
  GError *error = NULL;
  gboolean retval = TRUE;
  gint i = 0;

  argv = g_new0 (gchar*, 6);
  argv[i++] = g_find_program_in_path ("gksudo");
  argv[i++] = g_strdup ("--desktop");
  argv[i++] = g_strdup ("/usr/share/applications/synaptic.desktop");
  argv[i++] = g_strdup ("--disable-grab");
  argv[i++] = get_synaptic_command_line (window, path);
  argv[i++] = NULL;

  if (!gdk_spawn_on_screen (gtk_window_get_screen (window),
			    NULL, argv, NULL,
			    G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
			    NULL, NULL, child_pid, &error))
    {
      show_error_dialog (window, (error) ? error->message : "");
      g_error_free (error);
      retval = FALSE;
    }

  g_strfreev (argv);

  return retval;
}
Beispiel #5
0
/* Calls 'gnome-session-save arg' */
static void
gnome_session_save_command (const char *arg)
{
  char      *args[3];
  GError    *error;
  GdkScreen *screen;
  gboolean   res;

  args[0] = g_find_program_in_path ("gnome-session-save");
  if (args[0] == NULL)
    return;

  args[1] = (char *)arg;
  args[2] = NULL;

  screen = gdk_screen_get_default ();

  error = NULL;
  res = gdk_spawn_on_screen (screen, g_get_home_dir (), args, NULL, 0, NULL,
      NULL, NULL, &error);
  if (!res)
    {
      g_warning (_("Can't logout: %s"), error->message);
      g_error_free (error);
    }

  g_free (args[0]);
}
Beispiel #6
0
static gboolean
panel_run_dialog_launch_command (PanelRunDialog *dialog,
				 const char     *command,
				 const char     *locale_command)
{
	GdkScreen  *screen;
	gboolean    result;
	GError     *error = NULL;
	char      **argv;
	int         argc;
	GPid        pid;

	if (!command_is_executable (locale_command, &argc, &argv))
		return FALSE;

	screen = gtk_window_get_screen (GTK_WINDOW (dialog->run_dialog));

	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->terminal_checkbox)))
		mate_desktop_prepend_terminal_to_vector (&argc, &argv);

#if GTK_CHECK_VERSION (3, 0, 0)
	result = g_spawn_async (NULL, /* working directory */
				argv,
				NULL, /* envp */
				G_SPAWN_SEARCH_PATH,
				NULL,
				NULL,
				&pid,
				&error);
#else
	result = gdk_spawn_on_screen (screen,
				      NULL, /* working directory */
				      argv,
				      NULL, /* envp */
				      G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
				      NULL, /* child setup func */
				      NULL, /* user data */
				      &pid, /* child pid */
				      &error);
#endif

	if (!result) {
		char *primary;

		primary = g_markup_printf_escaped (_("Could not run command '%s'"),
						   command);
		panel_error_dialog (GTK_WINDOW (dialog->run_dialog), NULL,
				    "cannot_spawn_command", TRUE,
				    primary, error->message);
		g_free (primary);

		g_error_free (error);
	} else {
		g_child_watch_add (pid, dummy_child_watch, NULL);
	}

	g_strfreev (argv);

	return result;
}
Beispiel #7
0
static void call_system_monitor(GtkAction* action, TasklistData* tasklist)
{
#if !GTK_CHECK_VERSION (3, 0, 0)
	char* argv[2] = {NULL, NULL};
#endif
	char* programpath;
	int i;

	for (i = 0; i < G_N_ELEMENTS(system_monitors); i += 1)
	{
		programpath = g_find_program_in_path(system_monitors[i]);

		if (programpath != NULL)
		{
			g_free(programpath);

#if GTK_CHECK_VERSION (3, 0, 0)
			mate_gdk_spawn_command_line_on_screen(gtk_widget_get_screen(tasklist->applet),
				      system_monitors[i],
				      NULL);
#else
			argv[0] = system_monitors[i];
			gdk_spawn_on_screen(gtk_widget_get_screen(tasklist->applet), NULL, argv, NULL,
				      G_SPAWN_SEARCH_PATH,
				      NULL, NULL, NULL, NULL);
#endif

			return;
		}
	}
}
static void
main_window_help_debug_cb (GtkAction         *action,
			   EmpathyMainWindow *window)
{
	GdkScreen *screen = gdk_screen_get_default ();
	GError *error = NULL;
	gchar *argv[2] = { NULL, };
	gint i = 0;
	gchar *path;

	g_return_if_fail (GDK_IS_SCREEN (screen));

	/* Try to run from source directory if possible */
	path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), "src",
			"empathy-debugger", NULL);

	if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
		g_free (path);
		path = g_build_filename (BIN_DIR, "empathy-debugger", NULL);
	}

	argv[i++] = path;

	gdk_spawn_on_screen (screen, NULL, argv, NULL,
			G_SPAWN_SEARCH_PATH,
			NULL, NULL, NULL, &error);

	if (error) {
		g_warning ("Failed to open debug window: %s", error->message);
		g_error_free (error);
	}

	g_free (path);
}
Beispiel #9
0
/**
 * exo_execute_preferred_application_on_screen:
 * @category          : the category of the preferred application to launch.
 * @parameter         : additional parameter to pass to the preferred application
 *                      (i.e. an URL to pass to the preferred browser) or %NULL
 *                      to pass no parameter.
 * @working_directory : path to the directory in which to execute the
 *                      preferred application for @category.
 * @envp              : child's environment, or %NULL to inherit parent's.
 * @screen            : the #GdkScreen on which to run the preferred
 *                      application for @category.
 * @error             : return location for errors or %NULL.
 *
 * Launches the preferred application for the given @category with the
 * @parameter on @screen in the specified @working_directory.
 *
 * libexo currently supports the following categories: %"WebBrowser",
 * %"MailReader" and %"TerminalEmulator". If you specify an invalid
 * @category here, the execution will fail at a later stage and the
 * user will be presented with an error dialog.
 *
 * Note that even if this method returns %TRUE there's no warranty that
 * the preferred application for @category was run successfully, because
 * of the way the helper framework is implemented. But you can be sure
 * that if the execution fails at a later stage, the library will popup
 * an error dialog to inform the user that the execution failed.
 *
 * Returns: %TRUE on success, else %FALSE.
 *
 * Since: 0.3.1.3
 **/
gboolean
exo_execute_preferred_application_on_screen (const gchar *category,
                                             const gchar *parameter,
                                             const gchar *working_directory,
                                             gchar      **envp,
                                             GdkScreen   *screen,
                                             GError     **error)
{
  gchar *argv[5];
  gint   argc = 0;

  g_return_val_if_fail (category != NULL, FALSE);
  g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* generate the argument vector */
  argv[argc++] = HELPERDIR G_DIR_SEPARATOR_S "exo-helper-" LIBEXO_VERSION_API;
  argv[argc++] = "--launch";
  argv[argc++] = (gchar *) category;

  /* append parameter if given */
  if (G_LIKELY (parameter != NULL))
    argv[argc++] = (gchar *) parameter;

  /* null terminate the argument vector */
  argv[argc] = NULL;

  /* launch the command */
  return gdk_spawn_on_screen (screen, working_directory, argv, envp, 0, NULL, NULL, NULL, error);
}
Beispiel #10
0
gboolean
panel_launch_desktop_file_with_fallback (const char  *desktop_file,
					 const char  *fallback_exec,
					 GdkScreen   *screen,
					 GError     **error)
{
	char     *argv[2] = { (char *) fallback_exec, NULL };
	GError   *local_error;
	gboolean  retval;

	g_return_val_if_fail (desktop_file != NULL, FALSE);
	g_return_val_if_fail (fallback_exec != NULL, FALSE);
	g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	/* need to pass a non-NULL error to avoid getting a dialog */
	local_error = NULL;
	if (panel_launch_desktop_file (desktop_file, screen, &local_error))
		return TRUE;

	if (local_error) {
		g_error_free (local_error);
		local_error = NULL;
	}

	retval = gdk_spawn_on_screen (screen, NULL, argv, NULL,
				      G_SPAWN_SEARCH_PATH,
				      NULL, NULL, NULL, &local_error);

        if (local_error == NULL && retval == TRUE)
            return TRUE;

	return _panel_launch_handle_error (fallback_exec,
					   screen, local_error, error);
}
Beispiel #11
0
static void
spawn_external (ShellStatusMenu *status, const char *program)
{
  char *args[2];
  GError *error;
  GdkScreen *screen;
  gboolean res;

  args[0] = g_find_program_in_path (program);
  if (args[0] == NULL)
    return;
  args[1] = NULL;

  screen = gdk_screen_get_default ();

  error = NULL;
  res = gdk_spawn_on_screen (screen, g_get_home_dir (), args, NULL, 0, NULL,
      NULL, NULL, &error);
  if (!res)
    {
      g_warning ("Failed to exec %s: %s", program, error->message);
      g_clear_error (&error);
    }

  g_free (args[0]);

}
static gboolean
rb_disc_recorder_plugin_start_burning (RBDiscRecorderPlugin *pi,
					  const char *path,
					  gboolean copy)
{
	GtkWidget *main_window;
	GdkScreen *screen;
	GdkWindow *window;
	GPtrArray *array;
	char **args, *xid_str;
	GError *error = NULL;
	gboolean ret;
	
	array = g_ptr_array_new ();
	g_ptr_array_add (array, "brasero");
	if (copy != FALSE)
		g_ptr_array_add (array, "-c");
	else
		g_ptr_array_add (array, "-r");
	g_ptr_array_add (array, (gpointer) path);

	main_window = gtk_widget_get_toplevel (GTK_WIDGET (pi->selected_source));
	screen = gtk_widget_get_screen (main_window);
	window = gtk_widget_get_window (main_window);
	if (window) {
		int xid;
		xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (window));
		xid_str = g_strdup_printf ("%d", xid);
		g_ptr_array_add (array, "-x");
		g_ptr_array_add (array, xid_str);
	} else {
		xid_str = NULL;
	}
	
	g_ptr_array_add (array, NULL);
	args = (char **) g_ptr_array_free (array, FALSE);

	ret = TRUE;
	if (!gdk_spawn_on_screen (screen, NULL, args, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_FILE_AND_ARGV_ZERO, NULL, NULL, NULL, &error)) {
		if (copy != FALSE) {
			rb_error_dialog (GTK_WINDOW (main_window),
					 _("Rhythmbox could not duplicate the disc"),
					 "%s", error->message);

		} else {
			rb_error_dialog (GTK_WINDOW (main_window),
					 _("Rhythmbox could not record the audio disc"),
					 "%s", error->message);
		}
		ret = FALSE;
		g_error_free (error);
	}
	
	g_free (xid_str);
	g_free (args);
	
	return ret;
}
Beispiel #13
0
static gboolean
launch_previewer (void)
{
	GString *cmd_str;
	gchar   *cmd;
	gint     argc;
	gchar  **argv;
	gboolean retval = FALSE;
	GError  *error = NULL;

	/* Rebuild the command line, ignoring options
	 * not supported by the previewer and taking only
	 * the first path given
	 */
	cmd_str = g_string_new ("atril-previewer");
		
	if (print_settings) {
		gchar *quoted;

		quoted = g_shell_quote (print_settings);
		g_string_append_printf (cmd_str, " --print-settings %s", quoted);
		g_free (quoted);
	}

	if (unlink_temp_file)
		g_string_append (cmd_str, " --unlink-tempfile");

	if (file_arguments) {
		gchar *quoted;
		
		quoted = g_shell_quote (file_arguments[0]);
		g_string_append_printf (cmd_str, " %s", quoted);
		g_free (quoted);
	}

	cmd = g_string_free (cmd_str, FALSE);
	g_shell_parse_argv (cmd, &argc, &argv, &error);
	g_free (cmd);
	
	if (!error) {
		retval = gdk_spawn_on_screen (gdk_screen_get_default (),
					      NULL, argv, NULL,
					      G_SPAWN_SEARCH_PATH,
					      NULL, NULL, NULL,
					      &error);
		g_strfreev (argv);
	}

	if (error) {
		g_warning ("Error launching previewer: %s\n", error->message);
		g_error_free (error);
	}

	return retval;
}
static gboolean
idol_disc_recorder_plugin_start_burning (IdolDiscRecorderPlugin *pi,
					  const char *path,
					  gboolean copy)
{
	GtkWindow *main_window;
	GdkScreen *screen;
	GPtrArray *array;
	char **args, *xid_str;
	GError *error = NULL;
	gboolean ret;
	int xid;

	array = g_ptr_array_new ();
	g_ptr_array_add (array, (gpointer) "brasero");
	if (copy != FALSE)
		g_ptr_array_add (array, (gpointer) "-c");
	else
		g_ptr_array_add (array, (gpointer) "-r");
	g_ptr_array_add (array, (gpointer) path);

	main_window = idol_get_main_window (pi->idol);
	screen = gtk_widget_get_screen (GTK_WIDGET (main_window));
	xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (gtk_widget_get_window (GTK_WIDGET (main_window))));
	xid_str = g_strdup_printf ("%d", xid);
	g_ptr_array_add (array, (gpointer) "-x");
	g_ptr_array_add (array, xid_str);

	g_ptr_array_add (array, NULL);
	args = (char **) g_ptr_array_free (array, FALSE);

	ret = TRUE;
	if (gdk_spawn_on_screen (screen, NULL, args, NULL,
				 G_SPAWN_SEARCH_PATH | G_SPAWN_FILE_AND_ARGV_ZERO,
				 NULL, NULL, NULL, &error) == FALSE) {
		if (copy != FALSE) {
			idol_interface_error (_("The video disc could not be duplicated."),
					       error->message,
					       idol_get_main_window (pi->idol));
		} else {
			idol_interface_error (_("The movie could not be recorded."),
					       error->message,
					       idol_get_main_window (pi->idol));
		}
		ret = FALSE;
		g_error_free (error);
	}

	g_free (xid_str);
	g_free (args);

	return ret;
}
Beispiel #15
0
void
anjuta_res_url_show (const gchar *url)
{
	gchar *open[3];

	if (!anjuta_util_prog_is_installed ("xdg-open", TRUE))
		return;
	
	open[0] = "xdg-open";
	open[1] = (gchar *)url;
	open[2] = NULL;
					
	gdk_spawn_on_screen (gdk_screen_get_default (), NULL, open, NULL,
						 G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
}
Beispiel #16
0
void
mc_exec_command (MCData     *mc,
		 const char *cmd)
{
	GError *error = NULL;
	char command [1000];
	char **argv = NULL;
	gchar *str;

	strncpy (command, cmd, sizeof (command));
	command [sizeof (command) - 1] = '\0';

	mc_macro_expand_command (mc, command);

	if (!g_shell_parse_argv (command, NULL, &argv, &error)) {
		if (error != NULL) {
			g_error_free (error);
			error = NULL;
		}

		return;
	}

	if(!gdk_spawn_on_screen (gtk_widget_get_screen (GTK_WIDGET (mc->applet)),
				 g_get_home_dir (), argv, NULL,
				 G_SPAWN_SEARCH_PATH,
				 NULL, NULL, NULL,
				 &error)) {
		str = g_strconcat ("(?)", command, NULL);
		gtk_entry_set_text (GTK_ENTRY (mc->entry), str);
		//gtk_editable_set_position (GTK_EDITABLE (mc->entry), 0);
		mc->error = TRUE;
		beep ();
		g_free (str);
	} else {
		gtk_entry_set_text (GTK_ENTRY (mc->entry), (gchar *) "");
		append_history_entry (mc, cmd, FALSE);	
		}
	g_strfreev (argv);

	if (error != NULL)
		g_error_free (error);
}
static void nautilus_makepkg_menu_item_activate_cb (NautilusMenuItem *item, gpointer user_data) {
	gchar *options, *command, **argv;
	gint argc;
	GError *error = NULL;

	MenuItemActivateData *data = (MenuItemActivateData *) user_data;
	NautilusMakepkgPrivate *priv = data->self->priv;

	options = gconf_client_get_string (priv->conf, NAUTILUS_MAKEPKG_CONF_OPTIONS, &error);
	if (options == NULL) {
		g_warning ("Unable to retrieve key " NAUTILUS_MAKEPKG_CONF_OPTIONS ": %s\n", error->message);
		g_error_free (error);
		return;
	}

	command = g_strdup_printf ("%s %s", NAUTILUS_MAKEPKG_COMMAND, options);
	g_free (options);

	if (!g_shell_parse_argv (command, &argc, &argv, &error)) {
		g_warning ("Unable to understand options: %s\n", error->message);
		g_error_free (error);
		g_free (command);
		return;
	}

	gnome_desktop_prepend_terminal_to_vector (&argc, &argv);
	g_free (command);

	if (!gdk_spawn_on_screen (data->screen, data->path, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
		g_warning ("Unable to run makepkg: %s\n", error->message);
		g_error_free (error);
		g_strfreev (argv);
		return;
	}

	g_strfreev (argv);
	return;
}
Beispiel #18
0
gboolean
gdk_spawn_command_line_on_screen (GdkScreen    *screen,
                                  const gchar  *command_line,
                                  GError      **error)
{
    gchar    **argv = NULL;
    gboolean   retval;

    g_return_val_if_fail (command_line != NULL, FALSE);

    if (!g_shell_parse_argv (command_line,
                             NULL, &argv,
                             error))
        return FALSE;

    retval = gdk_spawn_on_screen (screen,
                                  NULL, argv, NULL,
                                  G_SPAWN_SEARCH_PATH,
                                  NULL, NULL, NULL,
                                  error);
    g_strfreev (argv);

    return retval;
}
static void
thunar_uca_provider_activated (ThunarUcaProvider *uca_provider,
                               GtkAction         *action)
{
  GtkTreeRowReference *row;
  ThunarUcaContext    *uca_context;
  GtkTreePath         *path;
  GtkTreeIter          iter;
  GtkWidget           *dialog;
  GtkWidget           *window;
  gboolean             succeed;
  GSource             *source;
  GError              *error = NULL;
  GList               *files;
  gchar              **argv;
  gchar               *working_directory = NULL;
  gchar               *filename;
  gchar               *label;
  gchar               *uri;
  gint                 argc;
  gint                 pid;

  g_return_if_fail (THUNAR_UCA_IS_PROVIDER (uca_provider));
  g_return_if_fail (GTK_IS_ACTION (action));

  /* check if the row reference is still valid */
  row = g_object_get_qdata (G_OBJECT (action), thunar_uca_row_quark);
  if (G_UNLIKELY (!gtk_tree_row_reference_valid (row)))
    return;

  /* determine the iterator for the item */
  path = gtk_tree_row_reference_get_path (row);
  gtk_tree_model_get_iter (GTK_TREE_MODEL (uca_provider->model), &iter, path);
  gtk_tree_path_free (path);

  /* determine the files and the window for the action */
  uca_context = g_object_get_qdata (G_OBJECT (action), thunar_uca_context_quark);
  window = thunar_uca_context_get_window (uca_context);
  files = thunar_uca_context_get_files (uca_context);

  /* determine the argc/argv for the item */
  succeed = thunar_uca_model_parse_argv (uca_provider->model, &iter, files, &argc, &argv, &error);
  if (G_LIKELY (succeed))
    {
      /* determine the working from the first file */
      if (G_LIKELY (files != NULL))
        {
          /* determine the filename of the first selected file */
          uri = thunarx_file_info_get_uri (files->data);
          filename = g_filename_from_uri (uri, NULL, NULL);
          if (G_LIKELY (filename != NULL))
            {
              /* if this is a folder action, we just use the filename as working directory */
              if (g_object_get_qdata (G_OBJECT (action), thunar_uca_folder_quark) != NULL)
                {
                  working_directory = filename;
                  filename = NULL;
                }
              else
                {
                  working_directory = g_path_get_dirname (filename);
                }
            }
          g_free (filename);
          g_free (uri);
        }

      /* spawn the command on the window's screen */
      succeed = gdk_spawn_on_screen (gtk_widget_get_screen (GTK_WIDGET (window)), working_directory,
                                     argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
                                     NULL, NULL, &pid, &error);

      /* check if we succeed */
      if (G_LIKELY (succeed))
        {
          /* check if we already have a child watch */
          if (G_UNLIKELY (uca_provider->child_watch_id >= 0))
            {
              /* reset the callback function to g_spawn_close_pid() so the plugin can be
               * safely unloaded and the child will still not become a zombie afterwards.
               */
              source = g_main_context_find_source_by_id (NULL, uca_provider->child_watch_id);
              g_source_set_callback (source, (GSourceFunc) g_spawn_close_pid, NULL, NULL);
            }

          /* schedule the new child watch */
          uca_provider->child_watch_id = g_child_watch_add_full (G_PRIORITY_LOW, pid, thunar_uca_provider_child_watch,
                                                                 uca_provider, thunar_uca_provider_child_watch_destroy);

          /* take over ownership of the working directory as child watch path */
          uca_provider->child_watch_path = working_directory;
          working_directory = NULL;
        }

      /* cleanup */
      g_free (working_directory);
      g_strfreev (argv);
    }

  /* present error message to the user */
  if (G_UNLIKELY (!succeed))
    {
      g_object_get (G_OBJECT (action), "label", &label, NULL);
      dialog = gtk_message_dialog_new ((GtkWindow *) window,
                                       GTK_DIALOG_DESTROY_WITH_PARENT
                                       | GTK_DIALOG_MODAL,
                                       GTK_MESSAGE_ERROR,
                                       GTK_BUTTONS_CLOSE,
                                       _("Failed to launch action \"%s\"."), label);
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", error->message);
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
      g_error_free (error);
      g_free (label);
    }
}
void
awn_applet_proxy_execute (AwnAppletProxy *proxy)
{
  AwnAppletProxyPrivate *priv;
  GdkScreen             *screen;
  GError                *error = NULL;
  gint                   panel_id = AWN_PANEL_ID_DEFAULT;
  gchar                 *exec;
  gchar                **argv = NULL;
  GPid                   pid;
  GSpawnFlags            flags = G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD;

  priv = AWN_APPLET_PROXY_GET_PRIVATE (proxy);

  priv->size_req_initialized = FALSE;
  gtk_widget_realize (GTK_WIDGET (proxy));

  /* FIXME: update tooltip with name of the applet?! */

  /* Load the applet */
  screen = gtk_widget_get_screen (GTK_WIDGET (proxy));
  gint64 socket_id = (gint64) gtk_socket_get_id (GTK_SOCKET (proxy));

  g_object_get (G_OBJECT (gtk_widget_get_toplevel (GTK_WIDGET (proxy))),
                "panel-id", &panel_id, NULL);

  if (g_getenv ("AWN_APPLET_GDB"))
  {
    exec = g_strdup_printf (DEBUG_APPLET_EXEC, priv->path, priv->uid,
                            socket_id, panel_id);
  }
  else
  {
    exec = g_strdup_printf (APPLET_EXEC, priv->path, priv->uid, 
                            socket_id, panel_id);
  }

  g_shell_parse_argv (exec, NULL, &argv, &error);
  g_warn_if_fail (error == NULL);

  if (gdk_spawn_on_screen (
        screen, NULL, argv, NULL, flags, NULL, NULL, &pid, &error))
  {
    priv->running = TRUE;
    g_child_watch_add(pid, on_child_exit, proxy);

    gchar *desktop = g_path_get_basename (priv->path);
    g_debug ("Spawned awn-applet[%d] for \"%s\", UID: %s, XID: %" G_GINT64_FORMAT,
       pid, desktop, priv->uid, socket_id);
    g_free (desktop);
  }
  else
  {
    g_warning ("Unable to load applet %s: %s", priv->path, error->message);
    g_error_free (error);
    g_signal_emit (proxy, _proxy_signals[APPLET_CRASHED], 0);
  }

  g_strfreev (argv);
  g_free (exec);
}