Repository: godotengine/godot (language: cpp)

Issue:
Embedded Game window wrong first startup location and size
### Tested versions

Reproductible since Godot 4.4 beta 4
Not reprodictible in Godot 4.4 beta 3

### System information

Godot v4.4.rc (8ed125b42) - Windows 11 (build 26100) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 (NVIDIA; 32.0.15.7216) - 11th Gen Intel(R) Core(TM) i5-11600KF @ 3.90GHz (12 threads)

### Issue description

When the game is started and the game is embedded inside the editor without the floating window and if the Game View tab was not accessed, the location and the size of the embedded game is wrong at the first startup of the game.

https://github.com/user-attachments/assets/f3623b5f-65c0-42ab-8422-b19c5e4dc2cc

### Steps to reproduce

- Open the editor, set embedding at true and floating window at false
- Go to another tab then Game View
- Close the editor
- Reopen a project in the editor
- Start the game without going to the Game View
- You will see the game for a split second really small and not correctly positionned on startup

### Minimal reproduction project (MRP)

Any project


Discussion / hints:

Fix patch:
diff --git a/editor/plugins/embedded_process.cpp b/editor/plugins/embedded_process.cpp
index 0da2dceb5f4d..b4897bcd48f9 100644
--- a/editor/plugins/embedded_process.cpp
+++ b/editor/plugins/embedded_process.cpp
@@ -95,9 +95,11 @@ void EmbeddedProcess::set_keep_aspect(bool p_keep_aspect) {
 	}
 }
 
-Rect2i EmbeddedProcess::_get_global_embedded_window_rect() {
-	Rect2i control_rect = get_global_rect();
-	control_rect = Rect2i(control_rect.position + margin_top_left, (control_rect.size - get_margins_size()).maxi(1));
+Rect2i EmbeddedProcess::get_adjusted_embedded_window_rect(Rect2i p_rect) {
+	Rect2i control_rect = Rect2i(p_rect.position + margin_top_left, (p_rect.size - get_margins_size()).maxi(1));
+	if (window) {
+		control_rect.position += window->get_position();
+	}
 	if (window_size != Size2i()) {
 		Rect2i desired_rect = Rect2i();
 		if (!keep_aspect && control_rect.size.x >= window_size.x && control_rect.size.y >= window_size.y) {
@@ -116,12 +118,7 @@ Rect2i EmbeddedProcess::_get_global_embedded_window_rect() {
 }
 
 Rect2i EmbeddedProcess::get_screen_embedded_window_rect() {
-	Rect2i rect = _get_global_embedded_window_rect();
-	if (window) {
-		rect.position += window->get_position();
-	}
-
-	return rect;
+	return get_adjusted_embedded_window_rect(get_global_rect());
 }
 
 int EmbeddedProcess::get_margin_size(Side p_side) const {
diff --git a/editor/plugins/embedded_process.h b/editor/plugins/embedded_process.h
index 55988be3f0b4..298424b0c553 100644
--- a/editor/plugins/embedded_process.h
+++ b/editor/plugins/embedded_process.h
@@ -83,6 +83,7 @@ class EmbeddedProcess : public Control {
 	void set_keep_aspect(bool p_keep_aspect);
 	void queue_update_embedded_process();
 
+	Rect2i get_adjusted_embedded_window_rect(Rect2i p_rect);
 	Rect2i get_screen_embedded_window_rect();
 	int get_margin_size(Side p_side) const;
 	Size2 get_margins_size();
diff --git a/editor/plugins/game_view_plugin.cpp b/editor/plugins/game_view_plugin.cpp
index 6318bf6d1645..30c558e0bd5d 100644
--- a/editor/plugins/game_view_plugin.cpp
+++ b/editor/plugins/game_view_plugin.cpp
@@ -812,10 +812,28 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
 	_update_embed_window_size();
 	Rect2i rect = embedded_process->get_screen_embedded_window_rect();
 
+	// On the first startup, the global rect of the embedded process control is invalid because it was
+	// never displayed. We will calculated it manually.
+	if (!window_wrapper->get_window_enabled() && rect.size.y < embedded_process->get_custom_minimum_size().y) {
+		Size2 old_min_size = embedded_process->get_custom_minimum_size();
+		embedded_process->set_custom_minimum_size(Size2i());
+
+		Control *container = EditorNode::get_singleton()->get_editor_main_screen()->get_control();
+		rect = container->get_global_rect();
+
+		Size2 wrapped_min_size = window_wrapper->get_minimum_size();
+		rect.position.y += wrapped_min_size.y;
+		rect.size.y -= wrapped_min_size.y;
+
+		rect = embedded_process->get_adjusted_embedded_window_rect(rect);
+
+		embedded_process->set_custom_minimum_size(old_min_size);
+	}
+
 	// When using the floating window, we need to force the position and size from the
 	// editor/project settings, because the get_screen_embedded_window_rect of the
 	// embedded_process will be updated only on the next frame.
-	if (p_idx == 0 && window_wrapper->get_window_enabled()) {
+	if (window_wrapper->get_window_enabled()) {
 		EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
 		if (placement.position != Point2i(INT_MAX, INT_MAX)) {
 			rect.position = placement.position;


Test patch: