[gnome-terminal] nautilus: Use the private terminal D-Bus API to create the terminal



commit 8e364f5722e786a2598908f2f2cae6948ab53aaf
Author: Christian Persch <chpe gnome org>
Date:   Mon Apr 15 15:30:26 2013 +0200

    nautilus: Use the private terminal D-Bus API to create the terminal

 src/Makefile.am         |  12 ++-
 src/terminal-nautilus.c | 221 ++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 187 insertions(+), 46 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 3fffa9a..b45974a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -242,16 +242,24 @@ gnome_terminal_LDADD = \
 # Nautilus extension
 
 libterminal_nautilus_la_SOURCES = \
+       terminal-client-utils.c \
+       terminal-client-utils.h \
+       terminal-defines.h \
        terminal-i18n.c \
        terminal-i18n.h \
        terminal-nautilus.c \
        $(NULL)
 
+nodist_libterminal_nautilus_la_SOURCES = \
+       terminal-gdbus-generated.c \
+       terminal-gdbus-generated.h \
+       terminal-type-builtins.c \
+       terminal-type-builtins.h \
+       $(NULL)
+
 libterminal_nautilus_la_CPPFLAGS = \
        -DTERMINAL_COMPILATION \
-       -DTERM_DATADIR="\"$(datadir)\"" \
        -DTERM_LOCALEDIR="\"$(datadir)/locale\"" \
-       -DTERM_BINDIR="\"$(bindir)\"" \
        -DGDK_MULTIHEAD_SAFE \
        $(AM_CPPFLAGS)
 
diff --git a/src/terminal-nautilus.c b/src/terminal-nautilus.c
index 346029d..4048a94 100644
--- a/src/terminal-nautilus.c
+++ b/src/terminal-nautilus.c
@@ -33,6 +33,9 @@
 #include <string.h>
 
 #include "terminal-i18n.h"
+#include "terminal-client-utils.h"
+#include "terminal-defines.h"
+#include "terminal-gdbus-generated.h"
 
 /* Nautilus extension class */
 
@@ -222,20 +225,21 @@ parse_sftp_uri (GFile *file,
   g_free (save);
 }
 
-static void
-append_remote_ssh_command (char ***argvp,
-                           int *argcp,
-                           const char *uri,
-                           gboolean run_in_mc)
+static char **
+ssh_argv (const char *uri,
+          gboolean run_in_mc,
+          int *argcp)
 {
   GFile *file;
-  char **argv = *argvp;
-  int argc = *argcp;
+  char **argv;
+  int argc;
   char *host_name, *path, *user_name, *unescaped_path, *quoted_path;
   guint host_port;
 
   g_assert (uri != NULL);
 
+  argv = g_new0 (char *, 8);
+  argc = 0;
   argv[argc++] = g_strdup ("ssh");
 
   file = g_file_new_for_uri (uri);
@@ -271,6 +275,20 @@ append_remote_ssh_command (char ***argvp,
   g_free (quoted_path);
 
   *argcp = argc;
+  return argv;
+}
+
+static char **
+mc_argv (int *argcp)
+{
+  char **argv;
+
+  argv = g_new (char *, 2);
+  argv[0] = g_strdup ("mc");
+  argv[1] = NULL;
+
+  *argcp = 1;
+  return argv;
 }
 
 static gboolean
@@ -301,6 +319,146 @@ uri_has_local_path (const char *uri)
 
 /* Nautilus menu item class */
 
+typedef struct {
+  TerminalNautilus *nautilus;
+  guint32 timestamp;
+  char *path;
+  char *uri;
+  char *display;
+  TerminalFileInfo info;
+  gboolean remote;
+  gboolean run_in_mc;
+} ExecData;
+
+static void
+exec_data_free (ExecData *data)
+{
+  g_object_unref (data->nautilus);
+  g_free (data->path);
+  g_free (data->uri);
+  g_free (data->display);
+
+  g_free (data);
+}
+
+/* FIXME: make this async */
+static gboolean
+create_terminal (ExecData *data /* transfer full */)
+{
+  TerminalFactory *factory;
+  TerminalReceiver *receiver;
+  GError *error = NULL;
+  GVariantBuilder builder;
+  char *object_path;
+  char startup_id[32];
+  char **argv;
+  int argc;
+
+  factory = terminal_factory_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+                                                     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+                                                     TERMINAL_APPLICATION_ID,
+                                                     TERMINAL_FACTORY_OBJECT_PATH,
+                                                     NULL /* cancellable */,
+                                                     &error);
+  if (factory == NULL) {
+    g_dbus_error_strip_remote_error (error);
+    g_printerr ("Error constructing proxy for %s:%s: %s\n",
+                TERMINAL_APPLICATION_ID, TERMINAL_FACTORY_OBJECT_PATH,
+                error->message);
+    g_error_free (error);
+    exec_data_free (data);
+    return FALSE;
+  }
+
+  g_snprintf (startup_id, sizeof (startup_id), "_TIME%u", data->timestamp);
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+  terminal_client_append_create_instance_options (&builder,
+                                                  data->display,
+                                                  startup_id,
+                                                  NULL /* geometry */,
+                                                  NULL /* role */,
+                                                  NULL /* use default profile */,
+                                                  NULL /* title */,
+                                                  FALSE /* maximised */,
+                                                  FALSE /* fullscreen */);
+
+  if (!terminal_factory_call_create_instance_sync
+         (factory,
+          g_variant_builder_end (&builder),
+          &object_path,
+          NULL /* cancellable */,
+          &error)) {
+    g_dbus_error_strip_remote_error (error);
+    g_printerr ("Error creating terminal: %s\n", error->message);
+    g_error_free (error);
+    g_object_unref (factory);
+    exec_data_free (data);
+    return FALSE;
+  }
+
+  g_object_unref (factory);
+
+  receiver = terminal_receiver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+                                                       G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+                                                       TERMINAL_APPLICATION_ID,
+                                                       object_path,
+                                                       NULL /* cancellable */,
+                                                       &error);
+  if (receiver == NULL) {
+    g_dbus_error_strip_remote_error (error);
+    g_printerr ("Failed to create proxy for terminal: %s\n", error->message);
+    g_error_free (error);
+    g_free (object_path);
+    exec_data_free (data);
+    return FALSE;
+  }
+
+  g_free (object_path);
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+  terminal_client_append_exec_options (&builder,
+                                       data->path,
+                                       TRUE /* shell */);
+
+  if (data->info == FILE_INFO_SFTP &&
+      data->remote) {
+    argv = ssh_argv (data->uri, data->run_in_mc, &argc);
+  } else if (data->run_in_mc) {
+    argv = mc_argv (&argc);
+  } else {
+    argv = NULL; argc = 0;
+  }
+
+  if (!terminal_receiver_call_exec_sync (receiver,
+                                         g_variant_builder_end (&builder),
+                                         g_variant_new_bytestring_array ((const char * const *) argv, argc),
+                                         NULL /* in FD list */,
+                                         NULL /* out FD list */,
+                                         NULL /* cancellable */,
+                                         &error)) {
+    g_dbus_error_strip_remote_error (error);
+    g_printerr ("Error: %s\n", error->message);
+    g_error_free (error);
+    g_strfreev (argv);
+    g_object_unref (receiver);
+    exec_data_free (data);
+    return FALSE;
+  }
+
+  g_strfreev (argv);
+
+  exec_data_free (data);
+
+  g_object_unref (receiver);
+
+  return TRUE;
+}
+
 static void
 terminal_nautilus_menu_item_activate (NautilusMenuItem *item)
 {
@@ -308,8 +466,7 @@ terminal_nautilus_menu_item_activate (NautilusMenuItem *item)
   TerminalNautilus *nautilus = menu_item->nautilus;
   char *uri, *path;
   TerminalFileInfo info;
-  char *argv[16];
-  int argc, i;
+  ExecData *data;
 
   uri = nautilus_file_info_get_activation_uri (menu_item->file_info);
   if (uri == NULL)
@@ -356,41 +513,17 @@ terminal_nautilus_menu_item_activate (NautilusMenuItem *item)
     return;
   }
 
-  argc = 0;
-  argv[argc++] = g_strdup (TERM_BINDIR "/gnome-terminal-client");
-  argv[argc++] = g_strdup ("open");
-
-  argv[argc++] = g_strdup ("--display");
-  argv[argc++] = gdk_screen_make_display_name (menu_item->screen);
-
-  if (path) {
-    argv[argc++] = g_strdup ("--cwd");
-    argv[argc++] = path;
-  }
-
-  if (info == FILE_INFO_SFTP && menu_item->remote_terminal) {
-    argv[argc++] = g_strdup ("--");
-    append_remote_ssh_command ((char ***)&argv, &argc, uri, menu_item->run_in_mc);
-  } else if (menu_item->run_in_mc) {
-    argv[argc++] = g_strdup ("--");
-    argv[argc++] = g_strdup ("mc");
-  }
-
-  argv[argc] = NULL;
-  g_assert (argc < (int) G_N_ELEMENTS (argv));
-
-  g_spawn_async (path,
-                 argv,
-                 NULL /* envv */,
-                 0 /* flags */,
-                 NULL, NULL, /* child setup */
-                 NULL /* pid */,
-                 NULL /* error */);
-
-  for (i = 0; i < argc; ++i)
-    g_free (argv[i]);
-
-  g_free (uri);
+  data = g_new (ExecData, 1);
+  data->nautilus = g_object_ref (nautilus);
+  data->timestamp = gtk_get_current_event_time ();
+  data->path = path;
+  data->uri = uri;
+  data->display = gdk_screen_make_display_name (menu_item->screen);
+  data->info = info;
+  data->remote = menu_item->remote_terminal;
+  data->run_in_mc = menu_item->run_in_mc;
+
+  create_terminal (data);
 }
 
 G_DEFINE_DYNAMIC_TYPE (TerminalNautilusMenuItem, terminal_nautilus_menu_item, NAUTILUS_TYPE_MENU_ITEM)


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