xdg-desktop-portal-wlr: the wlroots backend for screen capture
xdg-desktop-portal backend for wlroots
At a glance
- What is it?
- xdg-desktop-portal-wlr is an MIT licensed C implementation of two xdg desktop portals, Screenshot and ScreenCast, for compositors built on wlroots, and it deliberately leaves every other portal to another implementation chosen by the user. The judgement is that the design is the interesting part, because a portal backend that tries to do everything ends up doing none of it well, and the configuration file that routes each portal is the piece every user has to get right.
- Who is it for?
- xdg-desktop-portal-wlr fits a user of Sway, Hyprland or another wlroots compositor who wants a screen sharing and screenshot dialog that behaves like the rest of their desktop, because the two portals it implements are exactly the ones a compositor can answer natively.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 71 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two portals, and everything else is somebody else's job
xdg-desktop-portal-wlr is a backend for xdg-desktop-portal, and the readme states its scope in two sentences.
It currently implements only the following portals, and it is meant to offload the missing portals to other implementations depending on the user preferences. The two it implements are org.freedesktop.impl.portal.Screenshot and org.freedesktop.impl.portal.ScreenCast.
That is the whole design, and it is a good one. The xdg desktop portal specification defines a set of interfaces that applications use to ask the desktop for privileged things, a screenshot, a screen recording, a secret from a keyring, a file chooser, a print dialog. A compositor such as Sway can answer the screen ones natively, because it owns the display, but it has no business answering the others.
So the readme names the other implementations that can be used, gtk for many implementations and gnome-keyring for the Secret portal. The routing between them is the configuration, and that configuration is the subject of one of the sections below.
The project is MIT licensed, written in C, and the last push was on 2026-08-13, with the release history in the zero point eight line: version 0.8.2 on 2026-04-17, 0.8.3 on 2026-06-18 and 0.8.4 on 2026-07-28.
The build is meson and ninja
The build instructions are two commands, which is what you would expect from a project of this size.
meson build
ninja -C buildMeson sets up the build directory and Ninja drives it, and installing is one more command:
ninja -C build installThere is a meson_options.txt at the root, so the build has options, and the repository layout shows the standard meson arrangement with a src directory, an include directory, a protocols directory, a contrib directory. There is also a.builds directory, which is where the continuous integration definitions live, and an.editorconfig.
The build is not the interesting part of this project, and the readme does not spend much room on it. For most users the distribution package is the route, and the readme points at Repology for the packaging status across distributions, with a badge showing which ones carry it.
The build matters mostly for the people who are changing it, and for them the readme points at the CONTRIBUTING.md file, which covers testing and development, along with a FAQ document for the questions that come up often.
The D-Bus environment is where this usually breaks
The running section is the part to read carefully, because the failure modes here are confusing when you first hit them.
Two things have to be true. XDG_CURRENT_DESKTOP must be set, and both WAYLAND_DISPLAY and XDG_CURRENT_DESKTOP must be imported into D-Bus. The readme gives the exact command, and gives the Sway case as the example, since that is where the fix usually goes, in the compositor configuration:
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
The reason this matters is how the portal stack finds things. The xdg-desktop-portal service is what an application talks to, and it looks at XDG_CURRENT_DESKTOP to decide which backend to use for each portal. If the environment variable is not in the D-Bus session environment, the portal service cannot see it, and the result is an application that asks for a screen capture and gets nothing, with no obvious error.
The good news, and it is stated in the readme, is that when it is correctly installed, xdg-desktop-portal automatically invokes xdg-desktop-portal-wlr when needed. There is nothing to start by hand, and nothing to connect.
There is one escape hatch for development and testing. Some command line flags are available, and you can start an instance with:
xdg-desktop-portal-wlr -r [OPTION...]The help flag lists what is available.
The portals configuration decides which backend answers
This is the mechanism that changed recently, and it is the part most likely to affect an existing setup.
The readme links to an article about configuring portals, and explains that recent changes to xdg-desktop-portal require desktop environments to set up a configuration file with the name pattern *-portals.conf, specifying which portals should be used for a given XDG_CURRENT_DESKTOP value.
If that file does not exist in /usr/share/xdg-desktop-portal/, the readme says you should create it under ~/.config/xdg-desktop-portal/, with content like this:
[preferred]
default=gtk
org.freedesktop.impl.portal.Screenshot=wlr
org.freedesktop.impl.portal.ScreenCast=wlrThe structure is straightforward. The default line sets the implementation used for any portal that is not explicitly defined, and the two explicit lines send the screenshot and screen cast interfaces to the wlr implementation, which is this project.
The readme also notes that you can add a line for any other interface you need, and gives gnome-keyring for the Secret portal as the example. So a complete configuration for a wlroots desktop typically names three implementations in total, this one for the two screen interfaces, the GTK one as the catch-all, and the keyring one for secrets.
The reason the file is best created by hand rather than waiting for a distribution to ship it is that it is in your own configuration directory, so it survives system upgrades and it is per user, which is what a desktop environment switch means in practice.
A D-Bus service file, a portal interface file and a manual page
The repository contains the pieces that a portal backend needs to be installable and to be documented, and the file names describe them.
There is a D-Bus service template, org.freedesktop.impl.portal.desktop.wlr.service.in, which is how the backend registers itself as a service on the session bus with the system and the user able to activate it on demand. The .in suffix means it is processed at build time, which is the usual convention for a file that has to carry the installed path.
There is a wlr.portal file, which is the interface description of the wlr implementation, and it names the two interfaces this project provides, the Screenshot and ScreenCast ones, so the portal service knows that wlr is a candidate for those specific requests rather than for everything.
The documentation is a man page, xdg-desktop-portal-wlr.5.scd, written in the scdoc format, and the readme points to it with the usual man 5 invocation. Section 5 for a configuration file is the right convention here, since the file being documented is a configuration file, and the content is the place to look for the options that the command line flags do not cover.
Those five files, the service template, the portal interface, the manual page source, the build definition and the build options, are the entire surface of the project outside the source directories. It is a small, well-shaped project.
Two wiki pages and a chat channel for the hard cases
The readme points at two documents for when the simple path does not work, and both are wiki pages maintained with the repository.
The first is a FAQ for answers to commonly asked questions. The second is a screencast compatibility guide, which the readme describes as covering which applications are compatible and how to get them working. That second document is the one that matters in practice, because screen recording is the part of this stack that has the most variation between applications, with each tool asking for the portal in a slightly different way and some of them expecting a pipewire node name or a specific set of properties in the response.
The support channels are equally specific. If a question or problem is not mentioned in those documents, the readme asks you to open an issue or come to the sway channel on Libera Chat. Naming the channel rather than a mailing list or a forum is a good fit for this audience, since a compositor user is usually in that chat already.
The release cadence is regular enough to say the project is looked after. Three releases between April and July 2026, 0.8.2, 0.8.3 and 0.8.4, with a six week gap between the last two. Nothing in the readme suggests the project is winding down, and the structure of it, a small C program with a build file and two interfaces, is the kind of thing that keeps working for a long time.
Editorial conclusion
xdg-desktop-portal-wlr fits a user of Sway, Hyprland or another wlroots compositor who wants a screen sharing and screenshot dialog that behaves like the rest of their desktop, because the two portals it implements are exactly the ones a compositor can answer natively. It is the wrong choice if you expect a full portal implementation, since the readme is explicit that the missing portals are offloaded to other implementations according to user preference, and it is the wrong choice if you are on a desktop that already has a portal stack, because adding a second one causes conflicts. Before you install it, create the portals configuration file in your own configuration directory, because the file in the system directory will not exist on a minimal install, and check that the D-Bus session has the environment variables the compositor needs, since that is where most of the failures happen.
Frequently asked questions
What is xdg-desktop-portal-wlr?
It is an MIT licensed C backend for xdg-desktop-portal that implements the org.freedesktop.impl.portal.Screenshot and org.freedesktop.impl.portal.ScreenCast interfaces for wlroots compositors. The other portals are offloaded to other implementations, such as gtk or gnome-keyring, depending on user preference.
How do I choose which portal implementation handles which request?
Create a *-portals.conf file in ~/.config/xdg-desktop-portal if the system one does not exist, with a default line for the catch-all and explicit lines for the interfaces you want handled by wlr, for example org.freedesktop.impl.portal.ScreenCast=wlr.
Why does screen sharing not work after I install it?
Check the D-Bus environment first. XDG_CURRENT_DESKTOP must be set and both WAYLAND_DISPLAY and XDG_CURRENT_DESKTOP must be imported into D-Bus, which for Sway means running dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway from the compositor configuration.
How do I build xdg-desktop-portal-wlr from source?
Run meson build and then ninja -C build, and install with ninja -C build install. The build uses meson and ninja, with options in meson_options.txt, and most users will find a distribution package through Repology instead.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/emersion-xdg-desktop-portal-wlr)Was this useful?