2
0
Эх сурвалжийг харах

Merge pull request #106134 from stuartcarnie/macos_embedded_followup

macOS: Additional improvements and fixes for embedded window support
Thaddeus Crews 4 сар өмнө
parent
commit
02206f45b7

+ 7 - 6
editor/plugins/game_view_plugin.cpp

@@ -515,11 +515,9 @@ GameView::EmbedAvailability GameView::_get_embed_available() {
 	if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_WINDOW_EMBEDDING)) {
 		return EMBED_NOT_AVAILABLE_FEATURE_NOT_SUPPORTED;
 	}
-#ifndef MACOS_ENABLED
 	if (get_tree()->get_root()->is_embedding_subwindows()) {
 		return EMBED_NOT_AVAILABLE_SINGLE_WINDOW_MODE;
 	}
-#endif
 	String display_driver = GLOBAL_GET("display/display_server/driver");
 	if (display_driver == "headless" || display_driver == "wayland") {
 		return EMBED_NOT_AVAILABLE_PROJECT_DISPLAY_DRIVER;
@@ -835,11 +833,16 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
 	// Remove duplicates/unwanted parameters.
 	List<String>::Element *E = r_arguments.front();
 	List<String>::Element *user_args_element = nullptr;
+	HashSet<String> remove_args({ "--position", "--resolution", "--screen" });
+#ifdef MACOS_ENABLED
+	// macOS requires the embedded display driver.
+	remove_args.insert("--display-driver");
+#endif
 	while (E) {
 		List<String>::Element *N = E->next();
 
-		//For these parameters, we need to also renove the value.
-		if (E->get() == "--position" || E->get() == "--resolution" || E->get() == "--screen") {
+		// For these parameters, we need to also remove the value.
+		if (remove_args.has(E->get())) {
 			r_arguments.erase(E);
 			if (N) {
 				List<String>::Element *V = N->next();
@@ -861,8 +864,6 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
 	N = r_arguments.insert_after(N, itos(DisplayServer::get_singleton()->window_get_native_handle(DisplayServer::WINDOW_HANDLE, get_window()->get_window_id())));
 
 #if MACOS_ENABLED
-	r_arguments.push_back("--display-driver");
-	r_arguments.push_back("embedded");
 	r_arguments.push_back("--embedded");
 #endif
 

+ 5 - 0
main/main.cpp

@@ -287,6 +287,7 @@ bool profile_gpu = false;
 // Constants.
 
 static const String NULL_DISPLAY_DRIVER("headless");
+static const String EMBEDDED_DISPLAY_DRIVER("embedded");
 static const String NULL_AUDIO_DRIVER("Dummy");
 
 // The length of the longest column in the command-line help we should align to
@@ -1397,6 +1398,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 			audio_driver = NULL_AUDIO_DRIVER;
 			display_driver = NULL_DISPLAY_DRIVER;
 
+		} else if (arg == "--embedded") { // Enable embedded mode.
+
+			display_driver = EMBEDDED_DISPLAY_DRIVER;
+
 		} else if (arg == "--log-file") { // write to log file
 
 			if (N) {

+ 14 - 4
platform/macos/editor/embedded_process_macos.h

@@ -33,11 +33,13 @@
 #include "editor/plugins/embedded_process.h"
 
 class DisplayServerMacOS;
+class EmbeddedProcessMacOS;
 
-class LayerHost : public Control {
+class LayerHost final : public Control {
 	GDCLASS(LayerHost, Control);
 
 	ScriptEditorDebugger *script_debugger = nullptr;
+	EmbeddedProcessMacOS *process = nullptr;
 
 	virtual void gui_input(const Ref<InputEvent> &p_event) override;
 
@@ -48,6 +50,8 @@ public:
 	void set_script_debugger(ScriptEditorDebugger *p_debugger) {
 		script_debugger = p_debugger;
 	}
+
+	LayerHost(EmbeddedProcessMacOS *p_process);
 };
 
 class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
@@ -69,9 +73,11 @@ class EmbeddedProcessMacOS final : public EmbeddedProcessBase {
 
 	// Embedded process state.
 
-	/// @brief The current mouse mode of the embedded process.
+	// The last mouse mode sent by the embedded process.
 	DisplayServer::MouseMode mouse_mode = DisplayServer::MOUSE_MODE_VISIBLE;
 
+	// Helper functions.
+
 	void _try_embed_process();
 	void update_embedded_process() const;
 	void _joy_connection_changed(int p_index, bool p_connected) const;
@@ -81,7 +87,9 @@ protected:
 
 public:
 	// MARK: - Message Handlers
+
 	void set_context_id(uint32_t p_context_id);
+	void mouse_set_mode(DisplayServer::MouseMode p_mode);
 
 	uint32_t get_context_id() const { return context_id; }
 	void set_script_debugger(ScriptEditorDebugger *p_debugger) override;
@@ -90,7 +98,7 @@ public:
 		return embedding_state == EmbeddingState::IN_PROGRESS;
 	}
 
-	bool is_embedding_completed() const override {
+	_FORCE_INLINE_ bool is_embedding_completed() const override {
 		return embedding_state == EmbeddingState::COMPLETED;
 	}
 
@@ -103,8 +111,10 @@ public:
 
 	Rect2i get_adjusted_embedded_window_rect(const Rect2i &p_rect) const override;
 
-	void mouse_set_mode(DisplayServer::MouseMode p_mode);
 	_FORCE_INLINE_ LayerHost *get_layer_host() const { return layer_host; }
 
+	// MARK: - Embedded process state
+	_FORCE_INLINE_ DisplayServer::MouseMode get_mouse_mode() const { return mouse_mode; }
+
 	EmbeddedProcessMacOS();
 };

+ 24 - 2
platform/macos/editor/embedded_process_macos.mm

@@ -34,6 +34,8 @@
 
 #include "core/input/input_event_codec.h"
 #include "editor/debugger/script_editor_debugger.h"
+#include "editor/editor_main_screen.h"
+#include "editor/editor_node.h"
 #include "editor/editor_settings.h"
 #include "scene/gui/control.h"
 #include "scene/main/window.h"
@@ -182,12 +184,18 @@ Rect2i EmbeddedProcessMacOS::get_adjusted_embedded_window_rect(const Rect2i &p_r
 }
 
 void EmbeddedProcessMacOS::mouse_set_mode(DisplayServer::MouseMode p_mode) {
+	mouse_mode = p_mode;
+	// If the mouse is anything other than visible, we must ensure the Game view is active and the layer focused.
+	if (mouse_mode != DisplayServer::MOUSE_MODE_VISIBLE) {
+		EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_GAME);
+		layer_host->grab_focus();
+	}
 	DisplayServer::get_singleton()->mouse_set_mode(p_mode);
 }
 
 EmbeddedProcessMacOS::EmbeddedProcessMacOS() :
 		EmbeddedProcessBase() {
-	layer_host = memnew(LayerHost);
+	layer_host = memnew(LayerHost(this));
 	add_child(layer_host);
 	layer_host->set_focus_mode(FOCUS_ALL);
 	layer_host->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
@@ -207,11 +215,22 @@ void LayerHost::_notification(int p_what) {
 			if (script_debugger) {
 				script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_ENTER });
 			}
+			// Temporarily release mouse capture, so we can interact with the editor.
+			DisplayServer *ds = DisplayServer::get_singleton();
+			if (process->get_mouse_mode() != ds->mouse_get_mode()) {
+				// Restore embedded process mouse mode.
+				ds->mouse_set_mode(process->get_mouse_mode());
+			}
 		} break;
 		case NOTIFICATION_FOCUS_EXIT: {
 			if (script_debugger) {
 				script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_MOUSE_EXIT });
 			}
+			// Temporarily set mouse state back to visible, so the user can interact with the editor.
+			DisplayServer *ds = DisplayServer::get_singleton();
+			if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_VISIBLE) {
+				ds->mouse_set_mode(DisplayServer::MOUSE_MODE_VISIBLE);
+			}
 		} break;
 		case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
 			if (script_debugger && has_focus()) {
@@ -224,7 +243,7 @@ void LayerHost::_notification(int p_what) {
 }
 
 void LayerHost::gui_input(const Ref<InputEvent> &p_event) {
-	if (!script_debugger) {
+	if (!process->is_embedding_completed()) {
 		return;
 	}
 
@@ -246,3 +265,6 @@ void LayerHost::gui_input(const Ref<InputEvent> &p_event) {
 		accept_event();
 	}
 }
+
+LayerHost::LayerHost(EmbeddedProcessMacOS *p_process) :
+		process(p_process) {}

+ 0 - 1
platform/macos/godot_main_macos.mm

@@ -74,7 +74,6 @@ int main(int argc, char **argv) {
 
 		if (strcmp("--embedded", argv[i]) == 0) {
 			is_embedded = true;
-			continue;
 		}
 
 		args.ptr()[argsc] = argv[i];