FileSystem dock: Fix open a terminal

The previous implementation of opening a terminal
in the FileSystem dock was causing errors due to the use
of a bash builtin command that does not work outside the shell.

This resulted in the following error messages:

	ERROR: Could not create child process: command
		at: execute (drivers/unix/os_unix.cpp:553)
	ERROR: Could not create child process: command
		at: execute (drivers/unix/os_unix.cpp:553)
	...

To resolve this issue,
+ the command is now executed inside a bash shell,
+ if the `terminal_emulator_flags` editor option is empty,
  the working directory for gnome-terminal and urxvt is now properly set.
This commit is contained in:
Martin Capitanio 2024-02-10 10:25:02 +01:00
parent 907db8eebc
commit 8e8f8e92fb

View file

@ -2128,7 +2128,8 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
terminal_emulators.push_back(terminal_emulator_setting); terminal_emulators.push_back(terminal_emulator_setting);
} }
String arguments = EDITOR_GET("filesystem/external_programs/terminal_emulator_flags"); String flags = EDITOR_GET("filesystem/external_programs/terminal_emulator_flags");
String arguments = flags;
if (arguments.is_empty()) { if (arguments.is_empty()) {
// NOTE: This default value is ignored further below if the terminal executable is `powershell` or `cmd`, // NOTE: This default value is ignored further below if the terminal executable is `powershell` or `cmd`,
// due to these terminals requiring nonstandard syntax to start in a specified folder. // due to these terminals requiring nonstandard syntax to start in a specified folder.
@ -2138,16 +2139,13 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
#ifdef LINUXBSD_ENABLED #ifdef LINUXBSD_ENABLED
String chosen_terminal_emulator; String chosen_terminal_emulator;
for (const String &terminal_emulator : terminal_emulators) { for (const String &terminal_emulator : terminal_emulators) {
String pipe;
List<String> test_args; // Required for `execute()`, as it doesn't accept `Vector<String>`. List<String> test_args; // Required for `execute()`, as it doesn't accept `Vector<String>`.
test_args.push_back("-v"); test_args.push_back("-cr");
test_args.push_back(terminal_emulator); test_args.push_back("command -v " + terminal_emulator);
// Silence command name being printed when found. (stderr is already silenced by `OS::execute()` by default.) const Error err = OS::get_singleton()->execute("bash", test_args, &pipe);
// FIXME: This doesn't appear to silence stdout. // Check if a path to the terminal executable exists.
test_args.push_back(">"); if (err == OK && pipe.contains("/")) {
test_args.push_back("/dev/null");
int exit_code = 0;
const Error err = OS::get_singleton()->execute("command", test_args, nullptr, &exit_code);
if (err == OK && exit_code == EXIT_SUCCESS) {
chosen_terminal_emulator = terminal_emulator; chosen_terminal_emulator = terminal_emulator;
break; break;
} else if (err == ERR_CANT_FORK) { } else if (err == ERR_CANT_FORK) {
@ -2164,8 +2162,14 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
// Prepend default arguments based on the terminal emulator name. // Prepend default arguments based on the terminal emulator name.
// Use `String.ends_with()` so that installations in non-default paths // Use `String.ends_with()` so that installations in non-default paths
// or `/usr/local/bin` are detected correctly. // or `/usr/local/bin` are detected correctly.
if (chosen_terminal_emulator.ends_with("konsole")) { if (flags.is_empty()) {
terminal_emulator_args.push_back("--workdir"); if (chosen_terminal_emulator.ends_with("konsole")) {
terminal_emulator_args.push_back("--workdir");
} else if (chosen_terminal_emulator.ends_with("gnome-terminal")) {
terminal_emulator_args.push_back("--working-directory");
} else if (chosen_terminal_emulator.ends_with("urxvt")) {
terminal_emulator_args.push_back("-cd");
}
} }
#endif #endif