[gnome-builder] terminal: add support for terminals in build environment



commit efe54baf35828639cd04385c76df67c3797e4e8e
Author: Christian Hergert <chergert redhat com>
Date:   Tue Feb 21 18:01:35 2017 -0800

    terminal: add support for terminals in build environment
    
    With ctrl+alt+shift+t you can get a terminal that will be executed within
    the build system environment. This may be flatpak, jhbuild, etc.

 libide/keybindings/ide-shortcuts-window.ui       |   14 +++++++
 plugins/terminal/gb-terminal-application-addin.c |    8 ++++-
 plugins/terminal/gb-terminal-view-private.h      |    6 +++
 plugins/terminal/gb-terminal-view.c              |   40 ++++++++++++++++++---
 plugins/terminal/gb-terminal-workbench-addin.c   |   41 ++++++++++++++++-----
 5 files changed, 92 insertions(+), 17 deletions(-)
---
diff --git a/libide/keybindings/ide-shortcuts-window.ui b/libide/keybindings/ide-shortcuts-window.ui
index 994838a..69a236e 100644
--- a/libide/keybindings/ide-shortcuts-window.ui
+++ b/libide/keybindings/ide-shortcuts-window.ui
@@ -43,6 +43,13 @@
             <child>
               <object class="GtkShortcutsShortcut">
                 <property name="visible">true</property>
+                <property name="title" translatable="yes" context="shortcut window">Terminal in Build 
Runtime</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;alt&gt;&lt;shift&gt;t</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">true</property>
                 <property name="title" translatable="yes" context="shortcut window">Keyboard 
Shortcuts</property>
                 <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;question</property>
               </object>
@@ -474,6 +481,13 @@
             <child>
               <object class="GtkShortcutsShortcut">
                 <property name="visible">true</property>
+                <property name="title" translatable="yes" context="shortcut window">Terminal in Build 
Runtime</property>
+                <property name="accelerator">&lt;ctrl&gt;&lt;alt&gt;&lt;shift&gt;t</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkShortcutsShortcut">
+                <property name="visible">true</property>
                 <property name="title" translatable="yes" context="shortcut window">Keyboard 
Shortcuts</property>
                 <property name="accelerator">&lt;ctrl&gt;&lt;shift&gt;question</property>
               </object>
diff --git a/plugins/terminal/gb-terminal-application-addin.c 
b/plugins/terminal/gb-terminal-application-addin.c
index 9467ce3..9729098 100644
--- a/plugins/terminal/gb-terminal-application-addin.c
+++ b/plugins/terminal/gb-terminal-application-addin.c
@@ -36,12 +36,17 @@ gb_terminal_application_addin_load (IdeApplicationAddin *addin,
                                     IdeApplication      *application)
 {
   const gchar *new_terminal_accels[] = { "<ctrl><shift>t", NULL };
+  const gchar *new_terminal_in_runtime_accels[] = { "<ctrl><alt><shift>t", NULL };
 
   g_assert (GB_IS_TERMINAL_APPLICATION_ADDIN (addin));
   g_assert (IDE_IS_APPLICATION (application));
 
-  gtk_application_set_accels_for_action (GTK_APPLICATION (application), "win.new-terminal",
+  gtk_application_set_accels_for_action (GTK_APPLICATION (application),
+                                         "win.new-terminal",
                                          new_terminal_accels);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (application),
+                                         "win.new-terminal-in-runtime",
+                                         new_terminal_in_runtime_accels);
 }
 
 static void
@@ -54,6 +59,7 @@ gb_terminal_application_addin_unload (IdeApplicationAddin *addin,
   g_assert (IDE_IS_APPLICATION (application));
 
   gtk_application_set_accels_for_action (GTK_APPLICATION (application), "win.new-terminal", empty_accels);
+  gtk_application_set_accels_for_action (GTK_APPLICATION (application), "win.new-terminal-in-runtime", 
empty_accels);
 }
 
 static void
diff --git a/plugins/terminal/gb-terminal-view-private.h b/plugins/terminal/gb-terminal-view-private.h
index a615d37..aa88932 100644
--- a/plugins/terminal/gb-terminal-view-private.h
+++ b/plugins/terminal/gb-terminal-view-private.h
@@ -32,6 +32,12 @@ struct _GbTerminalView
 {
   IdeLayoutView        parent_instance;
 
+  /*
+   * If we are spawning a process in a runtime instead of the
+   * host, then we will have a runtime pointer here.
+   */
+  IdeRuntime          *runtime;
+
   GtkOverlay          *terminal_overlay_top;
   GtkOverlay          *terminal_overlay_bottom;
 
diff --git a/plugins/terminal/gb-terminal-view.c b/plugins/terminal/gb-terminal-view.c
index 5243339..2e0cb00 100644
--- a/plugins/terminal/gb-terminal-view.c
+++ b/plugins/terminal/gb-terminal-view.c
@@ -42,6 +42,7 @@ enum {
   PROP_FONT_NAME,
   PROP_MANAGE_SPAWN,
   PROP_PTY,
+  PROP_RUNTIME,
   LAST_PROP
 };
 
@@ -79,8 +80,9 @@ static void gb_terminal_respawn               (GbTerminalView *self,
                                                VteTerminal    *terminal);
 
 static gchar *
-gb_terminal_view_discover_shell (GCancellable  *cancellable,
-                                 GError       **error)
+gb_terminal_view_discover_shell (GbTerminalView  *self,
+                                 GCancellable    *cancellable,
+                                 GError         **error)
 {
   g_autoptr(IdeSubprocessLauncher) launcher = NULL;
   g_autoptr(IdeSubprocess) subprocess = NULL;
@@ -99,7 +101,12 @@ gb_terminal_view_discover_shell (GCancellable  *cancellable,
   if (!g_shell_parse_argv (command, NULL, &argv, error))
     return NULL;
 
-  launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
+  if (self->runtime != NULL)
+    launcher = ide_runtime_create_launcher (self->runtime, NULL);
+
+  if (launcher == NULL)
+    launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
+
   ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
   ide_subprocess_launcher_set_clear_env (launcher, FALSE);
   ide_subprocess_launcher_set_cwd (launcher, g_get_home_dir ());
@@ -221,7 +228,7 @@ gb_terminal_respawn (GbTerminalView *self,
   workdir = ide_vcs_get_working_directory (vcs);
   workpath = g_file_get_path (workdir);
 
-  shell = gb_terminal_view_discover_shell (NULL, &error);
+  shell = gb_terminal_view_discover_shell (self, NULL, &error);
 
   if (shell == NULL)
     {
@@ -256,8 +263,13 @@ gb_terminal_respawn (GbTerminalView *self,
   if (-1 == (stdout_fd = dup (tty_fd)) || -1 == (stderr_fd = dup (tty_fd)))
     IDE_GOTO (failure);
 
-  /* XXX: It would be nice to allow using the runtimes launcher */
-  launcher = ide_subprocess_launcher_new (0);
+  if (self->runtime != NULL)
+    launcher = ide_runtime_create_launcher (self->runtime, NULL);
+
+  if (launcher == NULL)
+    launcher = ide_subprocess_launcher_new (0);
+
+  ide_subprocess_launcher_set_flags (launcher, 0);
   ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
   ide_subprocess_launcher_set_clear_env (launcher, FALSE);
   ide_subprocess_launcher_set_cwd (launcher, workpath);
@@ -702,6 +714,7 @@ gb_terminal_view_finalize (GObject *object)
   g_clear_object (&self->save_as_file_bottom);
   g_clear_pointer (&self->selection_buffer, g_free);
   g_clear_object (&self->pty);
+  g_clear_object (&self->runtime);
 
   G_OBJECT_CLASS (gb_terminal_view_parent_class)->finalize (object);
 }
@@ -724,6 +737,10 @@ gb_terminal_view_get_property (GObject    *object,
       g_value_set_object (value, self->pty);
       break;
 
+    case PROP_RUNTIME:
+      g_value_set_object (value, self->runtime);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -751,6 +768,10 @@ gb_terminal_view_set_property (GObject      *object,
       self->pty = g_value_dup_object (value);
       break;
 
+    case PROP_RUNTIME:
+      self->runtime = g_value_dup_object (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     }
@@ -808,6 +829,13 @@ gb_terminal_view_class_init (GbTerminalViewClass *klass)
                          VTE_TYPE_PTY,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
 
+  properties [PROP_RUNTIME] =
+    g_param_spec_object ("runtime",
+                         "Runtime",
+                         "The runtime to use for spawning",
+                         IDE_TYPE_RUNTIME,
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_properties (object_class, LAST_PROP, properties);
 
   g_type_ensure (GB_TYPE_TERMINAL);
diff --git a/plugins/terminal/gb-terminal-workbench-addin.c b/plugins/terminal/gb-terminal-workbench-addin.c
index efcb4c3..9c88900 100644
--- a/plugins/terminal/gb-terminal-workbench-addin.c
+++ b/plugins/terminal/gb-terminal-workbench-addin.c
@@ -49,21 +49,43 @@ G_DEFINE_TYPE_EXTENDED (GbTerminalWorkbenchAddin,
                         0,
                         G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
 
+static IdeRuntime *
+find_runtime (IdeWorkbench *workbench)
+{
+  IdeContext *context;
+  IdeConfigurationManager *config_manager;
+  IdeConfiguration *config;
+
+  g_assert (IDE_IS_WORKBENCH (workbench));
+
+  context = ide_workbench_get_context (workbench);
+  config_manager = ide_context_get_configuration_manager (context);
+  config = ide_configuration_manager_get_current (config_manager);
+
+  return ide_configuration_get_runtime (config);
+}
+
 static void
-new_terminal_activate_cb (GSimpleAction            *action,
-                          GVariant                 *param,
-                          GbTerminalWorkbenchAddin *self)
+new_terminal_activate (GSimpleAction *action,
+                       GVariant      *param,
+                       gpointer       user_data)
 {
+  GbTerminalWorkbenchAddin *self = user_data;
   GbTerminalView *view;
   IdePerspective *perspective;
+  IdeRuntime *runtime = NULL;
 
   g_assert (G_IS_SIMPLE_ACTION (action));
   g_assert (GB_IS_TERMINAL_WORKBENCH_ADDIN (self));
 
+  if (g_strcmp0 (g_action_get_name (G_ACTION (action)), "new-terminal-in-runtime") == 0)
+    runtime = find_runtime (self->workbench);
+
   perspective = ide_workbench_get_perspective_by_name (self->workbench, "editor");
   ide_workbench_set_visible_perspective (self->workbench, perspective);
 
   view = g_object_new (GB_TYPE_TERMINAL_VIEW,
+                       "runtime", runtime,
                        "visible", TRUE,
                        NULL);
   gtk_container_add (GTK_CONTAINER (perspective), GTK_WIDGET (view));
@@ -160,6 +182,10 @@ gb_terminal_workbench_addin_load (IdeWorkbenchAddin *addin,
   IdeContext *context;
   IdeRunManager *run_manager;
   g_autoptr(GSimpleAction) action = NULL;
+  static const GActionEntry actions[] = {
+    { "new-terminal", new_terminal_activate },
+    { "new-terminal-in-runtime", new_terminal_activate },
+  };
 
   g_assert (GB_IS_TERMINAL_WORKBENCH_ADDIN (self));
   g_assert (IDE_IS_WORKBENCH (workbench));
@@ -168,13 +194,7 @@ gb_terminal_workbench_addin_load (IdeWorkbenchAddin *addin,
 
   ide_set_weak_pointer (&self->workbench, workbench);
 
-  action = g_simple_action_new ("new-terminal", NULL);
-  g_signal_connect_object (action,
-                           "activate",
-                           G_CALLBACK (new_terminal_activate_cb),
-                           self,
-                           0);
-  g_action_map_add_action (G_ACTION_MAP (workbench), G_ACTION (action));
+  g_action_map_add_action_entries (G_ACTION_MAP (workbench), actions, G_N_ELEMENTS (actions), self);
 
   if (self->panel_terminal == NULL)
     {
@@ -218,6 +238,7 @@ gb_terminal_workbench_addin_unload (IdeWorkbenchAddin *addin,
   g_assert (GB_IS_TERMINAL_WORKBENCH_ADDIN (self));
 
   g_action_map_remove_action (G_ACTION_MAP (self->workbench), "new-terminal");
+  g_action_map_remove_action (G_ACTION_MAP (self->workbench), "new-terminal-in-runtime");
 
   if (self->panel_dock_widget != NULL)
     {


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