Skip to content

Commit bdc8ef3

Browse files
committed
Merge pull request #81266 from bruvzg/mac_shell_env
[macOS] Add support for loading shell environment from UI apps.
2 parents af32c52 + ee18195 commit bdc8ef3

File tree

5 files changed

+40
-0
lines changed

5 files changed

+40
-0
lines changed

core/os/os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ class OS {
205205
virtual String get_environment(const String &p_var) const = 0;
206206
virtual void set_environment(const String &p_var, const String &p_value) const = 0;
207207
virtual void unset_environment(const String &p_var) const = 0;
208+
virtual void load_shell_environment() const {}
208209

209210
virtual String get_name() const = 0;
210211
virtual String get_identifier() const;

doc/classes/ProjectSettings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@
375375
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.
376376
This setting can be overridden using the [code]--frame-delay <ms;>[/code] command line argument.
377377
</member>
378+
<member name="application/run/load_shell_environment" type="bool" setter="" getter="" default="false">
379+
If [code]true[/code], loads the default shell and copies environment variables set by the shell startup scripts to the app environment.
380+
[b]Note:[/b] This setting is implemented on macOS for non-sandboxed applications only.
381+
</member>
378382
<member name="application/run/low_processor_mode" type="bool" setter="" getter="" default="false">
379383
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.
380384
</member>

main/main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
10371037

10381038
Vector<String> breakpoints;
10391039
bool delta_smoothing_override = false;
1040+
bool load_shell_env = false;
10401041

10411042
String default_renderer = "";
10421043
String default_renderer_mobile = "";
@@ -2642,12 +2643,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
26422643
OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true);
26432644
OS::get_singleton()->_allow_layered = GLOBAL_DEF_RST("display/window/per_pixel_transparency/allowed", false);
26442645

2646+
load_shell_env = GLOBAL_DEF("application/run/load_shell_environment", false);
2647+
26452648
#ifdef TOOLS_ENABLED
26462649
if (editor || project_manager) {
26472650
// The editor and project manager always detect and use hiDPI if needed.
26482651
OS::get_singleton()->_allow_hidpi = true;
2652+
load_shell_env = true;
26492653
}
26502654
#endif
2655+
if (load_shell_env) {
2656+
OS::get_singleton()->load_shell_environment();
2657+
}
26512658

26522659
if (separate_thread_render == -1) {
26532660
separate_thread_render = (int)GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE) == OS::RENDER_SEPARATE_THREAD;

platform/macos/os_macos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class OS_MacOS : public OS_Unix {
7878
virtual void set_cmdline_platform_args(const List<String> &p_args);
7979
virtual List<String> get_cmdline_platform_args() const override;
8080

81+
virtual void load_shell_environment() const override;
82+
8183
virtual String get_name() const override;
8284
virtual String get_distribution_name() const override;
8385
virtual String get_version() const override;

platform/macos/os_macos.mm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,32 @@
238238
return launch_service_args;
239239
}
240240

241+
void OS_MacOS::load_shell_environment() const {
242+
static bool shell_env_loaded = false;
243+
if (unlikely(!shell_env_loaded)) {
244+
shell_env_loaded = true;
245+
if (OS::get_singleton()->has_environment("TERM") || OS::get_singleton()->has_environment("__GODOT_SHELL_ENV_SET")) {
246+
return; // Already started from terminal, or other the instance with the shell environment, do nothing.
247+
}
248+
String pipe;
249+
List<String> args;
250+
args.push_back("-c");
251+
args.push_back(". /etc/zshrc;. /etc/zprofile;. ~/.zshenv;. ~/.zshrc;. ~/.zprofile;env");
252+
Error err = OS::get_singleton()->execute("zsh", args, &pipe);
253+
if (err == OK) {
254+
Vector<String> env_vars = pipe.split("\n");
255+
for (const String &E : env_vars) {
256+
Vector<String> tags = E.split("=", 2);
257+
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")) {
258+
continue;
259+
}
260+
OS::get_singleton()->set_environment(tags[0], tags[1]);
261+
}
262+
}
263+
OS::get_singleton()->set_environment("__GODOT_SHELL_ENV_SET", "1");
264+
}
265+
}
266+
241267
String OS_MacOS::get_name() const {
242268
return "macOS";
243269
}

0 commit comments

Comments
 (0)