Prechádzať zdrojové kódy

[macOS] Add support for loading shell environment from UI apps.

bruvzg 2 rokov pred
rodič
commit
ee181951b6

+ 1 - 0
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;

+ 4 - 0
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.
 		</member>
+		<member name="application/run/load_shell_environment" type="bool" setter="" getter="" default="false">
+			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.
+		</member>
 		<member name="application/run/low_processor_mode" type="bool" setter="" getter="" default="false">
 			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.
 		</member>

+ 7 - 0
main/main.cpp

@@ -1037,6 +1037,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 
 	Vector<String> 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;

+ 2 - 0
platform/macos/os_macos.h

@@ -78,6 +78,8 @@ public:
 	virtual void set_cmdline_platform_args(const List<String> &p_args);
 	virtual List<String> 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;

+ 26 - 0
platform/macos/os_macos.mm

@@ -238,6 +238,32 @@ List<String> 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<String> 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<String> env_vars = pipe.split("\n");
+			for (const String &E : env_vars) {
+				Vector<String> 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";
 }