In the following example, sddm
will be used as a display manager. The process is however similar for other display managers in nixpkgs and a summary that applies to all nixpkgs display managers is given at the end.
-
Systemd unit "display-manager.service" starts
services.x11.displayManager.job.execCmd
(the display manager)Code reference:
<nixpkgs>/nixos/modules/services/x11/xserver.nix
-
services.x11.displayManager.job.execCmd
is set to the path of thesddm
binary from thesddm
package in the nix store. So SDDM will start and read its configuration from/etc/sddm.conf
.Code reference:
<nixpkgs>/nixos/modules/services/x11/display-managers/sddm.nix
-
/etc/sddm.conf
sets three important options:- it sets the path to the xserver executable to a wrapper script that prepares the environment. In particular, the wrapper will run
services.x11.displayManager.xserverBin
, adding the argumentsservices.x11.displayManager.xserverArgs
before any additional arguments specified when running the wrapper. The wrapper will also export the environment variables specified insystemd.services."display-manager".environment
before executing the xserver. - It sets the directory to search for sessions to
services.x11.displayManager.desktops
. This is an automatically generated directory that contains a ".desktop" file for each possible session with more information about the session. For each desktop file, theExec
option is set to${services.x11.displayManager.session.script} <session name>
, so that script will be executed when the session should be started. - It sets the script to launch a session to
services.x11.displayManager.session.script
. This script is executed to start the session on a successful user login. Because of the ability to choose between different sessions (for example, between a gnome and a kde session), this script is passed the value of theExec
option of the selected session as an argument.
Code reference:
<nixpkgs>/nixos/modules/services/x11/display-managers/sddm.nix
- it sets the path to the xserver executable to a wrapper script that prepares the environment. In particular, the wrapper will run
-
After reading the configuration, SDDM will start the XServer using the command set in the configuration file explained above. SDDM will handle the authentication of users (how users are authenticated can be configured though PAM), and on successful logins, the session script will be executed after changing to the user's account. Thus, the session script does not need to handle starting of the XServer itself, since it simply gains access to the XServer that SDDM started already.
-
The session script has a special case for when the argument is a path: in that case, it just executes the argument. So combined with point 3, that means when a session is started, the command specified in the
Exec
property of the session's desktop file is executed.
After a successful login, the display manager will execute the following command as the user who was logged in:
${services.x11.displayManager.session.script} <session name>
where session name
is the name of the session that you selected when logging in, which uniquely identifies the window manager and the desktop manager that shall be used for this session. For example, a typical session name looks like kde + xmonad
. How these sessions are generated and what the session script does is explained in the next sections.
In nixpkgs, a session is always a combination of a window manager (such as xmonad, awesome, openbox, ...) and a desktop manager (such as kde, gnome, ...). Either of those may be "none", to signal that this session has no desktop manager or no window manager. The name of a session is <desktop manager name> + <window manager name>
, where the + <window manager name>
part is omitted if the window manager is "none".
The list of available window managers and desktop managers is stored in the nixos option services.x11.displayManager.session
. Each entry in this list is a set with three attributes: name
, manage
(either "desktop" or "window") and start
, which specifies the script that is executed to start this entry.
Code reference: <nixpkgs>/nixos/modules/x11/display-managers/default.nix
This list automatically the "none" desktop manager and window manager plus all enabled window managers (stored in services.x11.windowManager.session
, to which each window manager adds itself if is enabled) and all enabled desktop managers (stored services.x11.desktopManager.session
).
Code references:
<nixpkgs>/nixos/modules/services/x11/desktop-managers/default.nix
<nixpkgs>/nixos/modules/services/x11/window-managers/default.nix
What actually happens if a session is started is explained in the next section.
As explained in the first section, when a session is started, the session script will be executed. The full session script can be found at <nixpkgs>/nixos/modules/services/x11/display-manager/default.nix
, the following text will summarize the most important parts.
- First, some general setup is performed. This includes sourcing
/etc/profile
, setting up logging (either to~/.xsession-errors
or to systemd journal ifservices.x11.displayManager.logToJournal
is true), and parsing the arguments to get the name of the session to be started. You can look at the source to find out in detail what is happening in this phase. - After setting up the environment, the commands in specified in the nixos option
services.x11.displayManager.sessionCommands
are executed. - The file
~/.xprofile
is sourced if it exists. If~/.xsession
exists, that file isexec
'd, so the session script hands over control to that script. Otherwise, it continues. - If the session name is either "default" or "custom", it is set to "".
- The name of the desktop manager and the name of the window manager is extracted from the name of the session. This is done by splitting the session name on the first
+
(enclosed by spaces), everything before that is considered the desktop manager name and everything after that is the window manager name. If after this, the desktop manager name is empty (this happens if the session name is "default" or "custom" and was thus in step 4 set to "" so the part before any "+" is empty), then it is set to the default, specified by nixos optionservices.x11.desktopManager.default
. The same applies if the window manager name is empty (happens if the session name contains no+
), in this caseservices.x11.windowManager.default
specifies the default. - Now, the script executes the
start
script of the extracted window manager and then thestart
script of the extracted desktop manager. After that, it waits till the process with the PID stored in the variable$waitPID
exits, if$waitPID
is set (this variable should be set by either the desktop manager or the window manager start script, if those scripts don't block till the session is finished).
- The module never generates a session for starting a desktop manager without a window manager. The combination
<desktop manager> + none
is never generated, sincenone
is stripped from the session name and it becomes<desktop manager>
instead, which causes the default window manager to be used.