RTKit, portals, and Pipewire

Peeling an onion1, or how a bug report in a flatpaked2 application lead to fixes in three different part of the stack, but no change in the application itself.

How it started

It started with a bug report for the Flatpak of Ardour.

Pipewire needs to request realtime priorities for threads. Inside Flatpak pipewire is provided by the freedesktop-sdk, and what that bug report show is that pipewire can't find the module it uses to handle realtime priorities. This was a bug in the SDK, where it was too eager in removing unused files ­ pipewire-module-rt is the new name of the module. I submitted a fix for the 22.08 release, learning how to build the SDK in the process. freedesktop-sdk 22.08, to be released later this month, should become the base of GNOME 44 (and I think the current nightly), as well as a future KDE SDK release.

Realtime is not real

Now, to request the RT priority, pipewire does so by calling into RTKit, or, if it is not available, by calling the POSIX thread API.

RTKit allow requesting real time priorities for threads using D-Bus. It works by having the requester calling a D-Bus methods passing the process ID and thread ID.

Problem: Inside the Flatpak sandbox, the processes are in a namespace, therefore the process ID and thread ID are different. Passing them to RTKit doesn't work, so we need to use the portal API. One of the components is xdg-portal-desktop, that sits on the host side (outside the sandbox), but that get called via D-Bus from inside. It does provide an interface to proxy the RTKit calls. It does so by remapping the PID before forwarding it to RTKit. But this is not enough, the D-Bus call return a "not found" error. Notice how I said it remapped the process ID? What about the thread ID? Indeed, that's the source of the not-found-error.

Side note: Bustle was a great helper in helping diagnosing and testing this.

I then submitted a patch for the newly released "unstable" 1.15.0. And backported to 1.12.6 and 1.14.6.

Through the portal

As I said previously, Pipewire calls into RTKit. This still doesn't work for the reason given above. So I also submitted a patch for Pipewire to call the portal, and, if not found, RTKit directly. Note that the portal is also available to non flatpak applications3, and in that case it will directly forward the calls to RTKit. I hope this to be in 0.3.57 (it is on master as I write this).

On more thing...

Meanwhile, while testing how the build was going using the freedesktop-sdk 22.08beta I was still disappointed that pipewire-jack4 still didn't ship the JACK headers, forcing Flatpak packages to build JACK first. So I submitted a fix to the freedesktop-sdk.

And then I found out that the .pc file generated by Pipewire was incorrect, so I submitted a fix for that too, fix that is in 0.3.56.

Bottom line

With all of this we have better support for requesting realtime priorities and for Pipewire being a true drop in replacement in 22.08. Still pending is a release of pipewire 0.3.57 for the realtime portal support.

And there are probably a other applications to fix.


The onion peeling metaphor is adequate as there were a lot of tears.


Flatpak is a verb.


Unless you stripped down your system and there is no portal, which is handled anyway.


An important note here: JACK, cannot work from inside a Flatpak sandbox. Its API/ABI is guaranteed by using the system provided shared library libjack.so that will communicate with the sound daemon. That also means using a version libjack.so inside the sandbox wouldn't work as there is no guarantee it matches JACK installed on the host. On the other hand, pipewire-jack is designed to offer a JACK API drop in replacement, and that's what we are using.