GTK4 GtkFileChooser show only local files

I’ve asked this question on StackOverflow but to no avail, and I’m asking it here again hoping that somebody here would be able to help.

I’m migrating a cross-platform file dialog library from GTK3 to GTK4, and am lost trying to figure out how to restrict the file chooser to show local files only.

In a GTK3 File Chooser, there was a function gtk_file_chooser_set_local_only() that ensured that the user could only select local files (i.e. those that have a local path that could possibly be passed to open() or fopen()), and this restriction was enabled by default. This function has been removed in GTK4, and there does not appear to be any replacement. This migration document mentions that the function has been removed, and now GTK4 File Choosers can access both local and non-local resources.

While I could check whether the GFile that is returned is local, and display an error message if the file selected is non-local, there are some behavioral differences in the dialog itself when gtk_file_chooser_set_local_only() is set to false. For example, clicking on “Other Locations” will show a box that prompts for a URL. To avoid confusing the user, is it possible to configure the dialog to hide the non-local resources?


Background info: This library is meant to support MacOS and Windows too, and use the native dialogs there. GTK is used for Linux because it is the de-facto file chooser for Linux, but no other GTK features are used. On MacOS and Windows, GTK isn’t a dependency at all. Hence, to maintain a consistent abstraction, my library returns a filepath to the user as a string. These filenames may be passed to other libraries for consumption, for example fopen() or SDL_RWFromFile(), which do not understand non-local files and do not use GFileInputStream and the like.

No, we’ve removed the api because we don’t want to maintain a separate ‘local only’ mode in the file chooser.

All users of GTK link against libgio anyway, so they should not have a problem opening the files returned by the file chooser, local or not.

If you want to use the GTK filechooser without anything that comes with it (such as libgio), then it is up to you to bridge that gap (either by downloading non-local files before passing them on, or by throwing an error).

Thanks for the reply.

I was afraid so… I’d have to see what works best for my use case.

There unfortunately is a discrepancy there with the way the OS handles files that leaks through to API consumers irrespective of the file dialog… On windows the user can enter network paths into the file dialog and submit the dialog, and then fopen is able to handle those network paths because of the way Windows libc is written. This unfortunately isn’t the case for glibc fopen on Linux so gio must be used there to handle network paths. I don’t know the situation on MacOS but I’d imagine it’s similar. I checked and for macOS the expected way seems to be similar, to pass the URL from the dialog to an NSFileHandle instead of using libc functions. I can’t see a consistent way around this that doesn’t require ifdefs in the API consumers, or another abstraction layer for files :frowning:

For Windows, do you mean paths on network drives (e.g. \\nts\path\to\file.txt) or regular URLs that one might type into a browser? I would assume paths on network drives are fine to pass around to third party libraries, because Windows APIs transparently open the file as if it is a local file. I’m not sure about regular URLs though.

Basically, the GTK filechooser is not targeting fopen(). It returns GFile objects.

Yes, on Windows I believe the selection dialog is able to return those paths (\\nts\path\to\file.txt) and fopen is able to open them. I haven’t tested it in a while but it was like that last time I looked. On Linux the GTK dialog would return something like smb://nts/path/to/file.txt and fopen will not work, as @matthiasc says the user has to use GFile to handle that path, or you can throw an error for those paths and re-open the dialog within your library. I think g_file_get_path will return NULL for those uris? If not you can test for the file scheme.

Thanks for the elaboration. Yeah, I was intending to use g_file_get_path to check if the URI is a path.

On a side note, it doesn’t seem like GPath has an API that just checks that a GPath represents a local file - we have to use g_file_get_path to actually do the conversion in order to find out, which means it’s rather expensive to count the number of paths returned in a open file dialog that allows multiple selection. I found this somewhat surprising too.

I think g_file_get_path will work in any case when the file is mounted as a FUSE filesystem.

Yeah, but that’s fine, and we should indeed be treating files from FUSE as regular files, because the open() syscall and friends know how to handle FUSE filesystems transparently for the application.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.