NOTE: This document is a work-in-progress.
systemd only supports running one graphical session per user at a time. While this might not have always been the case historically, having multiple sessions for one user running at the same time is problematic. The DBus session bus is shared between all the logins, and services that are started must be implicitly assigned to the user’s current graphical session.
In principle it is possible to run a single graphical session across multiple logind seats, and this could be a way to use more than one display per user. When a user logs in to a second seat, the seat resources could be assigned to the existing session, allowing the graphical environment to present it is a single seat. Currently nothing like this is supported or even planned.
systemd.special(7)
defines the graphical-session.target
and graphical-session-pre.target
to
allow cross-desktop integration. Furthermore, systemd defines the three base
slices background
, app
and session
.
All units should be placed into one of these slices depending on their purposes:
session.slice
: Contains only processes essential to run the user’s graphical sessionapp.slice
: Contains all normal applications that the user is runningbackground.slice
: Useful for low-priority background tasksThe purpose of this grouping is to assign different priorities to the applications. This could e.g. mean reserving memory to session processes, preferentially killing background tasks in out-of-memory situations or assigning different memory/CPU/IO priorities to ensure that the session runs smoothly under load.
TODO: Will there be a default to place units into e.g. app.slice
by default
rather than the root slice?
To ensure cross-desktop compatibility and encourage sharing of good practices, desktop environments should adhere to the following conventions:
app[-<launcher>]-<ApplicationID>[@<RANDOM>].service
or app[-<launcher>]-<ApplicationID>-<RANDOM>.scope
e.g:
app-gnome-org.gnome.Evince@12345.service
app-flatpak-org.telegram.desktop@12345.service
app-KDE-org.kde.okular@12345.service
app-org.kde.amarok.service
app-org.gnome.Evince-12345.scope
Using .service
units instead of .scope
units, i.e. allowing systemd to
start the process on behalf of the caller,
instead of the caller starting the process and letting systemd know about it,
is encouraged.
<RANDOM>
should be a string of random characters to ensure that multiple instances
of the application can be launched. This can be omitted for service files of
non-transient applications, which ensure multiple instances cannot be
spawned. For scope files <RANDOM>
is mandatory, as the format would be
ambiguous otherwise.
basename(argv[0])
). This name must not
contain a -
character.This has the following advantages:
Using the app-<launcher>-
prefix means that the unit defaults can be
adjusted using desktop environment specific drop-in files.
The application ID can be retrieved by stripping the prefix and postfix.
This in turn should map to the corresponding .desktop
file when available.
Note that this naming scheme might be a unit alias, so runtime detection must check the entire name-array of a unit, rather than just its unit ID.
TODO: Define the name of slices that should be used.
This could be app-<launcher>-<ApplicationID>-<RANDOM>.slice
.
TODO: Does it really make sense to insert the <launcher>
? In GNOME I am
currently using a drop-in to configure BindTo=graphical-session.target
,
CollectMode=inactive-or-failed
and TimeoutSec=5s
.
I feel that such a policy makes sense, but it may make much more sense to just define a
global default for all (graphical) applications.
app-.service.d
drop-in configuration?To allow XDG autostart integration, systemd ships a cross-desktop generator
to create appropriate units for the autostart directory
(systemd-xdg-autostart-generator
).
Desktop Environments can opt-in to using this by starting xdg-desktop-autostart.target
.
The systemd generator correctly handles OnlyShowIn=
and NotShowIn=
.
It also handles the KDE and GNOME specific X-KDE-autostart-condition=
and AutostartCondition=
by using desktop-environment-provided binaries in an ExecCondition=
line.
However, this generator is somewhat limited in what it supports.
For example, all generated units will have After=graphical-session.target
set on them,
and therefore may not be useful to start session services.
Desktop files can be marked to be explicitly excluded from the generator using the line
X-systemd-skip=true
.
This should be set if an application provides its own systemd service file for startup.
Question here are:
gnome-session-shutdown.target
that is run with replace-irreversibly
considered a good practice?