Procházet zdrojové kódy

[DBus] Process file dialog callback in the main event loop instead of using deferred call.

bruvzg před 1 rokem
rodič
revize
67d6be30a0

+ 31 - 18
platform/linuxbsd/freedesktop_portal_desktop.cpp

@@ -496,24 +496,30 @@ Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_windo
 	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) {
-	if (p_opt_in_cb) {
-		Variant ret;
-		Callable::CallError ce;
-		const Variant *args[4] = { &p_status, &p_list, &p_index, &p_options };
-
-		p_callable.callp(args, 4, ret, ce);
-		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, 4, ce)));
-		}
-	} else {
-		Variant ret;
-		Callable::CallError ce;
-		const Variant *args[3] = { &p_status, &p_list, &p_index };
+void FreeDesktopPortalDesktop::process_file_dialog_callbacks() {
+	MutexLock lock(file_dialog_mutex);
+	while (!pending_cbs.is_empty()) {
+		FileDialogCallback cb = pending_cbs.front()->get();
+		pending_cbs.pop_front();
+
+		if (cb.opt_in_cb) {
+			Variant ret;
+			Callable::CallError ce;
+			const Variant *args[4] = { &cb.status, &cb.files, &cb.index, &cb.options };
+
+			cb.callback.callp(args, 4, 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, 4, ce)));
+			}
+		} else {
+			Variant ret;
+			Callable::CallError ce;
+			const Variant *args[3] = { &cb.status, &cb.files, &cb.index };
 
-		p_callable.callp(args, 3, ret, ce);
-		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)));
+			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);
 
 								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) {
 									callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);

+ 11 - 2
platform/linuxbsd/freedesktop_portal_desktop.h

@@ -56,8 +56,6 @@ private:
 	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);
 
-	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 {
 		Vector<String> filter_names;
 		DisplayServer::WindowID prev_focus = DisplayServer::INVALID_WINDOW_ID;
@@ -67,6 +65,16 @@ private:
 		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;
 	Vector<FileDialogData> file_dialogs;
 	Thread monitor_thread;
@@ -86,6 +94,7 @@ public:
 	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);
+	void process_file_dialog_callbacks();
 
 	// Retrieve the system's preferred color scheme.
 	// 0: No preference or unknown.

+ 6 - 0
platform/linuxbsd/wayland/display_server_wayland.cpp

@@ -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();
 
 	Input::get_singleton()->flush_buffered_events();

+ 6 - 0
platform/linuxbsd/x11/display_server_x11.cpp

@@ -5097,6 +5097,12 @@ void DisplayServerX11::process_events() {
 		*/
 	}
 
+#ifdef DBUS_ENABLED
+	if (portal_desktop) {
+		portal_desktop->process_file_dialog_callbacks();
+	}
+#endif
+
 	_THREAD_SAFE_UNLOCK_
 
 	Input::get_singleton()->flush_buffered_events();