--- filechooser.c.orig 2023-09-28 22:52:29.788289567 +0200 +++ filechooser.c 2023-09-28 22:55:47.430119038 +0200 @@ -214,6 +214,24 @@ file_dialog_handle_close (handle); } +// Copied from https://gitlab.gnome.org/GNOME/totem/blob/master/src/backend/bacon-video-widget.c#L3571 +static char * +get_target_uri (GFile *file) +{ + g_autoptr (GFileInfo) info = NULL; + g_autofree char *target = NULL; + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI, G_FILE_QUERY_INFO_NONE, NULL, NULL); + if (info != NULL) + { + const char *val = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI); + if (val != NULL) + target = g_strdup (val); + } + + return g_steal_pointer (&target); +} + static GSList * get_uris (GtkFileChooser *filechooser) { @@ -228,6 +246,58 @@ g_autoptr(GFile) file = g_list_model_get_item (files, i); g_autofree char *uri = g_file_get_uri (file); + /* + * Transform 'trash:///' and 'recent:///' URIs into + * local ones. + */ + if (g_file_has_uri_scheme (file, "trash") != FALSE || + g_file_has_uri_scheme (file, "recent") != FALSE) + { + char *target_uri = get_target_uri (file); + if (target_uri != NULL) + { + g_free (uri); + uri = g_steal_pointer (&target_uri); + } + } + + /* + * xdg-desktop-portal-gtk shows remote file systems (like + * SMB or SSH), and translates their non-local URIs (like + * smb:// or ssh://) into local ones (file://) because + * gtk_file_chooser_get_uris() from Gtk3 does that job + * automagically, using the local path offered by the + * FUSE mounts of Gvfsd. + * + * xdg-desktop-portal-gnome shows these remote FS too, but + * the method gtk_file_chooser_get_files() from Gtk4 returns + * a list of GFiles instead, and getting the URI value on these + * doesn't do that translation; this means that remote SMB or + * SSH mounts are shown in the dialog, and the user can choose + * files inside them, but the containerized application won't + * be able to access them, because xdg-desktop-portal removes + * those paths sent by xdg-desktop-portal-XXXX that aren't + * locally accesable. + * + * This piece of code adds the original functionality by asking + * to the GFile the local path for all non-file:// URI, offered + * by Gvfsd and the FUSE mount. + */ + + if (g_file_has_uri_scheme (file, "file") == FALSE) + { + g_autofree char *path = g_file_get_path (file); + if (path != NULL) + { + char *filename_uri = g_filename_to_uri (path, NULL, NULL); + if (filename_uri != NULL) + { + g_free (uri); + uri = g_steal_pointer (&filename_uri); + } + } + } + uris = g_slist_prepend (uris, g_steal_pointer (&uri)); }