Native file choosers in Gtk+

Recently I have been working on support for a filechooser portal for sandboxed applications (in xdg-app). The way these work is that the application triggers a file chooser, then the actual user interaction happens outside the sandbox, and the application only recieves the file data after the user finished the interaction.

Ideally something like this would be completely hidden by the toolkit, and the application would just use the regular file chooser APIs. However, the Gtk+ filechooser APIs expose too much details about the file chooser dialog, which means it has to be a regular in-process widget. Unfortunately this means we can’t replace it by an out-of-process dialog.

What we need is a Gtk+ API for the file chooser that hides the details of how the dialog works. At this point I realized that this is something that has been requested a lot in a different context. Such an API would allow us to plug in platform-native file chooser dialogs.

So, I got to work, and today I landed support for native Windows file choosers in Gtk:

win32 file chooser in gtkWe will also look at implementing an OSX version of this to ensure that the APIs work for the common cases.

Now that we have this people can start porting their applications (which is quite trivial in the common case, as the APIs is very similar to the old APIs). And once the apps are ported they will automatically get support for the filechooser portal to make them work in a sandboxed environment.

So, anyone maintaining a Gtk 3 application that want to work better on other platforms, or when sandboxed should take a look at the new GtkFileChooserNative API. Right now it only exists in git, but once there is a new release it should show up in the API docs.

33 thoughts on “Native file choosers in Gtk+”

    1. Tobias: Atm any kind of custom things makes it fall back to non-native dialog.

      However, I would like to add abstract support for some minimal customization of the dialog which could be implemented on the native dialog. Previewing will not be possible, but extra widgets could work.

      Also, the win32 dialog supports previewing by default, and gimp could install extra previewers for it file type if it wanted.

      1. Previews are possible if people provide standalone rendering routines that can be run in a sandbox to produce a preview image.

        The other big issues are embedding custom widgets (e.g. gedit’s encoding selector), which is feasible if someone writes a decent UI embedding protocol for Wayland (there are research prototypes that do UI embedding for security applications in Windows / Android so yes it must be possible),

        and saving files with the appropriate extension, a relatively trivial UX issue that can be solved with a bit of extra API (see SFCD: http://www.mupuf.org/blog/2014/05/14/introducing-sandbox-utils-0-6-1/). As far as I know Windows’s own sandbox-compatible file choosers don’t handle that properly yet, so it’d be a first. Apps like GIMP will need such a feature.

        File-roller is also an alien, delicate case since it has such a heavily modified file chooser. I strongly believe you should come up with appropriate APIs for such high-profile apps, and appropriate interaction and UI designs to support their needs, before pushing the API change. Otherwise it’ll just be twice as much work for app devs when people start complaining that their own app cannot be sandboxed and you end up changing the API again.

        1. Steve: I don’t think that the right approach for the widget embedding is to embed gtk widgets via wayland. I think the right apporach is to have a simple api to add some very common widgets, and have those implemented by the native dialog (in fact the win32 dialog already has a bunch of these).

          That said, i have also created a system for wayland embedding into gtk apps:
          https://github.com/alexlarsson/wakefield

          1. Alex,

            The big question then is: how do you decide that a widget is legitimate enough to get its own additional API? And how do you monitor new needs?

            Do you have a platform to collect anonymous reports from your users about their app usage? If so, you might be able to reuse GTK Inspector to retrieve the structure of custom widgets defined by third-party apps in the wild?

          2. We don’t have any way to such automatic collection. We can however look at all open source software out there and see what is used. We also accept requests in bugzilla for other things. We can also look at what e.g. the win32 native dialog can do as a hint on what people want.

          3. Actually, Windows 8’s API for sandboxed apps is missing some basic use cases (haven’t looked at whether it’s fixed in Win 10 though), such as file extensions matching file types. I’m collecting data right now with a bunch of Linux users to establish whether file use patterns match GTK+ file handling APIs, will report on that in 2-3 months when the study is over and the data analysed. Automatic collection should be easy to do insofar as you can instrument the Inspector to provide the information, and you can easily reuse Zeitgeist for that purpose. The only really important bit is to have a diverse sample of users from whom you collect data.

  1. Do you mean that inside the sandbox you do not allow the user to access their own files through the Gtk file chooser? The Gtk file chooser flexibility is quite usefull in some cases (I think about Pitivi for example where it is quite necessary to allow the user to preview their video when importing them in the media library) so using the ‘native’ file chooser is not an option there and I have the impression the file chooser needs to be in process for that case.

    1. Thibault: A nice out of process file chooser could implement some previewing by itself (like i.e. the win32 dialog does), but we don’t atm.

      I don’t see how you can claim to be “sandboxed” and yet have full access to the user files though, so the only way you can do custom previews in the file chooser is to request access to the users files. Maybe this is ok for the user, maybe not. It depend on what the app is.

  2. @alex, Currently we just do preview but in the future we will need to let the user specify what part of the media he want to import and things like that, I got your point about not letting the sandboxed app have access to user files, and your approach is right. We will just need to figure out how we will handle that in the various apps, but it should all be manageable.

  3. This is good stuff, and is one of the main things that makes Gtk apps look odd on windows and OSX, so cudos !

    It would be good if there could be support for widgets that can be used in for things like the gedit file sidebar.

    1. Kevin: For sandboxed xdg-app I will make Qt based file choosers for the portals.

      About using in-process KDE file choosers directly from gtk? Technically it might be doable, but I don’t personally have any interest in it.

  4. slightly off topic: my file picket in Gnome does not display network shares which are available in Nautilus. Could sb give me an hint how to fix it?
    Thank you very much.

    1. Peter: It depends on your app. The app has to first enable non-local files with gtk_file_chooser_set_local_only (chooser, FALSE); Then the *app* itself has to be changed so that it reads from uris viathe gio apis rather than pathnames only with some other API.

  5. I thought more about this and don’t think it’s the right approach.
    1. Special dialogue for every system means better integration but it also means harder debugging, more code, more bugs…
    I think it would be better to have a gtk file dialogues that looks an acts like the native ones.
    2. Does this mean you plan xdg-apps for Windows and MacOS?
    3. Do I understand this right, you open the file with a “File open App” and then send it via D-Bus to the requesting program? If yes, isn’t that a performance problem, if I e.g. import 1000 photos into darktable?
    6. Some programs open not the complete file. (If you open an geoTIFF in an GIS program the program usually just loads the first layer.) How will you handle this?

    1. Tobias, I expect it will pass an open file descriptor to the application (or perhaps marking the path as allowed in a security module so normal open() can be used). Copying the file through D-Bus would be a really bad idea, but I don’t think they are doing that.

      PS: Where are points 4 and 5? (:

    2. 1: Implementing something looking like the win32 dialog in gtk totally misses the point. It will never integrate with win32 (installed previewer, shell extensions, new styles/behaviours, smb browsing, etc). Not to mention that it would be ten thousand lines of new untested code rather than 50 lines spawning a standard win32 file chooser.

      2. No, xdg-app is quite linux specific.

      3. No, the dbus api is “create file dialog”, “show file dialog”, “listen for dialog response signal”. The actual file passing is done via the document portal which is a fuse proxy thing.

      4. 5. ?

      6. I don’t understand what this has to do with the file chooser. The code that reads the first layers needs not change at all.

      1. I think point 6 is that some apps typically load multiple files from a filename, e.g. video players automatically look for subtitles, audio players look for album covers or load multiple files from a playlist file, and so on.

        More generally, you need to be able to understand and model the difference between legitimate references to other files and plain old XXE attacks in the APIs you provide, and let the former happen but not the latter. Obviously this is a problem without a solution, but it’ll become much more apparent when you take apps that expect to be allowed to make such references and prevent them from doing so. I don’t think any of the major players right now do a good job of modelling which such patterns of accessing multiple files are legitimate and necessary for good user experience.

  6. I have two questions:

    1. How will this work with applications that use their own toolkit like Blender or UE4?

    2. If e.g. the Gtk filechooser has to run outside of the sandbox can Gtk still be installed from an xdg-app bundle?

    1. Max:
      1) They will have to call the portal directly.
      2) The “filechoser portal” is implementation agnostic, and I expect it to be implemented by the desktop (so, have both gtk and qt versions). The part in gtk is just some code that sends dbus messages to the portal, and this can clearly be installed in the bundle. However, the portal implementation has to be outside the bundle.

      1. Thanks for the answer, but unfortunately now I have even more questions:

        1) When Blender calls the portal directly, will it invoke the Gtk/Qt filechooser? That could be a problem, because the Blender filechooser has to do some special things, like move further down into .blend files to append individual parts of it.

        2) What about filemanagers, like Nautilus? Just like Blender I imagine they have their own special requirements.

        3) And is it even possible for other desktop environments like Enlightenment to use their own filechoosers?

        4) Can third parties create their own portals?

        Sorry for all these questions, I think xdg-app is great and therefore hope that it is generic enough to be used by everyone.

        1. 1) It will invoke whatever filechooser portal is running on the current system. This file chooser will by necessity be limited in what it can do. You can’t have the application run code that looks at the contents of the files that the user is browsing into, that would completely negate any sandboxing whatsoever.

          If you need very complicated features from your file chooser, then you can’t use a sandboxed file chooser, and you need to do something else, like have your app request full access to the home folder or a subset of it.

          2) Nautilus is a core part of the desktop and will not be running in a sandbox. Other file managers could be packaged as an xdg-app, but they would have to be granted filesystem access to be useful.

          3) Yeah, the idea is that all interactive portals should be replaceable by the currently running desktop.

          4) Yes, but I don’t think this will be very common appart from the major desktops doing their own.

  7. I’m not a desktop developer (I work as a Java Backend Engineer and mobile developer) but as a longtime Linux user I’m very interested in the success of xdg-apps

    Instead of adding little pieces in Gtk that work “automatically” another approach could be to have an standalone SDK that provides the functionality required to talk with the portals.

    Miscellaneous functionalities of the SDK:
    * file chooser portal
    * media chooser portal: pick images, videos or audio with preview
    * printing services
    * networking services: know when you are online and the kind of connection (wifi, LTE, …)
    * location services
    * account services (some way to talk to gnome-online-accounts)
    * some way to communicate with other apps.
    * “share with” (like in Android)

    Today with Apache Cordova you can write mobile apps with HTML and Javascript. With the same codebase (with little tweaks) you can build your app for different platforms quite easy.

    One possible goal for this xdg-app sdk could be to provide the device access that would be necessary to add Linux as a supported platform for Apache Cordova (Accelerometer, BatteryStatus, Camera, …). https://cordova.apache.org/docs/en/5.4.0/guide/support/index.html

    With this, thousand of applications could run in linux with little porting efforts.

    Just some thoughts. Thank you for your work!

    1. Jorge: All portals are already accessible without using the gtk+ apis, they are just regular DBus APIs that anything can call.
      Automatically using them from gtk+ is just a “nice thing” to have, and most of them won’t be possible to call from gtk+, as gtk doesn’t have any API for things like geolocation or sharing.

  8. This is what I’ve been thinking for a number of years now.

    If the file dialogues (not just save) are abstracted from the tool kit you can have:

    * Consistent file dialogues for all apps regardless of tool kit they use.
    * Universal Shell extensions, like in Windows Explorer, but unlike on Windows (least in my day) not loaded into the process calling the file dialog. And unlike on Windows, the extensions need only be installed once, not once for 32bit and once for 64bit. (Maybe this was sorted out post XP)
    * Integration between file dialogues and file manager windows. I.E. Finally drag and drop from a save dialogue into a file manager window to save. Like RISC OS had in the 90s.

    Really file dialogues should just be part of the file manager.

    This goes a long way towards what I want. Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *