XDG Desktop Portals Explained
Learn what XDG Desktop Portals do, how to install the right backend for GNOME, KDE, or wlroots, and how to fix common screen sharing and file picker failures.
Before you start
- ▸A working Wayland or X11 desktop session
- ▸sudo or root access to install packages
- ▸PipeWire installed and running (required for screen sharing)
- ▸Flatpak installed if you want to test with PortalTest
XDG Desktop Portals are the standardized bridge between sandboxed applications—primarily Flatpaks, but also Snaps and any app that opts in—and privileged desktop services like screen capture, file selection, and power management. Without them, a Flatpak running inside its sandbox cannot open a native file chooser, share your screen, or prevent your screensaver from activating. Portals expose a D-Bus API that apps call, and a backend implementation translates that call into whatever your desktop environment actually provides. Get the wrong backend installed, and things silently break in confusing ways.
How Portals Work
The portal architecture has two layers. The front-end is xdg-desktop-portal, a D-Bus service at org.freedesktop.portal.* that any app can call regardless of sandbox. The back-end is a separate package specific to your desktop environment—it receives the request from the front-end and does the real work using native DE APIs. The front-end and back-end communicate over a private D-Bus interface.
When a Flatpak calls the FileChooser portal, the sequence is:
- App sends a D-Bus request to
org.freedesktop.portal.FileChooser. - xdg-desktop-portal picks the correct backend based on the current desktop.
- The backend (e.g., xdg-desktop-portal-gnome) opens a native GTK file chooser.
- The user picks a file; the portal hands back only that file's path to the sandbox.
The app never gains broad filesystem access—it only gets what the user explicitly granted through the portal dialog.
Choosing the Right Backend
Each major desktop environment ships its own backend. Using the wrong one causes missing dialogs, broken screen sharing, or silent failures.
| Desktop | Package | Notes |
|---|---|---|
| GNOME | xdg-desktop-portal-gnome | Required for GNOME 43+; replaces the older gtk backend |
| KDE Plasma | xdg-desktop-portal-kde | Provides native KDE dialogs; required for KWin screen sharing |
| wlroots compositors (Sway, Hyprland, Wayfire) | xdg-desktop-portal-wlr | Handles screen sharing via wlroots wlr-screencopy protocol |
| XFCE / LXDE / generic | xdg-desktop-portal-gtk | Good fallback; uses GTK dialogs |
| Budgie, Cinnamon, MATE | xdg-desktop-portal-gtk | No dedicated backend; gtk works well |
| LXQt | xdg-desktop-portal-lxqt | Available in most repos since 2023 |
You can have multiple backends installed simultaneously. The front-end chooses based on the DESKTOP_SESSION or XDG_CURRENT_DESKTOP environment variable, and you can override the selection with a config file (covered below).
Installing Portals
Debian / Ubuntu
sudo apt install xdg-desktop-portal xdg-desktop-portal-gnome
# KDE instead
sudo apt install xdg-desktop-portal xdg-desktop-portal-kde
# wlroots compositors
sudo apt install xdg-desktop-portal xdg-desktop-portal-wlr
Fedora / RHEL / Rocky
sudo dnf install xdg-desktop-portal xdg-desktop-portal-gnome
# KDE
sudo dnf install xdg-desktop-portal xdg-desktop-portal-kde
# wlroots
sudo dnf install xdg-desktop-portal xdg-desktop-portal-wlr
Arch Linux
sudo pacman -S xdg-desktop-portal xdg-desktop-portal-gnome
# KDE
sudo pacman -S xdg-desktop-portal xdg-desktop-portal-kde
# wlroots (Sway, Hyprland)
sudo pacman -S xdg-desktop-portal xdg-desktop-portal-wlr
Key Portal Interfaces
FileChooser
The most commonly encountered portal. When a sandboxed app needs to open or save a file, it calls org.freedesktop.portal.FileChooser. The backend opens your desktop's native picker, and only the chosen path is returned to the app. No backend running means the app either crashes, shows a blank dialog, or—worse—silently fails to open any file at all.
ScreenCast and RemoteDesktop
Screen sharing in apps like Firefox, Chromium, OBS, and Teams on Wayland works entirely through org.freedesktop.portal.ScreenCast. On Wayland there is no global screen grabbing API, so portals are the only sanctioned path. The flow is:
- App requests a ScreenCast session via the portal.
- A picker dialog lets you choose a window or entire screen.
- The compositor hands back a PipeWire stream node ID.
- The app reads video frames from PipeWire—never directly from the display server.
This requires PipeWire to be running. On modern GNOME and KDE installations it runs by default. On wlroots compositors you may need to start it manually or via your session manager.
# Verify PipeWire is active
systemctl --user status pipewire pipewire-pulse
Inhibit
org.freedesktop.portal.Inhibit lets apps request that the system not suspend, dim, or lock the screen. A video player preventing screen blanking during playback is the canonical use-case. This portal has no visible UI—it either works silently or the screensaver kicks in anyway.
Notification
org.freedesktop.portal.Notification allows sandboxed apps to post desktop notifications through the native notification daemon. If Flatpak notifications are missing, a missing or misconfigured backend is the first thing to check.
Configuring Backend Selection
From xdg-desktop-portal 1.15+ you can explicitly map portal interfaces to specific backends using a config file. This is especially useful on wlroots compositors that don't set XDG_CURRENT_DESKTOP to a recognized value, or when you have multiple backends and want fine-grained control.
Create the config at ~/.config/xdg-desktop-portal/portals.conf:
mkdir -p ~/.config/xdg-desktop-portal
nano ~/.config/xdg-desktop-portal/portals.conf
A typical config for Sway (wlroots screen sharing, GTK file picker):
[preferred]
default=gtk
org.freedesktop.portal.ScreenCast=wlr
org.freedesktop.portal.RemoteDesktop=wlr
For Hyprland, which sets XDG_CURRENT_DESKTOP=Hyprland, the same approach works but you may want xdg-desktop-portal-hyprland (available in the AUR and some distro repos) which is a maintained fork of xdg-desktop-portal-wlr with Hyprland-specific fixes.
After editing, restart the portal service:
systemctl --user restart xdg-desktop-portal
Verifying Portals Are Working
The flatpak-portal-test tool from the Flatpak team is the clearest way to confirm portals are functional:
flatpak install flathub org.freedesktop.PortalTest
flatpak run org.freedesktop.PortalTest
Each button in the PortalTest UI exercises one portal interface. A successful FileChooser test opens your native file picker; a successful ScreenCast test starts a PipeWire stream.
You can also inspect what's running on D-Bus directly:
busctl --user list | grep freedesktop.portal
Expected output shows entries for org.freedesktop.portal.Desktop and at least one backend. If you see nothing, the service is not running—check the next section.
Troubleshooting
Portal service not starting
The front-end service is socket-activated via systemd user units. Check its status and logs:
systemctl --user status xdg-desktop-portal
journalctl --user -u xdg-desktop-portal -n 50
A common cause is a stale socket from a prior session. Kill the service and restart it:
systemctl --user stop xdg-desktop-portal
systemctl --user start xdg-desktop-portal
Screen sharing is a black screen or fails to start
On Wayland, confirm PipeWire is running and that XDG_CURRENT_DESKTOP is set correctly in your session. For wlroots compositors, this variable is often not set automatically—add it to your compositor's config or session startup file:
# For Sway: add to ~/.config/sway/config
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
Wrong backend is being used
If both xdg-desktop-portal-gnome and xdg-desktop-portal-gtk are installed, the front-end may pick the wrong one on non-GNOME desktops. Use the portals.conf method above to pin the backend explicitly, or remove the conflicting package.
Flatpak app ignores the portal file picker
Some older Flatpaks use a bundled GTK filechooser rather than the portal API. Check whether the app respects the --talk-name=org.freedesktop.portal.FileChooser Flatpak permission. If not, this is an upstream app bug—file a report with the app maintainer.
Frequently asked questions
- Do portals only matter for Flatpaks?
- Primarily yes, but any app that opts into the portal API benefits from them. Electron apps, Snaps, and even some native apps use portals for Wayland screen sharing and notifications.
- Why does screen sharing work in X11 but break on Wayland?
- X11 allows any process to read the entire display directly. Wayland forbids this by design, so screen sharing must go through the ScreenCast portal backed by PipeWire. If the portal or PipeWire is misconfigured, sharing fails entirely.
- Can I use xdg-desktop-portal-gtk on GNOME as a fallback?
- It was the standard backend before GNOME 43, but on modern GNOME you should use xdg-desktop-portal-gnome. The gtk backend lacks support for newer portal interfaces like dynamic launchers and account information.
- How do I tell which backend is actually handling a portal call?
- Run 'journalctl --user -u xdg-desktop-portal -f' while triggering the portal action. The log shows which backend was selected and any errors that occurred during the call.
- My compositor is not listed anywhere—what backend should I use?
- Install xdg-desktop-portal-gtk as a generic fallback for file picker, notifications, and inhibit. For screen sharing on any wlroots-based compositor, add xdg-desktop-portal-wlr and map the ScreenCast interface to it in portals.conf.
Related guides
Linux Clipboards Explained (+ Clipboard Managers)
Learn the difference between Linux's PRIMARY and CLIPBOARD selections, use xclip, xsel, and wl-clipboard from the terminal, and manage history with GPaste or Klipper.
Configure LibreOffice for Daily Use
Configure LibreOffice for daily use: set default save formats for MS Office interop, tune autosave, install fonts, and add productivity extensions.
Configure the Touchpad and Multitouch Gestures
Configure Linux touchpad behavior and multitouch gestures using libinput, libinput-gestures, and native GNOME and KDE Plasma settings on both Wayland and X11.
Wayland vs X11: How to Choose and Configure Each
Know when to run Wayland or X11, how to check your current session, switch at login with GDM/SDDM/LightDM, and handle NVIDIA and XWayland edge cases.