| DARKMAN(1) | General Commands Manual | DARKMAN(1) |
darkman — control
dark-mode and light-mode transitions
darkman |
[options] command |
darkman runs in the background and turns
on dark mode at sundown, and turns it off again at sunrise.
darkman is not designed to be used interactively:
it's designed to be set up once, and run in the background.
It is also possible to trigger manual transitions and it is also possible to disable automatic transitions entirely.
run
[--ready-fd fd]darkman service. This command is intended
to be executed by a service manager, init script or alike.
The optional fd is a file descriptor
where darkman will notify when it is ready to
receive connections from clients. The protocol used is compatible with
readiness notifications for s6, dinit and systemd.
set
⟨light |
dark⟩gettoggle--verbosetrue for the
run command and to false
for all other commands.See darkman.conf(5) for configuration file format and FILES for configuration file locations.
The open source desktop ecosystem is quite heterogeneous and making different applications switch between dark/light requires different mechanisms.
darkman seeks to implement the more widely
adopted standards, while leaving room for users to hook in custom scripts
for other applications.
darkman can run custom executables (which
can be simple shell scripts).
Scripts are searched in a directory named
darkman inside paths defined in the
XDG_DATA_DIRS as well as
XDG_DATA_HOME. Each script receives the current mode
(“dark or “light””) as
its first argument ($1). This allows a single script to handle both
modes:
#!/bin/sh case "$1" in dark) THEME=dark-theme ;; light) THEME=light-theme ;; esac gsettings set org.example.app theme "$THEME"
For backwards compatibility, darkman also
searches dark-mode.d and
light-mode.d directories (legacy format). Scripts in
these directories run without arguments. Scripts in the
darkman directory with the same name will override
legacy scripts.
Both of these variables and their fallbacks are defined in the XDG Base Directory Specification: https://specifications.freedesktop.org/basedir-spec/latest/
These scripts or executables can perform any actions required like re-write configuration files for a PDF reader, control a notification daemon to switch to another theme, or toggle a DE-specific setting.
Files must have the executable bit set in order to be considered an executable. Scripts must have the proper shebang for the OS to properly execute them.
Typically, the XDG_DATA_* variables
mentioned above will resolve to the following set of directories:
Example scripts (and discussion on how to integrate different applications) are available in the project repository: https://gitlab.com/WhyNotHugo/darkman
Packages may also drop-in their own scripts into any of these locations, although application developers are encouraged to use the socket API to determine the current mode and listen for changes (see below for details).
darkman implements the XDG desktop
portal's dark mode interface. Applications using this API should switch to
dark/light mode based on darkman's current
preference. This interface was originally pushed by the GNOME and Elementary
teams, and is currently supported by KDE, Firefox and many other projects.
You should expect applications from those environments to support it,
amongst others.
For more details on this protocol, see: https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Settings.html
As of xdg-desktop-portal(1) version 1.17.0,
portals MUST be configured with per-user configuration
portals.conf(5). To force the usage of
darkman for dark/light mode setting, use something
like the following:
[preferred] org.freedesktop.impl.portal.Settings=darkman
When using a desktop-specific configuration (e.g.:
swaywm-portals.conf), please keep in mind that the
environment variable XDG_CURRENT_DESKTOP must be set
for the xdg-desktop-portal(1).
The xdg-desktop-portal(1) should start after
darkman has started and is ready. Use
--ready-fd for readiness notification. This is
likely not relevant on systemd-based setups, where the service manager
intermediates in taking the named bus.
For a more in-depth explanation, see this article: https://whynothugo.nl/journal/2024/04/09/darkman-portal-configuration/
For Emacs users, a third party package exists to integrate
darkman with Emacs:
https://github.com/grtcdr/darkman.el
There also exists a plugin for neovim users: https://github.com/4e554c4c/darkman.nvim
The current location may be specified in the configuration file. The location is used to calculate what time sundown and sunrise happen.
It is also possible for darkman to
automatically determine the system's location using
geoclue(1). Geoclue's reliability varies depending on
distribution and desktop environment, as an agent often needs to be
configured for it to work properly.
If no location is known, automatic transitions are disabled.
The following environment variables are also read and will override the configuration file:
DARKMAN_LATDARKMAN_LNGXDG_CURRENT_DESKTOPdarkman does not use this variable; it should be
defined for the xdg-desktop-portal(1) instead.darkman searches for a configuration file
in the following locations, using the first one found:
XDG_CONFIG_DIRS, with
darkman/config.yaml appended.If XDG_CONFIG_HOME is not set, it defaults
to ~/.config. If
XDG_CONFIG_DIRS is not set, it defaults to
/etc/xdg.
See darkman.conf(5) for configuration file format.
darkman will trigger a darkmode/lightmode
transition at sundown in the current location. Any application that is
running locally can record or transmit the time of these transitions and
attempt to extrapolate information related to the current location.
When a web browser applies this transition at the same time, open websites can record this information too.
A potential stalker or tracker can use the above information to infer that you are likely in a region of the world where sunset happened at a specific time. This region is usually a wide area spanning tens of thousands of kilometers, but can be smaller for certain geographical locations.
The author of this tool uses a manually configured location with an integer latitude and longitude to achieve a sensible balance between privacy and convenience.
For issues and general development inquiries, see the project home currently hosted at GitLab: https://gitlab.com/WhyNotHugo/darkman
To confirm which value is relayed via the xdg-desktop-portal(1) use:
gdbus call --session \
--dest org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.portal.Settings.ReadOne \
org.freedesktop.appearance color-scheme
darkman.conf(5), darkman-ipc(5), portals.conf(5), gammastep(1), sd-ready-fd(1)
Developed by Hugo O. Barrera <hugo@whynothugo.nl>, with invaluable contributions from the community.
darkman is an open source project licensed
under the ISC licence and developed for anyone to use freely. If you would
like to sponsor this project, see:
https://whynothugo.nl/sponsor
| 2025-12-25 | Linux 6.18.37-0-lts |