From 2e1f48ff6e52a124fdd513d4cace0ec56147df72 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 24 Aug 2023 08:49:18 +0300 Subject: [PATCH] [Native File Dialogs] Refocus last focused window on close. --- platform/linuxbsd/freedesktop_portal_desktop.cpp | 6 +++++- platform/linuxbsd/freedesktop_portal_desktop.h | 3 ++- platform/linuxbsd/x11/display_server_x11.cpp | 4 ++-- platform/macos/display_server_macos.mm | 8 ++++++++ platform/windows/display_server_windows.cpp | 5 +++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp index 91c14e0e9111..e9f55faf7fae 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.cpp +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -266,7 +266,7 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it return true; } -Error FreeDesktopPortalDesktop::file_dialog_show(const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback) { +Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback) { if (unsupported) { return FAILED; } @@ -277,6 +277,7 @@ Error FreeDesktopPortalDesktop::file_dialog_show(const String &p_xid, const Stri // Open connection and add signal handler. FileDialogData fd; fd.callback = p_callback; + fd.prev_focus = p_window_id; CryptoCore::RandomGenerator rng; ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator."); @@ -416,6 +417,9 @@ void FreeDesktopPortalDesktop::_thread_file_dialog_monitor(void *p_ud) { Variant *v_args[2] = { &v_status, &v_files }; fd.callback.call_deferredp((const Variant **)&v_args, 2); } + if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) { + callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus); + } } dbus_message_unref(msg); diff --git a/platform/linuxbsd/freedesktop_portal_desktop.h b/platform/linuxbsd/freedesktop_portal_desktop.h index a9b83b3844d3..6ffb3e7b04a0 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.h +++ b/platform/linuxbsd/freedesktop_portal_desktop.h @@ -56,6 +56,7 @@ class FreeDesktopPortalDesktop { struct FileDialogData { DBusConnection *connection = nullptr; + DisplayServer::WindowID prev_focus = DisplayServer::INVALID_WINDOW_ID; Callable callback; String path; }; @@ -73,7 +74,7 @@ class FreeDesktopPortalDesktop { bool is_supported() { return !unsupported; } - Error file_dialog_show(const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback); + Error file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback); // Retrieve the system's preferred color scheme. // 0: No preference or unknown. diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index f38a9dd27833..8112f3998cca 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -364,14 +364,14 @@ bool DisplayServerX11::is_dark_mode() const { } Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback) { - WindowID window_id = _get_focused_window_or_popup(); + WindowID window_id = last_focused_window; if (!windows.has(window_id)) { window_id = MAIN_WINDOW_ID; } String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window); - return portal_desktop->file_dialog_show(xid, p_title, p_current_directory, p_filename, p_mode, p_filters, p_callback); + return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, p_filename, p_mode, p_filters, p_callback); } #endif diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index e79d6acc3f89..d416a567ac37 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1885,6 +1885,8 @@ } } + WindowID prev_focus = last_focused_window; + Callable callback = p_callback; // Make a copy for async completion handler. switch (p_mode) { case FILE_DIALOG_MODE_SAVE_FILE: { @@ -1952,6 +1954,9 @@ callback.callp((const Variant **)&v_args, 2, ret, ce); } } + if (prev_focus != INVALID_WINDOW_ID) { + callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(prev_focus); + } }]; } break; case FILE_DIALOG_MODE_OPEN_ANY: @@ -2031,6 +2036,9 @@ callback.callp((const Variant **)&v_args, 2, ret, ce); } } + if (prev_focus != INVALID_WINDOW_ID) { + callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(prev_focus); + } }]; } break; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 5863a75324ff..b18d683c3f5a 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -239,6 +239,8 @@ Error DisplayServerWindows::file_dialog_show(const String &p_title, const String filters.push_back({ (LPCWSTR)filter_names[i].ptr(), (LPCWSTR)filter_exts[i].ptr() }); } + WindowID prev_focus = last_focused_window; + HRESULT hr = S_OK; IFileDialog *pfd = nullptr; if (p_mode == FILE_DIALOG_MODE_SAVE_FILE) { @@ -339,6 +341,9 @@ Error DisplayServerWindows::file_dialog_show(const String &p_title, const String } } pfd->Release(); + if (prev_focus != INVALID_WINDOW_ID) { + callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(prev_focus); + } return OK; } else {