Choose XDG Desktop Portal Backends with portals.conf
Write one portals.conf in the wrong place and the desktop quietly ignores your careful backend choice in favour of a vendor default you never see. You will create a per-user file that chooses a portal backend, gives one interface a different choice, and leaves an easy rollback. This guide describes the xdg-desktop-portal package version 1.18.4-1ubuntu2.24.04.3 installed on this machine. Allow about fifteen minutes. You need a graphical session, a shell, and a backend that is already installed.
The route
Jump straight to the step you need, or tick off Done means at the end.
The file selects implementations for portal interfaces such as file picking, opening links and screen capture. It does not install a backend, change Flatpak permissions, or make an unsupported backend implement an interface. The names in the examples are only useful when matching backend files are present on your system.
1. Check the session and available backends
Start by finding the desktop identity that portal selection uses. The value is normally supplied by the desktop session, so run this inside the session whose portals you want to change:
$ printf 'desktop: %s\n' "${XDG_CURRENT_DESKTOP:-unset}"
desktop: GNOME
$ command -v xdg-desktop-portal
/usr/bin/xdg-desktop-portal
Your desktop value will differ. XDG_CURRENT_DESKTOP is a colon-separated list, with the most specific name first, and each name is folded to lower case when it is turned into a filename. A value of Budgie:GNOME therefore makes the portal service try budgie-portals.conf, then gnome-portals.conf, then the generic portals.conf.
Look for backend registration files before choosing a name:
$ find /usr/share/flatpak/portals "$HOME/.local/share/flatpak/portals" \
-maxdepth 1 -type f -name '*.portal' -print 2>/dev/null
/usr/share/flatpak/portals/gtk.portal
/usr/share/flatpak/portals/gnome.portal
The exact directories and results depend on your installed packages. A name such as gtk in portals.conf refers to the backend identifier, not automatically to a package you can assume exists. If no suitable file is present, stop here and install or enable the backend through your normal distribution process.
2. Understand which file wins
- It is an INI file. Portal configuration uses a
[preferred]group. - Desktop-specific beats generic. For each search location, desktop-specific names are considered before the generic name.
- Search order matters. Locations are searched from highest to lowest precedence:
$XDG_CONFIG_HOME, the directories in$XDG_CONFIG_DIRS, the build-time system configuration directory, the data directories, and finally the build-time data directory. - Only the first file counts. With the usual defaults, a user file at
~/.config/xdg-desktop-portal/portals.confwins over a vendor file under/usr/share/xdg-desktop-portal, and lower-precedence files are not merged with it. This is the trap that makes a small user file unexpectedly hide a vendor default.
Checkpoint
Inspect possible user and system files before creating one:
$ printf 'user: %s\n' "${XDG_CONFIG_HOME:-$HOME/.config}/xdg-desktop-portal"
$ find "${XDG_CONFIG_HOME:-$HOME/.config}/xdg-desktop-portal" \
/etc/xdg/xdg-desktop-portal /usr/share/xdg-desktop-portal \
-maxdepth 1 -type f -name '*portals.conf' -print 2>/dev/null
If a desktop-specific file already exists in your user directory, edit or remove that file instead of assuming the generic file will be read.
3. Create a minimal per-user configuration
The least disruptive place to start is your user configuration directory. This changes no system file and needs no elevated privileges.
$ portal_dir="${XDG_CONFIG_HOME:-$HOME/.config}/xdg-desktop-portal"
$ mkdir -p "$portal_dir"
$ cp --preserve=mode,timestamps "$portal_dir/portals.conf" "$portal_dir/portals.conf.bak" 2>/dev/null || true
$ editor "$portal_dir/portals.conf"
Put a small configuration in the editor. Replace BACKEND_ID with an identifier you actually found, then replace SPECIAL_BACKEND_ID only if that backend implements screen capture:
[preferred]
default=BACKEND_ID
org.freedesktop.impl.portal.ScreenCast=SPECIAL_BACKEND_ID
defaultis used for every interface that has no explicit entry.- An interface entry takes precedence for that specific interface.
- A preference list can be semicolon-separated, for example
first;second, and the portal service searches it in order. *picks the first available implementation in lexicographical order, andnonedeliberately forces no implementation. Both are policy decisions that can make an application feature disappear.
Do not copy the example names blindly. A backend can be installed but still lack the interface you are overriding.
4. Add desktop-specific behaviour only when needed
If you use more than one desktop environment, a generic file applies too broadly. Use the lower-case desktop name from XDG_CURRENT_DESKTOP in the filename:
$ desktop_name="${XDG_CURRENT_DESKTOP%%:*}"
$ desktop_name="${desktop_name,,}"
$ printf '%s\n' "$desktop_name"
gnome
$ editor "$portal_dir/${desktop_name}-portals.conf"
For a session reporting Budgie:GNOME, the first possible desktop-specific file is budgie-portals.conf. The order is significant: a generic file is not combined with the desktop-specific file, and a file for a later desktop name cannot override an earlier one.
Keep one source of truth where practical. If you create both generic and desktop-specific files, write the complete intended [preferred] group in each file. This avoids forgetting that lower-precedence settings are ignored rather than inherited.
5. Inspect the result before restarting anything
Read back the exact file and check that it is an INI-shaped configuration with one preferred group:
$ sed -n '1,80p' "$portal_dir/portals.conf"
[preferred]
default=BACKEND_ID
org.freedesktop.impl.portal.ScreenCast=SPECIAL_BACKEND_ID
$ test "$(grep -c '^\[preferred\]$' "$portal_dir/portals.conf")" -eq 1 && \
echo 'preferred group present'
preferred group present
This check catches a wrong path or missing group; it cannot prove the backend implements every requested interface. Keep comments simple and avoid shell syntax in the configuration: the file is read as INI data, not as a script.
Do not use sudo for a per-user file. If an administrator is intentionally setting a system-wide default, the corresponding file belongs under /etc/xdg-desktop-portal and requires elevated privileges. Warn other users first because a system file affects their sessions and can hide vendor configuration. Back up the existing file before editing it.
6. Apply and diagnose the change
The manual documents file selection, not a universal reload command. Portal processes are commonly managed by the user session, D-Bus activation or the desktop environment. Close applications that use portals, then log out and back in if the new choice is not picked up. Avoid killing a shared user service while important file or screen-capture operations are running.
After the new session starts, repeat the session check and test the application feature you meant to change. If it fails, inspect the user journal without changing anything:
$ journalctl --user -b --no-pager | grep -iE 'portal|backend|screencast'
$ systemctl --user --no-pager --type=service | grep -i portal
A missing backend, an incorrect identifier, an unsupported interface or a hidden vendor file is more likely than a permissions problem. Compare the backend names with the installed .portal files. A non-zero result from grep only means no matching journal line was found; it is not proof that portal selection failed.
7. Roll back without guessing
If the change breaks a portal feature, restore the backup or remove only the user file you created. Do not delete a file you did not inspect first:
$ test -f "$portal_dir/portals.conf.bak" && \
cp --preserve=mode,timestamps "$portal_dir/portals.conf.bak" "$portal_dir/portals.conf"
$ rm -f "$portal_dir/${desktop_name}-portals.conf"
$ sed -n '1,80p' "$portal_dir/portals.conf" 2>/dev/null || echo 'no generic user override'
Start a fresh desktop session and test again. If there was no backup, removing your generic user override lets the next lower-precedence configuration be considered, provided one exists. The undo is limited to your configuration; it does not uninstall a backend or alter system files.
Done means
- Version and session recorded. You confirmed the installed
xdg-desktop-portalpackage version and your session'sXDG_CURRENT_DESKTOP. - Backends verified, not guessed. You chose backend identifiers that are present on the machine instead of guessing from package names.
- Configuration deliberate. Your file uses
[preferred], a deliberate default, and only the interface overrides you need. - Precedence understood. You understand that the first configuration file found wins and lower-precedence files are ignored.
- Checked and backed up. You checked the file before starting a fresh session and kept a rollback copy.
- Rollback ready. You can remove or restore the user override without touching the system configuration.