[DBus] Process file dialog callback in the main event loop instead of using deferred call.
This commit is contained in:
parent
7abe0c6014
commit
67d6be30a0
4 changed files with 53 additions and 19 deletions
|
@ -496,24 +496,30 @@ Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_windo
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeDesktopPortalDesktop::_file_dialog_callback(const Callable &p_callable, const Variant &p_status, const Variant &p_list, const Variant &p_index, const Variant &p_options, bool p_opt_in_cb) {
|
void FreeDesktopPortalDesktop::process_file_dialog_callbacks() {
|
||||||
if (p_opt_in_cb) {
|
MutexLock lock(file_dialog_mutex);
|
||||||
Variant ret;
|
while (!pending_cbs.is_empty()) {
|
||||||
Callable::CallError ce;
|
FileDialogCallback cb = pending_cbs.front()->get();
|
||||||
const Variant *args[4] = { &p_status, &p_list, &p_index, &p_options };
|
pending_cbs.pop_front();
|
||||||
|
|
||||||
p_callable.callp(args, 4, ret, ce);
|
if (cb.opt_in_cb) {
|
||||||
if (ce.error != Callable::CallError::CALL_OK) {
|
Variant ret;
|
||||||
ERR_PRINT(vformat("Failed to execute file dialogs callback: %s.", Variant::get_callable_error_text(p_callable, args, 4, ce)));
|
Callable::CallError ce;
|
||||||
}
|
const Variant *args[4] = { &cb.status, &cb.files, &cb.index, &cb.options };
|
||||||
} else {
|
|
||||||
Variant ret;
|
|
||||||
Callable::CallError ce;
|
|
||||||
const Variant *args[3] = { &p_status, &p_list, &p_index };
|
|
||||||
|
|
||||||
p_callable.callp(args, 3, ret, ce);
|
cb.callback.callp(args, 4, ret, ce);
|
||||||
if (ce.error != Callable::CallError::CALL_OK) {
|
if (ce.error != Callable::CallError::CALL_OK) {
|
||||||
ERR_PRINT(vformat("Failed to execute file dialogs callback: %s.", Variant::get_callable_error_text(p_callable, args, 3, ce)));
|
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 4, ce)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Variant ret;
|
||||||
|
Callable::CallError ce;
|
||||||
|
const Variant *args[3] = { &cb.status, &cb.files, &cb.index };
|
||||||
|
|
||||||
|
cb.callback.callp(args, 3, ret, ce);
|
||||||
|
if (ce.error != Callable::CallError::CALL_OK) {
|
||||||
|
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 3, ce)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,7 +562,14 @@ void FreeDesktopPortalDesktop::_thread_monitor(void *p_ud) {
|
||||||
file_chooser_parse_response(&iter, fd.filter_names, cancel, uris, index, options);
|
file_chooser_parse_response(&iter, fd.filter_names, cancel, uris, index, options);
|
||||||
|
|
||||||
if (fd.callback.is_valid()) {
|
if (fd.callback.is_valid()) {
|
||||||
callable_mp(portal, &FreeDesktopPortalDesktop::_file_dialog_callback).call_deferred(fd.callback, !cancel, uris, index, options, fd.opt_in_cb);
|
FileDialogCallback cb;
|
||||||
|
cb.callback = fd.callback;
|
||||||
|
cb.status = !cancel;
|
||||||
|
cb.files = uris;
|
||||||
|
cb.index = index;
|
||||||
|
cb.options = options;
|
||||||
|
cb.opt_in_cb = fd.opt_in_cb;
|
||||||
|
portal->pending_cbs.push_back(cb);
|
||||||
}
|
}
|
||||||
if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) {
|
if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);
|
callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);
|
||||||
|
|
|
@ -56,8 +56,6 @@ private:
|
||||||
static void append_dbus_dict_bool(DBusMessageIter *p_iter, const String &p_key, bool p_value);
|
static void append_dbus_dict_bool(DBusMessageIter *p_iter, const String &p_key, bool p_value);
|
||||||
static bool file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, bool &r_cancel, Vector<String> &r_urls, int &r_index, Dictionary &r_options);
|
static bool file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, bool &r_cancel, Vector<String> &r_urls, int &r_index, Dictionary &r_options);
|
||||||
|
|
||||||
void _file_dialog_callback(const Callable &p_callable, const Variant &p_status, const Variant &p_list, const Variant &p_index, const Variant &p_options, bool p_opt_in_cb);
|
|
||||||
|
|
||||||
struct FileDialogData {
|
struct FileDialogData {
|
||||||
Vector<String> filter_names;
|
Vector<String> filter_names;
|
||||||
DisplayServer::WindowID prev_focus = DisplayServer::INVALID_WINDOW_ID;
|
DisplayServer::WindowID prev_focus = DisplayServer::INVALID_WINDOW_ID;
|
||||||
|
@ -67,6 +65,16 @@ private:
|
||||||
bool opt_in_cb = false;
|
bool opt_in_cb = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FileDialogCallback {
|
||||||
|
Callable callback;
|
||||||
|
Variant status;
|
||||||
|
Variant files;
|
||||||
|
Variant index;
|
||||||
|
Variant options;
|
||||||
|
bool opt_in_cb = false;
|
||||||
|
};
|
||||||
|
List<FileDialogCallback> pending_cbs;
|
||||||
|
|
||||||
Mutex file_dialog_mutex;
|
Mutex file_dialog_mutex;
|
||||||
Vector<FileDialogData> file_dialogs;
|
Vector<FileDialogData> file_dialogs;
|
||||||
Thread monitor_thread;
|
Thread monitor_thread;
|
||||||
|
@ -86,6 +94,7 @@ public:
|
||||||
bool is_supported() { return !unsupported; }
|
bool is_supported() { return !unsupported; }
|
||||||
|
|
||||||
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_root, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb);
|
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_root, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb);
|
||||||
|
void process_file_dialog_callbacks();
|
||||||
|
|
||||||
// Retrieve the system's preferred color scheme.
|
// Retrieve the system's preferred color scheme.
|
||||||
// 0: No preference or unknown.
|
// 0: No preference or unknown.
|
||||||
|
|
|
@ -1161,6 +1161,12 @@ void DisplayServerWayland::process_events() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBUS_ENABLED
|
||||||
|
if (portal_desktop) {
|
||||||
|
portal_desktop->process_file_dialog_callbacks();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wayland_thread.mutex.unlock();
|
wayland_thread.mutex.unlock();
|
||||||
|
|
||||||
Input::get_singleton()->flush_buffered_events();
|
Input::get_singleton()->flush_buffered_events();
|
||||||
|
|
|
@ -5097,6 +5097,12 @@ void DisplayServerX11::process_events() {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBUS_ENABLED
|
||||||
|
if (portal_desktop) {
|
||||||
|
portal_desktop->process_file_dialog_callbacks();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_THREAD_SAFE_UNLOCK_
|
_THREAD_SAFE_UNLOCK_
|
||||||
|
|
||||||
Input::get_singleton()->flush_buffered_events();
|
Input::get_singleton()->flush_buffered_events();
|
||||||
|
|
Loading…
Reference in a new issue