Skip to content

Commit

Permalink
Merge pull request godotengine#102470 from Hilderin/fix-floating-wind…
Browse files Browse the repository at this point in the history
…ow-close-opened-dialog

Fix Floating Window request close when a dialog is opened
  • Loading branch information
akien-mga committed Feb 6, 2025
2 parents 212c077 + a3d0371 commit f1f5b51
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 6 deletions.
6 changes: 6 additions & 0 deletions editor/plugins/embedded_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ void EmbeddedProcess::reset() {
queue_redraw();
}

void EmbeddedProcess::request_close() {
if (current_process_id != 0 && embedding_completed) {
DisplayServer::get_singleton()->request_close_embedded_process(current_process_id);
}
}

void EmbeddedProcess::_try_embed_process() {
bool is_visible = is_visible_in_tree();
Error err = DisplayServer::get_singleton()->embed_process(window->get_window_id(), current_process_id, get_screen_embedded_window_rect(), is_visible, is_visible && application_has_focus && embedding_grab_focus);
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/embedded_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class EmbeddedProcess : public Control {
public:
void embed_process(OS::ProcessID p_pid);
void reset();
void request_close();

void set_window_size(const Size2i p_window_size);
void set_keep_aspect(bool p_keep_aspect);
Expand Down
9 changes: 5 additions & 4 deletions editor/plugins/game_view_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,16 +798,17 @@ void GameView::_window_close_request() {
// Before the parent window closed, we close the embedded game. That prevents
// the embedded game to be seen without a parent window for a fraction of second.
if (EditorRunBar::get_singleton()->is_playing() && (embedded_process->is_embedding_completed() || embedded_process->is_embedding_in_progress())) {
// Try to gracefully close the window. That way, the NOTIFICATION_WM_CLOSE_REQUEST
// notification should be propagated in the game process.
embedded_process->reset();

// When the embedding is not complete, we need to kill the process.
// If the game is paused, the close request will not be processed by the game, so it's better to kill the process.
if (paused || embedded_process->is_embedding_in_progress()) {
embedded_process->reset();
// Call deferred to prevent the _stop_pressed callback to be executed before the wrapper window
// actually closes.
callable_mp(EditorRunBar::get_singleton(), &EditorRunBar::stop_playing).call_deferred();
} else {
// Try to gracefully close the window. That way, the NOTIFICATION_WM_CLOSE_REQUEST
// notification should be propagated in the game process.
embedded_process->request_close();
}
}
}
Expand Down
16 changes: 15 additions & 1 deletion platform/linuxbsd/x11/display_server_x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5926,7 +5926,7 @@ Error DisplayServerX11::embed_process(WindowID p_window, OS::ProcessID p_pid, co
return OK;
}

Error DisplayServerX11::remove_embedded_process(OS::ProcessID p_pid) {
Error DisplayServerX11::request_close_embedded_process(OS::ProcessID p_pid) {
_THREAD_SAFE_METHOD_

if (!embedded_processes.has(p_pid)) {
Expand Down Expand Up @@ -5956,6 +5956,20 @@ Error DisplayServerX11::remove_embedded_process(OS::ProcessID p_pid) {
// Restore default error handler.
XSetErrorHandler(oldHandler);

return OK;
}

Error DisplayServerX11::remove_embedded_process(OS::ProcessID p_pid) {
_THREAD_SAFE_METHOD_

if (!embedded_processes.has(p_pid)) {
return ERR_DOES_NOT_EXIST;
}

EmbeddedProcessData *ep = embedded_processes.get(p_pid);

request_close_embedded_process(p_pid);

embedded_processes.erase(p_pid);
memdelete(ep);

Expand Down
1 change: 1 addition & 0 deletions platform/linuxbsd/x11/display_server_x11.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ class DisplayServerX11 : public DisplayServer {
virtual void window_start_resize(WindowResizeEdge p_edge, WindowID p_window) override;

virtual Error embed_process(WindowID p_window, OS::ProcessID p_pid, const Rect2i &p_rect, bool p_visible, bool p_grab_focus) override;
virtual Error request_close_embedded_process(OS::ProcessID p_pid) override;
virtual Error remove_embedded_process(OS::ProcessID p_pid) override;
virtual OS::ProcessID get_focused_process_id() override;

Expand Down
16 changes: 15 additions & 1 deletion platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3004,7 +3004,7 @@ Error DisplayServerWindows::embed_process(WindowID p_window, OS::ProcessID p_pid
return OK;
}

Error DisplayServerWindows::remove_embedded_process(OS::ProcessID p_pid) {
Error DisplayServerWindows::request_close_embedded_process(OS::ProcessID p_pid) {
_THREAD_SAFE_METHOD_

if (!embedded_processes.has(p_pid)) {
Expand All @@ -3016,6 +3016,20 @@ Error DisplayServerWindows::remove_embedded_process(OS::ProcessID p_pid) {
// Send a close message to gracefully close the process.
PostMessage(ep->window_handle, WM_CLOSE, 0, 0);

return OK;
}

Error DisplayServerWindows::remove_embedded_process(OS::ProcessID p_pid) {
_THREAD_SAFE_METHOD_

if (!embedded_processes.has(p_pid)) {
return ERR_DOES_NOT_EXIST;
}

EmbeddedProcessData *ep = embedded_processes.get(p_pid);

request_close_embedded_process(p_pid);

// This is a workaround to ensure the parent window correctly regains focus after the
// embedded window is closed. When the embedded window is closed while it has focus,
// the parent window (the editor) does not become active. It appears focused but is not truly activated.
Expand Down
1 change: 1 addition & 0 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ class DisplayServerWindows : public DisplayServer {

virtual void enable_for_stealing_focus(OS::ProcessID pid) override;
virtual Error embed_process(WindowID p_window, OS::ProcessID p_pid, const Rect2i &p_rect, bool p_visible, bool p_grab_focus) override;
virtual Error request_close_embedded_process(OS::ProcessID p_pid) override;
virtual Error remove_embedded_process(OS::ProcessID p_pid) override;
virtual OS::ProcessID get_focused_process_id() override;

Expand Down
5 changes: 5 additions & 0 deletions servers/display_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,11 @@ Error DisplayServer::embed_process(WindowID p_window, OS::ProcessID p_pid, const
return ERR_UNAVAILABLE;
}

Error DisplayServer::request_close_embedded_process(OS::ProcessID p_pid) {
WARN_PRINT("Embedded process not supported by this display server.");
return ERR_UNAVAILABLE;
}

Error DisplayServer::remove_embedded_process(OS::ProcessID p_pid) {
WARN_PRINT("Embedded process not supported by this display server.");
return ERR_UNAVAILABLE;
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,7 @@ class DisplayServer : public Object {
virtual void enable_for_stealing_focus(OS::ProcessID pid);

virtual Error embed_process(WindowID p_window, OS::ProcessID p_pid, const Rect2i &p_rect, bool p_visible, bool p_grab_focus);
virtual Error request_close_embedded_process(OS::ProcessID p_pid);
virtual Error remove_embedded_process(OS::ProcessID p_pid);
virtual OS::ProcessID get_focused_process_id();

Expand Down

0 comments on commit f1f5b51

Please sign in to comment.