Skip to content

Commit 2fd6c63

Browse files
committed
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
2 parents 800b63a + e9fef1c commit 2fd6c63

File tree

4 files changed

+48
-8
lines changed

4 files changed

+48
-8
lines changed

editor/plugins/game_view_plugin.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,20 +243,29 @@ void GameView::_show_update_window_wrapper() {
243243
Size2i size = floating_window_rect.size;
244244
int screen = floating_window_screen;
245245

246-
Size2 wrapped_margins_size = window_wrapper->get_margins_size();
247-
Point2 offset_embedded_process = embedded_process->get_global_position() - get_global_position();
248-
offset_embedded_process.x += embedded_process->get_margin_size(SIDE_LEFT);
249-
offset_embedded_process.y += embedded_process->get_margin_size(SIDE_TOP);
250-
251246
// Obtain the size around the embedded process control. Usually, the difference between the game view's get_size
252247
// and the embedded control should work. However, when the control is hidden and has never been displayed,
253248
// the size of the embedded control is not calculated.
254249
Size2 old_min_size = embedded_process->get_custom_minimum_size();
255250
embedded_process->set_custom_minimum_size(Size2i());
256-
Size2 min_size = get_minimum_size();
251+
252+
Size2 embedded_process_min_size = get_minimum_size();
253+
Size2 wrapped_margins_size = window_wrapper->get_margins_size();
254+
Size2 wrapped_min_size = window_wrapper->get_minimum_size();
255+
Point2 offset_embedded_process = embedded_process->get_global_position() - get_global_position();
256+
257+
// On the first startup, the global position of the embedded process control is invalid because it was
258+
// never displayed. We will calculated it manually using the minimum size of the window.
259+
if (offset_embedded_process == Point2()) {
260+
offset_embedded_process.y = wrapped_min_size.y;
261+
}
262+
offset_embedded_process.x += embedded_process->get_margin_size(SIDE_LEFT);
263+
offset_embedded_process.y += embedded_process->get_margin_size(SIDE_TOP);
264+
offset_embedded_process += window_wrapper->get_margins_top_left();
265+
257266
embedded_process->set_custom_minimum_size(old_min_size);
258267

259-
Point2 size_diff_embedded_process = Point2(0, min_size.y) + embedded_process->get_margins_size();
268+
Point2 size_diff_embedded_process = Point2(0, embedded_process_min_size.y) + embedded_process->get_margins_size();
260269

261270
if (placement.position != Point2i(INT_MAX, INT_MAX)) {
262271
position = placement.position - offset_embedded_process;
@@ -786,8 +795,21 @@ void GameView::_update_arguments_for_instance(int p_idx, List<String> &r_argumen
786795

787796
// Be sure to have the correct window size in the embedded_process control.
788797
_update_embed_window_size();
789-
790798
Rect2i rect = embedded_process->get_screen_embedded_window_rect();
799+
800+
// When using the floating window, we need to force the position and size from the
801+
// editor/project settings, because the get_screen_embedded_window_rect of the
802+
// embedded_process will be updated only on the next frame.
803+
if (p_idx == 0 && window_wrapper->get_window_enabled()) {
804+
EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
805+
if (placement.position != Point2i(INT_MAX, INT_MAX)) {
806+
rect.position = placement.position;
807+
}
808+
if (placement.size != Size2i()) {
809+
rect.size = placement.size;
810+
}
811+
}
812+
791813
N = r_arguments.insert_after(N, "--position");
792814
N = r_arguments.insert_after(N, itos(rect.position.x) + "," + itos(rect.position.y));
793815
N = r_arguments.insert_after(N, "--resolution");

editor/window_wrapper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,14 @@ Size2 WindowWrapper::get_margins_size() {
338338
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));
339339
}
340340

341+
Size2 WindowWrapper::get_margins_top_left() {
342+
if (!margins) {
343+
return Size2();
344+
}
345+
346+
return Size2(margins->get_margin_size(SIDE_LEFT), margins->get_margin_size(SIDE_TOP));
347+
}
348+
341349
void WindowWrapper::grab_window_focus() {
342350
if (get_window_enabled() && is_visible()) {
343351
window->grab_focus();

editor/window_wrapper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class WindowWrapper : public MarginContainer {
8686
void set_window_title(const String &p_title);
8787
void set_margins_enabled(bool p_enabled);
8888
Size2 get_margins_size();
89+
Size2 get_margins_top_left();
8990
void grab_window_focus();
9091

9192
void set_override_close_request(bool p_enabled);

platform/windows/display_server_windows.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6173,6 +6173,15 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
61736173

61746174
wd.parent_hwnd = p_parent_hwnd;
61756175

6176+
// Detach the input queue from the parent window.
6177+
// This prevents the embedded window from waiting on the main window's input queue,
6178+
// causing lags input lags when resizing or moving the main window.
6179+
if (p_parent_hwnd) {
6180+
DWORD mainThreadId = GetWindowThreadProcessId(owner_hwnd, nullptr);
6181+
DWORD embeddedThreadId = GetCurrentThreadId();
6182+
AttachThreadInput(embeddedThreadId, mainThreadId, FALSE);
6183+
}
6184+
61766185
if (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
61776186
wd.fullscreen = true;
61786187
if (p_mode == WINDOW_MODE_FULLSCREEN) {

0 commit comments

Comments
 (0)