Skip to content
skierpage edited this page May 13, 2019 · 7 revisions

See also the xdg-desktop-portal docs.

Portals are high-level session bus APIs that provide selective access to resources to sandboxed applications. The implicit expectation of portals is that the user will always be involved in granting or rejecting a portal request, thus most portal APIs will lead to user interaction in the form of dialogs.

Since such dialogs must fit into the user experience of the desktop shell, the portal APIs are implemented by a generic frontend called xdg-desktop-portal which calls out to desktop-specific implementations that provide the actual UI. The bus name through which the portal APIs are available is org.freedesktop.portal.Desktop, with the object path /org/freedesktop/portal/desktop implementing the various portal interfaces.

The FileChooser portal

The file chooser portal provides indirect file access to sandboxed applications. The basic idea of the portal is that sandboxed apps are not allowed to directly open files (outside the filesystem ''playground'' that is part of the sandbox). Instead, the portal can be used to selectively make files available inside the sandbox, via a fuse filesystem that is mounted at /run/user/$uid/doc/.

A number of D-Bus services are working in concert to achieve this. The document portal service maintains a database of what apps have access to what files. This database is backing the fuse filesystem that is mounted at /run/user/$uid/doc/ inside the sandbox. It is also mounted outside the sandbox, so you can easily inspect it. Per-application access permissions are stored using the permission store D-Bus service.

Applications are not expected to interact directly with the document portal or the permission store. To open a file outside the sandbox, apps use the file chooser portal, which interacts with the user to select the document to open, then adds it to the document portal, and returns a file uri pointing into the fuse filesystem to the app.

org.freedesktop.portal.FileChooser

The file chooser portal is available under the name org.freedesktop.portal.Desktop on the session bus.

Methods

OpenFile :: (ssa{sv}) → (o)

Presents a content chooser UI to the user, to open a single file.

The first parameter (s) is a parent window identifier, in a display-dependent format. For X, it has the form "x11:$hex-window-id".

The second parameter (s) is a title for the file chooser dialog.

The third parameter (a{sv}) is a dictionary of optional extra information. Some fields have been used in implementations: "accept_label" and "cancel_label", with string values, and "modal", with a boolean value.

The return value (o) is a handle to match the OpenFileResponse signal that signals the end of the user interaction.

OpenFiles :: (ssa{sv}) → (o)

Presents a content chooser UI to the user, to open multiple files.

The first parameter (s) is a parent window identifier, in a display-dependent format. For X, it has the form "x11:$hex-window-id".

The second parameter (s) is a title for the file chooser dialog.

The third parameter (a{sv}) is a dictionary of optional extra information. Some fields have been used in implementations: "accept_label" and "cancel_label", with string values, and "modal", with a boolean value.

The return value (o) is a handle to match the OpenFilesResponse signal that signals the end of the user interaction.

SaveFile :: (ssa{sv}) → (o)

Presents a content chooser UI to the user, to select a file to save content in.

The first parameter (s) is a parent window identifier, in a display-dependent format. For X, it has the form "x11:$hex-window-id".

The second parameter (s) is a title for the file chooser dialog.

The third parameter (a{sv}) is a dictionary of optional extra information. Some fields have been used in implementations: "accept_label" and "cancel_label", with string values, and "modal", with a boolean value.

The return value (o) is a handle to match the SaveFileResponse signal that signals the end of the user interaction.

Close :: (o) → ()

Closes a file chooser that has been opened with one of the OpenFile, OpenFiles or SaveFile methods.

The sole parameter (o) is the handle returned by that call.

Signals

OpenFileResponse :: (ousa{sv})

This signal is emitted when the user interaction started by an OpenFile call is ended.

The first parameter (o) is a handle that matches the handle returned by the OpenFile call.

The second parameter (u) is a response code, with the following meaning:

  • 0 (success): a file is returned
  • 1 (cancel): the user canceled the dialog without selecting a file
  • 2 (delete): the dialog was closed in some way without selecting a file

The third parameter (s) is the uri for the selected file, or "" if no file was selected.

The fourth parameter (a{sv}) is currently unused.

OpenFilesResponse :: (ouasa{sv})

This signal is emitted when the user interaction started by an OpenFiles call is ended.

The first parameter (o) is a handle that matches the handle returned by the OpenFiles call.

The second parameter (u) is a response code, with the following meaning:

  • 0 (success): no files are returned
  • 1 (cancel): the user canceled the dialog without selecting a file
  • 2 (delete): the dialog was closed in some way without selecting a file

The third parameter (as) contains the uri for the selected files, or [] if no file was selected.

The fourth parameter (a{sv}) is currently unused.

SaveFileResponse :: (ousa{sv})

This signal is emitted when the user interaction started by a SaveFile call is ended.

The first parameter (o) is a handle that matches the handle returned by the SaveFile call.

The second parameter (u) is a response code, with the following meaning:

  • 0 (success): a file is returned
  • 1 (cancel): the user canceled the dialog without selecting a file
  • 2 (delete): the dialog was closed in some way without selecting a file

The third parameter (s) is the uri for the selected file, or "" if no file was selected.

The fourth parameter (a{sv}) is currently unused.

Implementing portals

The xdg-desktop-portal frontend is registering portal implementations by loading key files from /usr/share/flatpak/portals/. The key files must have a .portal extension and look like this:

[portal]
DBusName=org.freedesktop.impl.portal.desktop.gtk
Interfaces=org.freedesktop.portal.FileChooser
UseIn=gnome

The following keys are required in the portal group:

  • DBusName: The name that the backend is taking on the bus
  • Interfaces: List of portal interfaces that the backend implements
  • UseIn: List of desktop identifiers for which this backend is suitable, matched against the XDG_SESSION_DESKTOP environment variable

The backend is expected to implemement the impl interfaces corresponding to the portal interfaces that it supports, at the object path /org/freedesktop/portal/desktop.

The impl interface name for a portal interface is obtained by replacing the org.freedesktop.portal. prefix with org.freedesktop.impl.portal..

The impl interface has all the same methods as the portal interface, with two additional string parameters prepended to the argument list: the first string is the bus name of the application making the call, the second string is its application id.

The impl interface also has all the same signals as the portal interface, with one additional parameter prepended to the argument list: the bus name of the application that this signal should be directed back at.