Posted on

Integrating sandboxed Vala apps with the host system through xdg-desktop-portals

Portals are a mechanism through which applications can interact with the host environment from within a sandbox. They give the ability to interact with data, files, and services without the need to add sandbox permissions.

Examples of capabilities that can be accessed through portals include opening files through a file chooser dialog, or printing. More information about portals can be found in Sandbox Permissions.

Some portals, such as the FileChooser one, provide an almost seamless experience without much extra code on the app side. For other portals, you usually need some code to talk to the portal’s DBus interface or use libportal.

Vala was designed specifically for the development of GNOME apps, and it has some nice syntax-sugar that makes the communication with DBus pretty simple to implement.

GNOME Boxes is written in Vala and, for this reason, instead of consuming libportal, I introduced a small singleton Portal class that centralizes the whole portal communication logic for the app. This turned out to be quite convenient, so I am copy-pasting it in other Vala apps I work on, and sharing this here in case it can be useful to you too. 🙂

This works because in Vala you can define a namespace matching the desired DBus interface name and with annotations, you can bind objects, properties, and methods to a DBus service. See the Vala DBus Client Samples for more examples.

With the Portal singleton, a call to the Background portal requesting permission for the app to run in the background gets as simple as:

var portals = Portals.get_default ();
yield portals.request_to_run_in_background ((response, results) => {
    if (response == 0)
        // do something...

Notice that this is an async call and you may pass a callback to handle its response.

Nothing written here is new, but I thought it was worth sharing this snippet to help others make their apps integrate with xdg-desktop-portals and reduce the unnecessary exposition of user data in sandboxed environments.