[gnome-builder] project-tree: discover terminals on host
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] project-tree: discover terminals on host
- Date: Mon, 6 May 2019 21:18:42 +0000 (UTC)
commit d7df241a568e0037b5c62147a5c752fde1be8a41
Author: Christian Hergert <chergert redhat com>
Date: Mon May 6 14:14:24 2019 -0700
project-tree: discover terminals on host
The project-tree was never really made aware of the sandboxing
that Builder typically exists within. Therefore, searching for
terminals within $PATH isn't sufficient.
This checks the host system for the terminal and then launches
the terminal through our host-system abstractions.
After the fix, we should extract the find_program_in_path() into
an ide_find_program_in_host_path() helper which can be re-used.
Fixes #909
.../project-tree/gbp-project-tree-pane-actions.c | 74 ++++++++++++++--------
1 file changed, 48 insertions(+), 26 deletions(-)
---
diff --git a/src/plugins/project-tree/gbp-project-tree-pane-actions.c
b/src/plugins/project-tree/gbp-project-tree-pane-actions.c
index 8ff256d92..c909068d0 100644
--- a/src/plugins/project-tree/gbp-project-tree-pane-actions.c
+++ b/src/plugins/project-tree/gbp-project-tree-pane-actions.c
@@ -458,12 +458,42 @@ DEFINE_ACTION_HANDLER (open_with_hint, {
NULL, NULL, NULL);
});
+static gchar *
+find_program_in_path (const gchar *program)
+{
+ g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+ g_autoptr(IdeSubprocess) subprocess = NULL;
+
+ if (program == NULL)
+ return NULL;
+
+ launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE |
+ G_SUBPROCESS_FLAGS_STDERR_SILENCE);
+ ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
+ ide_subprocess_launcher_push_argv (launcher, "which");
+ ide_subprocess_launcher_push_argv (launcher, program);
+
+ if ((subprocess = ide_subprocess_launcher_spawn (launcher, NULL, NULL)))
+ {
+ g_autofree gchar *path = NULL;
+
+ if (ide_subprocess_communicate_utf8 (subprocess, NULL, NULL, &path, NULL, NULL))
+ {
+ g_strstrip (path);
+
+ if (!ide_str_empty0 (path))
+ return g_steal_pointer (&path);
+ }
+ }
+
+ return NULL;
+}
+
/* Based on gdesktopappinfo.c in GIO */
static gchar *
find_terminal_executable (void)
{
- gsize i;
- gchar *path = NULL;
+ g_autofree gchar *path = NULL;
g_autoptr(GSettings) terminal_settings = NULL;
g_autofree gchar *gsettings_terminal = NULL;
const gchar *terminals[] = {
@@ -483,17 +513,17 @@ find_terminal_executable (void)
/* This is generally one of the fallback terminals */
terminals[3] = g_getenv ("TERM");
- for (i = 0; i < G_N_ELEMENTS (terminals) && path == NULL; ++i)
+ for (guint i = 0; i < G_N_ELEMENTS (terminals) && path == NULL; ++i)
{
if (terminals[i] != NULL)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- path = g_find_program_in_path (terminals[i]);
+ path = find_program_in_path (terminals[i]);
G_GNUC_END_IGNORE_DEPRECATIONS
}
}
- return path;
+ return g_steal_pointer (&path);
}
static void
@@ -503,10 +533,11 @@ gbp_project_tree_pane_actions_open_in_terminal (GSimpleAction *action,
{
GbpProjectTreePane *self = user_data;
IdeProjectFile *project_file;
+ g_autoptr(IdeSubprocessLauncher) launcher = NULL;
+ g_autoptr(IdeSubprocess) subprocess = NULL;
g_autoptr(GFile) file = NULL;
IdeTreeNode *selected;
g_autofree gchar *terminal_executable = NULL;
- const gchar *argv[] = { NULL, NULL };
g_auto(GStrv) env = NULL;
g_autoptr(GFile) workdir = NULL;
g_autoptr(GError) error = NULL;
@@ -523,34 +554,25 @@ gbp_project_tree_pane_actions_open_in_terminal (GSimpleAction *action,
if (!g_file_is_native (workdir))
{
- g_warning ("Not a native directory, cannot open terminal");
+ g_autofree gchar *uri = g_file_get_uri (workdir);
+ g_warning ("Not a native file, cannot open terminal here: %s", uri);
return;
}
terminal_executable = find_terminal_executable ();
- argv[0] = terminal_executable;
g_return_if_fail (terminal_executable != NULL);
- env = g_get_environ ();
-
- {
- /*
- * Overwrite SHELL to the users default shell.
- * Failure to do so typically results in /bin/sh being used.
- */
- g_autofree gchar *shell = vte_get_user_shell ();
- env = g_environ_setenv (env, "SHELL", shell, TRUE);
- }
+ /* Launch the terminal, on the host */
+ launcher = ide_subprocess_launcher_new (0);
+ ide_subprocess_launcher_set_run_on_host (launcher, TRUE);
+ ide_subprocess_launcher_set_clear_env (launcher, FALSE);
+ ide_subprocess_launcher_set_cwd (launcher, g_file_peek_path (workdir));
+ ide_subprocess_launcher_push_argv (launcher, terminal_executable);
- /* Can't use GdkAppLaunchContext as
- * we cannot set the working directory.
- */
- if (!g_spawn_async (g_file_peek_path (workdir),
- (gchar **)argv, env,
- G_SPAWN_STDERR_TO_DEV_NULL,
- NULL, NULL, NULL, &error))
- /* translators: %s is replaced with the error message */
+ if (!(subprocess = ide_subprocess_launcher_spawn (launcher, NULL, &error)))
g_warning ("Failed to spawn terminal: %s", error->message);
+ else
+ ide_subprocess_wait_async (subprocess, NULL, NULL, NULL);
}
static const GActionEntry entries[] = {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]