[gnome-terminal] screen: Use async spawning



commit d4e25a57a8fa9b1dae4b18a8a36735775f9bfd77
Author: Christian Persch <chpe gnome org>
Date:   Fri Nov 25 22:18:53 2016 +0100

    screen: Use async spawning
    
    Use the new async spawning functions from vte.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=772354

 src/terminal-screen.c |  106 ++++++++++++++++++++++++++++--------------------
 1 files changed, 62 insertions(+), 44 deletions(-)
---
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index 9a0b450..06f5db2 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -63,6 +63,8 @@
 
 #define URL_MATCH_CURSOR  (GDK_HAND2)
 
+#define SPAWN_TIMEOUT (30 * 1000 /* 30s */)
+
 typedef struct {
   int *fd_list;
   int fd_list_len;
@@ -1346,6 +1348,50 @@ terminal_screen_child_setup (FDSetupData *data)
   }
 }
 
+static void
+spawn_result_cb (VteTerminal *terminal,
+                 GPid pid,
+                 GError *error,
+                 gpointer user_data)
+{
+  TerminalScreen *screen;
+  TerminalScreenPrivate *priv;
+
+  /* Terminal was destroyed while the spawn operation was in progress; nothing to do. */
+  if (terminal == NULL)
+    return;
+
+  screen = TERMINAL_SCREEN (terminal);
+  priv = screen->priv;
+
+  priv->child_pid = pid;
+
+  if (error) {
+    GtkWidget *info_bar;
+
+    vte_terminal_set_pty (terminal, NULL);
+    info_bar = terminal_info_bar_new (GTK_MESSAGE_ERROR,
+                                      _("_Profile Preferences"), RESPONSE_EDIT_PROFILE,
+                                      _("_Relaunch"), RESPONSE_RELAUNCH,
+                                      NULL);
+    terminal_info_bar_format_text (TERMINAL_INFO_BAR (info_bar),
+                                   _("There was an error creating the child process for this terminal"));
+    terminal_info_bar_format_text (TERMINAL_INFO_BAR (info_bar),
+                                   "%s", error->message);
+    g_signal_connect (info_bar, "response",
+                      G_CALLBACK (info_bar_response_cb), screen);
+
+    gtk_widget_set_halign (info_bar, GTK_ALIGN_FILL);
+    gtk_widget_set_valign (info_bar, GTK_ALIGN_START);
+    gtk_overlay_add_overlay (GTK_OVERLAY (terminal_screen_container_get_from_screen (screen)),
+                             info_bar);
+    gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL);
+    gtk_widget_show (info_bar);
+
+    return;
+  }
+}
+
 static gboolean
 terminal_screen_do_exec (TerminalScreen *screen,
                          FDSetupData    *data /* adopting */,
@@ -1356,13 +1402,11 @@ terminal_screen_do_exec (TerminalScreen *screen,
   GSettings *profile;
   char **env, **argv;
   char *shell = NULL;
-  GError *err = NULL;
   const char *working_dir;
   VtePtyFlags pty_flags = VTE_PTY_DEFAULT;
   GSpawnFlags spawn_flags = G_SPAWN_SEARCH_PATH_FROM_ENVP |
                             VTE_SPAWN_NO_PARENT_ENVV;
-  GPid pid;
-  gboolean result = FALSE;
+  GCancellable *cancellable = NULL;
 
   if (priv->child_pid != -1) {
     g_set_error_literal (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
@@ -1387,53 +1431,27 @@ terminal_screen_do_exec (TerminalScreen *screen,
   env = get_child_environment (screen, working_dir, &shell);
 
   argv = NULL;
-  if (!get_child_command (screen, shell, &spawn_flags, &argv, &err) ||
-      !vte_terminal_spawn_sync (terminal,
-                                pty_flags,
-                                working_dir,
-                                argv,
-                                env,
-                                spawn_flags,
-                                (GSpawnChildSetupFunc) (data ? terminal_screen_child_setup : NULL), 
-                                data,
-                                &pid,
-                                NULL /* cancellable */,
-                                &err)) {
-    GtkWidget *info_bar;
-
-    info_bar = terminal_info_bar_new (GTK_MESSAGE_ERROR,
-                                      _("_Profile Preferences"), RESPONSE_EDIT_PROFILE,
-                                      _("_Relaunch"), RESPONSE_RELAUNCH,
-                                      NULL);
-    terminal_info_bar_format_text (TERMINAL_INFO_BAR (info_bar),
-                                   _("There was an error creating the child process for this terminal"));
-    terminal_info_bar_format_text (TERMINAL_INFO_BAR (info_bar),
-                                   "%s", err->message);
-    g_signal_connect (info_bar, "response",
-                      G_CALLBACK (info_bar_response_cb), screen);
-
-    gtk_widget_set_halign (info_bar, GTK_ALIGN_FILL);
-    gtk_widget_set_valign (info_bar, GTK_ALIGN_START);
-    gtk_overlay_add_overlay (GTK_OVERLAY (terminal_screen_container_get_from_screen (screen)),
-                             info_bar);
-    gtk_info_bar_set_default_response (GTK_INFO_BAR (info_bar), GTK_RESPONSE_CANCEL);
-    gtk_widget_show (info_bar);
-
-    g_propagate_error (error, err);
-    goto out;
-  }
-
-  priv->child_pid = pid;
+  if (!get_child_command (screen, shell, &spawn_flags, &argv, error))
+    return FALSE;
 
-  result = TRUE;
+  vte_terminal_spawn_async (terminal,
+                            pty_flags,
+                            working_dir,
+                            argv,
+                            env,
+                            spawn_flags,
+                            (GSpawnChildSetupFunc) (data ? terminal_screen_child_setup : NULL),
+                            data,
+                            (GDestroyNotify) (data ? free_fd_setup_data : NULL),
+                            SPAWN_TIMEOUT,
+                            cancellable,
+                            spawn_result_cb, NULL);
 
-out:
   g_free (shell);
   g_strfreev (argv);
   g_strfreev (env);
-  free_fd_setup_data (data);
 
-  return result;
+  return TRUE; /* can't report any more errors since they only occur async */
 }
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]