diff --git a/core/os/os.h b/core/os/os.h
index b70516436e9..d6778c990a3 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -205,6 +205,7 @@ public:
virtual String get_environment(const String &p_var) const = 0;
virtual void set_environment(const String &p_var, const String &p_value) const = 0;
virtual void unset_environment(const String &p_var) const = 0;
+ virtual void load_shell_environment() const {}
virtual String get_name() const = 0;
virtual String get_identifier() const;
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 1cd6209e77d..3e31806728d 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -373,6 +373,10 @@
Forces a [i]constant[/i] delay between frames in the main loop (in milliseconds). In most situations, [member application/run/max_fps] should be preferred as an FPS limiter as it's more precise.
This setting can be overridden using the [code]--frame-delay <ms;>[/code] command line argument.
+
+ If [code]true[/code], loads the default shell and copies environment variables set by the shell startup scripts to the app environment.
+ [b]Note:[/b] This setting is implemented on macOS for non-sandboxed applications only.
+
If [code]true[/code], enables low-processor usage mode. When enabled, the engine takes longer to redraw, but only redraws the screen if necessary. This may lower power consumption, and is intended for editors or mobile applications. For most games, because the screen needs to be redrawn every frame, it is recommended to keep this setting disabled.
diff --git a/main/main.cpp b/main/main.cpp
index 22b3ce4589c..310494724ad 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1037,6 +1037,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Vector breakpoints;
bool delta_smoothing_override = false;
+ bool load_shell_env = false;
String default_renderer = "";
String default_renderer_mobile = "";
@@ -2642,12 +2643,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true);
OS::get_singleton()->_allow_layered = GLOBAL_DEF_RST("display/window/per_pixel_transparency/allowed", false);
+ load_shell_env = GLOBAL_DEF("application/run/load_shell_environment", false);
+
#ifdef TOOLS_ENABLED
if (editor || project_manager) {
// The editor and project manager always detect and use hiDPI if needed.
OS::get_singleton()->_allow_hidpi = true;
+ load_shell_env = true;
}
#endif
+ if (load_shell_env) {
+ OS::get_singleton()->load_shell_environment();
+ }
if (separate_thread_render == -1) {
separate_thread_render = (int)GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE) == OS::RENDER_SEPARATE_THREAD;
diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h
index f222610a1f6..dac11f26ebd 100644
--- a/platform/macos/os_macos.h
+++ b/platform/macos/os_macos.h
@@ -78,6 +78,8 @@ public:
virtual void set_cmdline_platform_args(const List &p_args);
virtual List get_cmdline_platform_args() const override;
+ virtual void load_shell_environment() const override;
+
virtual String get_name() const override;
virtual String get_distribution_name() const override;
virtual String get_version() const override;
diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm
index bc8dc88e992..bff0ffe780c 100644
--- a/platform/macos/os_macos.mm
+++ b/platform/macos/os_macos.mm
@@ -238,6 +238,32 @@ List OS_MacOS::get_cmdline_platform_args() const {
return launch_service_args;
}
+void OS_MacOS::load_shell_environment() const {
+ static bool shell_env_loaded = false;
+ if (unlikely(!shell_env_loaded)) {
+ shell_env_loaded = true;
+ if (OS::get_singleton()->has_environment("TERM") || OS::get_singleton()->has_environment("__GODOT_SHELL_ENV_SET")) {
+ return; // Already started from terminal, or other the instance with the shell environment, do nothing.
+ }
+ String pipe;
+ List args;
+ args.push_back("-c");
+ args.push_back(". /etc/zshrc;. /etc/zprofile;. ~/.zshenv;. ~/.zshrc;. ~/.zprofile;env");
+ Error err = OS::get_singleton()->execute("zsh", args, &pipe);
+ if (err == OK) {
+ Vector env_vars = pipe.split("\n");
+ for (const String &E : env_vars) {
+ Vector tags = E.split("=", 2);
+ if (tags.size() != 2 || tags[0] == "SHELL" || tags[0] == "USER" || tags[0] == "COMMAND_MODE" || tags[0] == "TMPDIR" || tags[0] == "TERM_SESSION_ID" || tags[0] == "PWD" || tags[0] == "OLDPWD" || tags[0] == "SHLVL" || tags[0] == "HOME" || tags[0] == "DISPLAY" || tags[0] == "LOGNAME" || tags[0] == "TERM" || tags[0] == "COLORTERM" || tags[0] == "_" || tags[0].begins_with("__CF") || tags[0].begins_with("XPC_") || tags[0].begins_with("__GODOT")) {
+ continue;
+ }
+ OS::get_singleton()->set_environment(tags[0], tags[1]);
+ }
+ }
+ OS::get_singleton()->set_environment("__GODOT_SHELL_ENV_SET", "1");
+ }
+}
+
String OS_MacOS::get_name() const {
return "macOS";
}