|
@@ -1555,16 +1555,23 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_
|
|
|
data_device->drag_offer = wl_data_offer_get_user_data(id);
|
|
|
|
|
|
/* TODO: SDL Support more mime types */
|
|
|
- has_mime = Wayland_data_offer_has_mime(
|
|
|
- data_device->drag_offer, FILE_MIME);
|
|
|
-
|
|
|
- /* If drag_mime is NULL this will decline the offer */
|
|
|
- wl_data_offer_accept(id, serial,
|
|
|
- (has_mime == SDL_TRUE) ? FILE_MIME : NULL);
|
|
|
+#ifdef SDL_USE_LIBDBUS
|
|
|
+ if (Wayland_data_offer_has_mime(data_device->drag_offer, FILE_PORTAL_MIME)) {
|
|
|
+ has_mime = SDL_TRUE;
|
|
|
+ wl_data_offer_accept(id, serial, FILE_PORTAL_MIME);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ if (Wayland_data_offer_has_mime(data_device->drag_offer, FILE_MIME)) {
|
|
|
+ has_mime = SDL_TRUE;
|
|
|
+ wl_data_offer_accept(id, serial, FILE_MIME);
|
|
|
+ }
|
|
|
|
|
|
/* SDL only supports "copy" style drag and drop */
|
|
|
- if (has_mime == SDL_TRUE) {
|
|
|
+ if (has_mime) {
|
|
|
dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
|
|
+ } else {
|
|
|
+ /* drag_mime is NULL this will decline the offer */
|
|
|
+ wl_data_offer_accept(id, serial, NULL);
|
|
|
}
|
|
|
if (wl_data_offer_get_version(data_device->drag_offer->offer) >= 3) {
|
|
|
wl_data_offer_set_actions(data_device->drag_offer->offer,
|
|
@@ -1725,21 +1732,61 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_d
|
|
|
if (data_device->drag_offer != NULL) {
|
|
|
/* TODO: SDL Support more mime types */
|
|
|
size_t length;
|
|
|
- void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
|
|
|
- &length, FILE_MIME, SDL_TRUE);
|
|
|
- if (buffer) {
|
|
|
- char *saveptr = NULL;
|
|
|
- char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr);
|
|
|
- while (token != NULL) {
|
|
|
- char *fn = Wayland_URIToLocal(token);
|
|
|
- if (fn) {
|
|
|
- SDL_SendDropFile(data_device->dnd_window, fn);
|
|
|
+ SDL_bool drop_handled = SDL_FALSE;
|
|
|
+#ifdef SDL_USE_LIBDBUS
|
|
|
+ if (Wayland_data_offer_has_mime(
|
|
|
+ data_device->drag_offer, FILE_PORTAL_MIME)) {
|
|
|
+ void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
|
|
|
+ &length, FILE_PORTAL_MIME, SDL_TRUE);
|
|
|
+ if (buffer) {
|
|
|
+ SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
|
|
+ if (dbus) {
|
|
|
+ int path_count = 0;
|
|
|
+ char **paths = SDL_DBus_DocumentsPortalRetrieveFiles(buffer, &path_count);
|
|
|
+ /* If dropped files contain a directory the list is empty */
|
|
|
+ if (paths && path_count > 0) {
|
|
|
+ for (int i = 0; i < path_count; i++) {
|
|
|
+ SDL_SendDropFile(data_device->dnd_window, paths[i]);
|
|
|
+ }
|
|
|
+ dbus->free_string_array(paths);
|
|
|
+ SDL_SendDropComplete(data_device->dnd_window);
|
|
|
+ drop_handled = SDL_TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SDL_free(buffer);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ /* If XDG document portal fails fallback.
|
|
|
+ * When running a flatpak sandbox this will most likely be a list of
|
|
|
+ * non paths that are not visible to the application
|
|
|
+ */
|
|
|
+ if (!drop_handled && Wayland_data_offer_has_mime(
|
|
|
+ data_device->drag_offer, FILE_MIME)) {
|
|
|
+ void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
|
|
|
+ &length, FILE_MIME, SDL_TRUE);
|
|
|
+ if (buffer) {
|
|
|
+ char *saveptr = NULL;
|
|
|
+ char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr);
|
|
|
+ while (token != NULL) {
|
|
|
+ char *fn = Wayland_URIToLocal(token);
|
|
|
+ if (fn) {
|
|
|
+ SDL_SendDropFile(data_device->dnd_window, fn);
|
|
|
+ }
|
|
|
+ token = SDL_strtokr(NULL, "\r\n", &saveptr);
|
|
|
}
|
|
|
- token = SDL_strtokr(NULL, "\r\n", &saveptr);
|
|
|
+ SDL_SendDropComplete(data_device->dnd_window);
|
|
|
+ SDL_free(buffer);
|
|
|
+ drop_handled = SDL_TRUE;
|
|
|
}
|
|
|
- SDL_SendDropComplete(data_device->dnd_window);
|
|
|
- SDL_free(buffer);
|
|
|
}
|
|
|
+
|
|
|
+ if (drop_handled && wl_data_offer_get_version(data_device->drag_offer->offer) >=
|
|
|
+ WL_DATA_OFFER_FINISH_SINCE_VERSION) {
|
|
|
+ wl_data_offer_finish(data_device->drag_offer->offer);
|
|
|
+ }
|
|
|
+ Wayland_data_offer_destroy(data_device->drag_offer);
|
|
|
+ data_device->drag_offer = NULL;
|
|
|
}
|
|
|
}
|
|
|
|