{pkgs, config, ...}:
let
inherit (pkgs.lib) mkOption mergeOneOption optionals filter concatMap concatMapStrings;
cfg = config.services.xserver;
xorg = cfg.package;
# file provided by services.xserver.displayManager.session.script
xsession = wm: dm: pkgs.writeText "xsession" ''
source /etc/profile
exec > $HOME/.Xerrors 2>&1
### Load X defaults.
if test -e ~/.Xdefaults; then
${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
fi
${if cfg.startSSHAgent then ''
### Start the SSH agent.
export SSH_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass
eval $(${pkgs.openssh}/bin/ssh-agent)
'' else ""}
### Allow user to override system-wide configuration
if test -f ~/.xsession; then
source ~/.xsession;
fi
# this script expect to have as first argument the following input
# "desktop-manager + window-manager".
arg="$1"
# extract the window manager.
windowManager="''${arg##* + }"
: ''${windowManager:=${cfg.windowManager.default}}
# extract the desktop manager.
desktopManager="''${arg% + *}"
: ''${desktopManager:=${cfg.desktopManager.default}}
# used to restart the xserver.
waitPID=0
# handle window manager starts.
case $windowManager in
${concatMapStrings (s: "
(${s.name})
${s.start}
;;
") wm}
(*) echo "$0: Window manager '$windowManager' not found.";;
esac
# handle desktop manager starts.
case $desktopManager in
${concatMapStrings (s: "
(${s.name})
${s.start}
;;
") dm}
(*) echo "$0: Desktop manager '$desktopManager' not found.";;
esac
test "$waitPID" != 0 && wait "$waitPID"
exit
'';
in
{
# list of display managers.
require = [
(import ./slim.nix)
];
services = {
xserver = {
displayManager = {
xauthBin = mkOption {
default = "${xorg.xauth}/bin/xauth";
description = "
Path to the xauth binary used by display managers.
";
};
xserverBin = mkOption {
default = "${xorg.xorgserver}/bin/X";
description = "
Path to the xserver binary used by display managers.
";
};
xserverArgs = mkOption {
default = [];
example = [
"-ac"
"-logverbose"
"-nolisten tcp"
];
description = "
List of arguments which have to be pass to when
the display manager start the xserver.
";
apply = toString;
};
session = mkOption {
default = [];
example = [
{
manage = "desktop";
name = "xterm";
start = "
${pkgs.xterm}/bin/xterm -ls &
waitPID=$!
";
}
];
description = ''
List of session supported with the command used to start each
session. Each session script can set the
waitPID shell variable to make this script
waiting until the end of the user session. Each script is used
to define either a windows manager or a desktop manager. These
can be differentiated by setting the attribute
manage either to "window"
or "desktop".
The list of desktop manager and window manager should appear
inside the display manager with the desktop manager name
followed by the window manager name.
'';
apply = list: rec {
wm = filter (s: s.manage == "window") list;
dm = filter (s: s.manage == "desktop") list;
names = concatMap (d: map (w: d.name + " + " + w.name) wm) dm;
script = xsession wm dm;
};
};
job = mkOption {
default = {};
example = {
beforeScript = ''
rm -f /var/log/slim.log
'';
env = ''
env SLIM_CFGFILE=/etc/slim.conf
'';
execCmd = "${pkgs.slim}/bin/slim";
};
description = "
List of arguments which have to be pass to when
the display manager start the xserver.
";
merge = mergeOneOption;
};
};
};
};
}