Browse Source

Merge pull request #102744 from Hilderin/fix-floating-window-freeze-when-moving

Fix Game and editor freeze when clicking on the game's title bar
Rémi Verschelde 6 months ago
parent
commit
2fd6c635d5

+ 30 - 8
editor/plugins/game_view_plugin.cpp

@@ -243,20 +243,29 @@ void GameView::_show_update_window_wrapper() {
 	Size2i size = floating_window_rect.size;
 	int screen = floating_window_screen;
 
-	Size2 wrapped_margins_size = window_wrapper->get_margins_size();
-	Point2 offset_embedded_process = embedded_process->get_global_position() - get_global_position();
-	offset_embedded_process.x += embedded_process->get_margin_size(SIDE_LEFT);
-	offset_embedded_process.y += embedded_process->get_margin_size(SIDE_TOP);
-
 	// Obtain the size around the embedded process control. Usually, the difference between the game view's get_size
 	// and the embedded control should work. However, when the control is hidden and has never been displayed,
 	// the size of the embedded control is not calculated.
 	Size2 old_min_size = embedded_process->get_custom_minimum_size();
 	embedded_process->set_custom_minimum_size(Size2i());
-	Size2 min_size = get_minimum_size();
+
+	Size2 embedded_process_min_size = get_minimum_size();
+	Size2 wrapped_margins_size = window_wrapper->get_margins_size();
+	Size2 wrapped_min_size = window_wrapper->get_minimum_size();
+	Point2 offset_embedded_process = embedded_process->get_global_position() - get_global_position();
+
+	// On the first startup, the global position of the embedded process control is invalid because it was
+	// never displayed. We will calculated it manually using the minimum size of the window.
+	if (offset_embedded_process == Point2()) {
+		offset_embedded_process.y = wrapped_min_size.y;
+	}
+	offset_embedded_process.x += embedded_process->get_margin_size(SIDE_LEFT);
+	offset_embedded_process.y += embedded_process->get_margin_size(SIDE_TOP);
+	offset_embedded_process += window_wrapper->get_margins_top_left();
+
 	embedded_process->set_custom_minimum_size(old_min_size);
 
-	Point2 size_diff_embedded_process = Point2(0, min_size.y) + embedded_process->get_margins_size();
+	Point2 size_diff_embedded_process = Point2(0, embedded_process_min_size.y) + embedded_process->get_margins_size();
 
 	if (placement.position != Point2i(INT_MAX, INT_MAX)) {
 		position = placement.position - offset_embedded_process;
@@ -786,8 +795,21 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
 
 	// Be sure to have the correct window size in the embedded_process control.
 	_update_embed_window_size();
-
 	Rect2i rect = embedded_process->get_screen_embedded_window_rect();
+
+	// 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()) {
+		EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
+		if (placement.position != Point2i(INT_MAX, INT_MAX)) {
+			rect.position = placement.position;
+		}
+		if (placement.size != Size2i()) {
+			rect.size = placement.size;
+		}
+	}
+
 	N = r_arguments.insert_after(N, "--position");
 	N = r_arguments.insert_after(N, itos(rect.position.x) + "," + itos(rect.position.y));
 	N = r_arguments.insert_after(N, "--resolution");

+ 8 - 0
editor/window_wrapper.cpp

@@ -338,6 +338,14 @@ Size2 WindowWrapper::get_margins_size() {
 	return Size2(margins->get_margin_size(SIDE_LEFT) + margins->get_margin_size(SIDE_RIGHT), margins->get_margin_size(SIDE_TOP) + margins->get_margin_size(SIDE_RIGHT));
 }
 
+Size2 WindowWrapper::get_margins_top_left() {
+	if (!margins) {
+		return Size2();
+	}
+
+	return Size2(margins->get_margin_size(SIDE_LEFT), margins->get_margin_size(SIDE_TOP));
+}
+
 void WindowWrapper::grab_window_focus() {
 	if (get_window_enabled() && is_visible()) {
 		window->grab_focus();

+ 1 - 0
editor/window_wrapper.h

@@ -86,6 +86,7 @@ public:
 	void set_window_title(const String &p_title);
 	void set_margins_enabled(bool p_enabled);
 	Size2 get_margins_size();
+	Size2 get_margins_top_left();
 	void grab_window_focus();
 
 	void set_override_close_request(bool p_enabled);

+ 9 - 0
platform/windows/display_server_windows.cpp

@@ -6173,6 +6173,15 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
 
 		wd.parent_hwnd = p_parent_hwnd;
 
+		// Detach the input queue from the parent window.
+		// This prevents the embedded window from waiting on the main window's input queue,
+		// causing lags input lags when resizing or moving the main window.
+		if (p_parent_hwnd) {
+			DWORD mainThreadId = GetWindowThreadProcessId(owner_hwnd, nullptr);
+			DWORD embeddedThreadId = GetCurrentThreadId();
+			AttachThreadInput(embeddedThreadId, mainThreadId, FALSE);
+		}
+
 		if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
 			wd.fullscreen = true;
 			if (p_mode == WINDOW_MODE_FULLSCREEN) {