Skip to content

Commit

Permalink
eel-gnome-extensions.c: Support whitespace in execution commands
Browse files Browse the repository at this point in the history
A default command line with whitespace will fail to execute, either
silently or with a visible error, depending on the trigger. In addition,
some actions would default to launching with GNOME Terminal even when
another terminal was configured as the default. This adds a default list
of terminals, proper switches for execution, and a boolean for whether
or not the command line sequence needs to be escaped.

Closes #2571
  • Loading branch information
rcalixte committed Jun 3, 2024
1 parent 4e7196b commit 87498e1
Showing 1 changed file with 60 additions and 47 deletions.
107 changes: 60 additions & 47 deletions eel/eel-gnome-extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,78 +33,91 @@
#include <gtk/gtk.h>

/* Adapted from gio - gdesktopappinfo.c - prepend_terminal_to_vector */
static const struct {
const char *exec;
const char *exec_arg;
const gboolean escape_command;
} known_terminals[] = {
{ "alacritty", "-e", TRUE },
{ "color-xterm", "-e", TRUE },
{ "dtterm", "-e", TRUE },
{ "gnome-terminal", "--", TRUE },
{ "kgx", "-e", TRUE },
{ "kitty", "--", FALSE },
{ "konsole", "-e", TRUE },
{ "lxterminal", "-e", TRUE },
{ "mate-terminal", "-x", TRUE },
{ "nxterm", "-e", TRUE },
{ "rxvt", "-e", TRUE },
{ "sakura", "-x", TRUE },
{ "st", "-e", TRUE },
{ "terminator", "-x", TRUE },
{ "terminology", "-e", TRUE },
{ "tilix", "-e", TRUE },
{ "wezterm", "--", TRUE },
{ "xfce4-terminal", "-x", FALSE },
{ "xterm", "-e", TRUE },
};

static char *
prepend_terminal_to_command_line (const char *command_line)
{
GSettings *settings;
gchar *prefix = NULL;
GString *prefix = NULL;
gchar *terminal = NULL;
gchar *ret = NULL;
GString *escaped_command_line = NULL;
gint i;

g_return_val_if_fail (command_line != NULL, g_strdup (command_line));

settings = g_settings_new ("org.cinnamon.desktop.default-applications.terminal");
terminal = g_settings_get_string (settings, "exec");

if (terminal != NULL) {
gchar *term_path = NULL;

term_path = g_find_program_in_path (terminal);

if (term_path != NULL) {
gchar *exec_flag = NULL;
for (i = 0; i < G_N_ELEMENTS (known_terminals); i++) {
if (g_strcmp0 (known_terminals[i].exec, terminal) == 0) {
prefix = g_string_new (g_strdup_printf ("%s %s", known_terminals[i].exec, known_terminals[i].exec_arg));
break;
}
}
}

exec_flag = g_settings_get_string (settings, "exec-arg");
if (prefix == NULL) {
gchar *term_path = NULL;

if (exec_flag == NULL) {
prefix = g_strdup (term_path);
} else {
prefix = g_strdup_printf ("%s %s", term_path, exec_flag);
for (i = 0; i < G_N_ELEMENTS (known_terminals); i++) {
term_path = g_find_program_in_path (known_terminals[i].exec);
if (term_path != NULL) {
prefix = g_string_new (g_strdup_printf ("%s %s", known_terminals[i].exec, known_terminals[i].exec_arg));
break;
}

g_free (exec_flag);
}

g_free (term_path);
}

g_object_unref (settings);
g_free (terminal);

if (prefix == NULL) {
gchar *check = NULL;

check = g_find_program_in_path ("gnome-terminal");
if (check != NULL) {
/* Note that gnome-terminal takes -x and
* as -e in gnome-terminal is broken we use that.
20201114 - There looks to be an issue with -x now with gnome-terminal
and -- is now the recommended option */
prefix = g_strdup_printf ("gnome-terminal --");
} else {
check = g_find_program_in_path ("nxterm");

if (check == NULL)
check = g_find_program_in_path ("color-xterm");
if (check == NULL)
check = g_find_program_in_path ("rxvt");
if (check == NULL)
check = g_find_program_in_path ("xterm");
if (check == NULL)
check = g_find_program_in_path ("dtterm");
if (check == NULL) {
check = g_strdup ("xterm");
g_warning ("couldn't find a terminal, falling back to xterm");
// Escape space characters in the command line if needed
if (prefix != NULL && known_terminals[i].escape_command) {
escaped_command_line = g_string_new("");
for (const gchar *p = command_line; *p != '\0'; p++) {
if (*p == ' ') {
g_string_append(escaped_command_line, "\\ ");
} else {
g_string_append_c(escaped_command_line, *p);
}

prefix = g_strdup_printf ("%s -e", check);
}
}

g_free (check);
if (escaped_command_line == NULL) {
escaped_command_line = g_string_new (command_line);
}

ret = g_strdup_printf ("%s %s", prefix, command_line);
g_free (prefix);
g_object_unref (settings);

ret = g_strdup_printf ("%s %s", prefix->str, escaped_command_line->str);
g_string_free (prefix, TRUE);
g_free (terminal);
g_string_free (escaped_command_line, TRUE);

return ret;
}
Expand Down

0 comments on commit 87498e1

Please sign in to comment.