‹ back home

Darkman portal configuration

2024-04-09 #darkman #desktop #linux

Since early 2022, darkman supports exposing the dark mode / light mode preference via the appropriate xdg-desktop-portal API. While this works quite well, it’s been a constant source of questions, since setting it up and actually understanding how it works is far from trivial.

The xdg-desktop-portal is a kitchen-sink service1, which implements dozens of unrelated functionalities mashed together. Some of these features are implemented directly in the portal, while others are delegated to portal implementations.

One of the features implemented by the xdg-desktop-portal is the settings interface. This interface exposes settings to local user applications. Amongst a few other values, it exposes a color-scheme preference, which can be either dark mode, light mode, or “no preference”.

However, the xdg-desktop-portal itself isn’t the source of this information; it queries portal implementations for the correct value. Which portal implementation it uses requires careful configuration, and this is the main source of confusion.

There are several ways to configure which portal implementation is used.

Configuration files can exist in system-wide locations, or user-specific locations. I’ll only cover user-specific locations here; if you need to configure something system-wide for multiple users, consult man 5 portals.conf for additional details.

Depending on the filename given to the configuration file, it will apply only to specific desktop environments (e.g.: kde-portals.conf would only apply on KDE) or apply to any environment (e.g.: portals.conf will be used by default on any desktop environment unless a desktop-specific configuration is found)

I prefer using portals.conf, since my user account always runs sway and I don’t need per-DE functionality for it. If you use your same user account with different compositors or DEs, you’ll need to take the other approach.

A single configuration file

The most straightforward location for a user configuration is ~/.config/xdg-desktop-portal/portals.conf, which overrides other directories.

To use darkman as a source for settings (which results in its dark / light mode value being exposed), the following configuration would suffice:


In my case, I also configure the xdg-desktop-portal to use xdp-wlr for screen casting (this in turn is used by Firefox). My real configuration file currently looks like this:


If you are using a distribution with a pre-configured desktop environment, when you create a configuration file it will completely override the system-wide configuration. You may need to copy-paste any lines from the system-wide configuration file into your own to retain existing integrations.

Per-DE configuration files

I mentioned before that it is possible to create per-DE configuration files.

For example, if you need to support both sway and KDE, you’ll need two configuration files2:

Creating the files alone isn’t enough: the xdg-desktop-portal needs to know which desktop you are currently running. This is configured via the XDG_CURRENT_DESKTOP environment variable, which must be set for the xdg-desktop-portal process itself. If you are using a service manager, you need to inject this variable into the environment that it creates for services. If you are starting the service manually, you can just export it with the usual mechanisms.

For the above two example, this variable should be defined as XDG_CURRENT_DESKTOP=sway or XDG_CURRENT_DESKTOP=kde respectively.


Darkman doesn’t care about the value of XDG_CURRENT_DESKTOP. It will expose its portal implementation bus in org.freedesktop.impl.portal.desktop.darkman. When the xdg-desktop-portal is configured with org.freedesktop.impl.portal.Settings=darkman, it will query darkman’s bus for settings.

Darkman will only respond to queries for the color-scheme preference.

Start-up order

The XDG_CURRENT_DESKTOP variable needs to be defined in the execution environment of xdg-desktop-portal. If it starts during early session initialisation, ensure that the ordering is as expected.

The xdg-desktop-portal will try to communicate with configured portal implementations (e.g.: darkman) as soon as it starts.

When dbus-daemon is configured to auto-start services (this is the default), then it will start darkman immediately.

If you are using a service manager to start these service, you should consider darkman a dependency of xdg-desktop-portal. In this case, darkman must start and be ready before the xdg-desktop-portal starts.

  1. I find the general design of the xdg-desktop-portal quite poor. It’s the far opposite of “do one thing and do it well”; it does dozens of things in highly opinionated ways, and is quite coupled with several other systems. ↩︎

  2. Keep in mind that other locations are searched if these do not exist. Again, see man 5 portals.conf for full details. ↩︎

Have comments or want to discuss this topic?
Send an email to ~whynothugo/public-inbox@lists.sr.ht (mailing list etiquette)

— § —