nixos/displayManager: Create a common environment wrapper for all dms

This makes it easier to support a wider variety of .desktop session files. In
particular this makes it possible to use both the «legacy» sessions and upstream
session files.

We separate `xsession` into two parts, `xsessionWrapper` and `xsession`.
`xsessionWrapper` sets up the correct environment and then lauches the session's
Exec command (from the .desktop file), falling back to launching the default
window/desktopManager through the `xsession` script (required by at least some
nixos tests).

`xsession` then _only_ handles launching desktop-managers/window-managers defined
through `services.xserver.desktopManager.session`.

Changed files
+35 -42
nixos
modules
services
+31 -38
nixos/modules/services/x11/display-managers/default.nix
···
Xft.hintstyle: hintslight
'';
-
# file provided by services.xserver.displayManager.session.script
-
xsession = wm: dm: pkgs.writeScript "xsession"
+
# file provided by services.xserver.displayManager.session.wrapper
+
xsessionWrapper = pkgs.writeScript "xsession-wrapper"
''
#! ${pkgs.bash}/bin/bash
-
# Expected parameters:
-
# $1 = <desktop-manager>+<window-manager>
-
-
# Actual parameters (FIXME):
-
# SDDM is calling this script like the following:
-
# $1 = /nix/store/xxx-xsession (= $0)
-
# $2 = <desktop-manager>+<window-manager>
-
# SLiM is using the following parameter:
-
# $1 = /nix/store/xxx-xsession <desktop-manager>+<window-manager>
-
# LightDM keeps the double quotes:
-
# $1 = /nix/store/xxx-xsession "<desktop-manager>+<window-manager>"
-
# The fake/auto display manager doesn't use any parameters and GDM is
-
# broken.
-
# If you want to "debug" this script don't print the parameters to stdout
-
# or stderr because this script will be executed multiple times and the
-
# output won't be visible in the log when the script is executed for the
-
# first time (e.g. append them to a file instead)!
-
-
# All of the above cases are handled by the following hack (FIXME).
-
# Since this line is *very important* for *all display managers* it is
-
# very important to test changes to the following line with all display
-
# managers:
-
if [ "''${1:0:1}" = "/" ]; then eval exec "$1" "$2" ; fi
-
-
# Now it should be safe to assume that the script was called with the
-
# expected parameters.
+
# Shared environment setup for graphical sessions.
. /etc/profile
cd "$HOME"
-
-
# The first argument of this script is the session type.
-
sessionType="$1"
-
if [ "$sessionType" = default ]; then sessionType=""; fi
${optionalString cfg.startDbusSession ''
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
-
exec ${pkgs.dbus.dbus-launch} --exit-with-session "$0" "$sessionType"
+
exec ${pkgs.dbus.dbus-launch} --exit-with-session "$0" "$@"
fi
''}
${optionalString cfg.displayManager.job.logToJournal ''
if [ -z "$_DID_SYSTEMD_CAT" ]; then
export _DID_SYSTEMD_CAT=1
-
exec ${config.systemd.package}/bin/systemd-cat -t xsession "$0" "$sessionType"
+
exec ${config.systemd.package}/bin/systemd-cat -t xsession "$0" "$@"
fi
''}
···
${config.systemd.package}/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
# Load X defaults.
+
# FIXME: Check XDG_SESSION_TYPE against x11
${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft}
if test -e ~/.Xresources; then
${xorg.xrdb}/bin/xrdb -merge ~/.Xresources
···
# Allow the user to setup a custom session type.
if test -x ~/.xsession; then
exec ~/.xsession
+
fi
+
+
if test "$1"; then
+
# Run the supplied session command. Remove any double quotes with eval.
+
eval exec "$@"
else
-
if test "$sessionType" = "custom"; then
-
sessionType="" # fall-thru if there is no ~/.xsession
-
fi
+
# Fall back to the default window/desktopManager
+
exec ${cfg.displayManager.session.script}
fi
+
'';
+
+
# file provided by services.xserver.displayManager.session.script
+
xsession = wm: dm: pkgs.writeScript "xsession"
+
''
+
#! ${pkgs.bash}/bin/bash
+
+
# Legacy session script used to construct .desktop files from
+
# `services.xserver.displayManager.session` entries. Called from
+
# `sessionWrapper`.
+
+
# Expected parameters:
+
# $1 = <desktop-manager>+<window-manager>
+
+
# The first argument of this script is the session type.
+
sessionType="$1"
+
if [ "$sessionType" = default ]; then sessionType=""; fi
# The session type is "<desktop-manager>+<window-manager>", so
# extract those (see:
···
Type=XSession
TryExec=${cfg.displayManager.session.script}
Exec=${cfg.displayManager.session.script} "${n}"
-
X-GDM-BypassXsession=true
Name=${n}
Comment=
EODESKTOP
···
(filter (w: d.name != "none" || w.name != "none") wm));
desktops = mkDesktops names;
script = xsession wm dm;
+
wrapper = xsessionWrapper;
};
};
+1 -1
nixos/modules/services/x11/display-managers/gdm.nix
···
${optionalString cfg.gdm.debug "Enable=true"}
'';
-
environment.etc."gdm/Xsession".source = "${pkgs.gnome3.gdm}/etc/gdm/Xsession";
+
environment.etc."gdm/Xsession".source = config.services.xserver.displayManager.session.wrapper;
# GDM LFS PAM modules, adapted somehow to NixOS
security.pam.services = {
+1 -1
nixos/modules/services/x11/display-managers/lightdm.nix
···
[Seat:*]
xserver-command = ${xserverWrapper}
-
session-wrapper = ${dmcfg.session.script}
+
session-wrapper = ${dmcfg.session.wrapper}
${optionalString cfg.greeter.enable ''
greeter-session = ${cfg.greeter.name}
''}
+1 -1
nixos/modules/services/x11/display-managers/sddm.nix
···
MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)}
ServerPath=${xserverWrapper}
XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr
-
SessionCommand=${dmcfg.session.script}
+
SessionCommand=${dmcfg.session.wrapper}
SessionDir=${dmcfg.session.desktops}/share/xsessions
XauthPath=${pkgs.xorg.xauth}/bin/xauth
DisplayCommand=${Xsetup}
+1 -1
nixos/modules/services/x11/display-managers/slim.nix
···
default_xserver ${dmcfg.xserverBin}
xserver_arguments ${toString dmcfg.xserverArgs}
sessiondir ${dmcfg.session.desktops}/share/xsessions
-
login_cmd exec ${pkgs.runtimeShell} ${dmcfg.session.script} "%session"
+
login_cmd exec ${pkgs.runtimeShell} ${dmcfg.session.wrapper} "%session"
halt_cmd ${config.systemd.package}/sbin/shutdown -h now
reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
logfile /dev/stderr