From 8e8f8e92fbc0cbdbacd976121f5db606c9bf6200 Mon Sep 17 00:00:00 2001 From: Martin Capitanio Date: Sat, 10 Feb 2024 10:25:02 +0100 Subject: [PATCH] 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. --- editor/filesystem_dock.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 88bd90be981..dde7ddd32db 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2128,7 +2128,8 @@ void FileSystemDock::_file_option(int p_option, const Vector &p_selected 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()) { // 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. @@ -2138,16 +2139,13 @@ void FileSystemDock::_file_option(int p_option, const Vector &p_selected #ifdef LINUXBSD_ENABLED String chosen_terminal_emulator; for (const String &terminal_emulator : terminal_emulators) { + String pipe; List test_args; // Required for `execute()`, as it doesn't accept `Vector`. - test_args.push_back("-v"); - test_args.push_back(terminal_emulator); - // Silence command name being printed when found. (stderr is already silenced by `OS::execute()` by default.) - // FIXME: This doesn't appear to silence stdout. - test_args.push_back(">"); - 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) { + test_args.push_back("-cr"); + test_args.push_back("command -v " + terminal_emulator); + const Error err = OS::get_singleton()->execute("bash", test_args, &pipe); + // Check if a path to the terminal executable exists. + if (err == OK && pipe.contains("/")) { chosen_terminal_emulator = terminal_emulator; break; } else if (err == ERR_CANT_FORK) { @@ -2164,8 +2162,14 @@ void FileSystemDock::_file_option(int p_option, const Vector &p_selected // Prepend default arguments based on the terminal emulator name. // Use `String.ends_with()` so that installations in non-default paths // or `/usr/local/bin` are detected correctly. - if (chosen_terminal_emulator.ends_with("konsole")) { - terminal_emulator_args.push_back("--workdir"); + if (flags.is_empty()) { + 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