0
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-13 21:50:33 +03:00

Merge pull request #53843 from hedning/session-default

nixos/displayManager: introduce defaultSession
This commit is contained in:
Jan Tojnar 2019-12-18 21:16:06 +01:00 committed by GitHub
commit 6be14ee97b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 305 additions and 224 deletions

View file

@ -83,8 +83,7 @@
desktop environment. If you wanted no desktop environment and i3 as your your desktop environment. If you wanted no desktop environment and i3 as your your
window manager, you'd define: window manager, you'd define:
<programlisting> <programlisting>
<xref linkend="opt-services.xserver.desktopManager.default"/> = "none"; <xref linkend="opt-services.xserver.displayManager.defaultSession"/> = "none+i3";
<xref linkend="opt-services.xserver.windowManager.default"/> = "i3";
</programlisting> </programlisting>
And, finally, to enable auto-login for a user <literal>johndoe</literal>: And, finally, to enable auto-login for a user <literal>johndoe</literal>:
<programlisting> <programlisting>

View file

@ -7,9 +7,8 @@
<para> <para>
To enable the Xfce Desktop Environment, set To enable the Xfce Desktop Environment, set
<programlisting> <programlisting>
<link linkend="opt-services.xserver.desktopManager.default">services.xserver.desktopManager</link> = { <xref linkend="opt-services.xserver.desktopManager.xfce.enable" /> = true;
<link linkend="opt-services.xserver.desktopManager.xfce.enable">xfce.enable</link> = true; <xref linkend="opt-services.xserver.displayManager.defaultSession" /> = "xfce";
<link linkend="opt-services.xserver.desktopManager.default">default</link> = "xfce";
}; };
</programlisting> </programlisting>
</para> </para>

View file

@ -55,6 +55,19 @@
and adding a <option>--all</option> option which prints all options and their values. and adding a <option>--all</option> option which prints all options and their values.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<option>services.xserver.desktopManager.default</option> and <option>services.xserver.windowManager.default</option> options were replaced by a single <xref linkend="opt-services.xserver.displayManager.defaultSession"/> option to improve support for upstream session files. If you used something like:
<programlisting>
services.xserver.desktopManager.default = "xfce";
services.xserver.windowManager.default = "icewm";
</programlisting>
you should change it to:
<programlisting>
services.xserver.displayManager.defaultSession = "xfce+icewm";
</programlisting>
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>

View file

@ -262,9 +262,8 @@ in rec {
virtualisation.memorySize = 1024; virtualisation.memorySize = 1024;
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.auto.enable = true; services.xserver.displayManager.auto.enable = true;
services.xserver.windowManager.default = "icewm"; services.xserver.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true; services.xserver.windowManager.icewm.enable = true;
services.xserver.desktopManager.default = "none";
}; };
in in
runInMachine ({ runInMachine ({

View file

@ -249,9 +249,8 @@ in rec {
virtualisation.memorySize = 1024; virtualisation.memorySize = 1024;
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.auto.enable = true; services.xserver.displayManager.auto.enable = true;
services.xserver.windowManager.default = "icewm"; services.xserver.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true; services.xserver.windowManager.icewm.enable = true;
services.xserver.desktopManager.default = "none";
}; };
in in
runInMachine ({ runInMachine ({

View file

@ -24,6 +24,7 @@ let
swayJoined = pkgs.symlinkJoin { swayJoined = pkgs.symlinkJoin {
name = "sway-joined"; name = "sway-joined";
paths = [ swayWrapped swayPackage ]; paths = [ swayWrapped swayPackage ];
passthru.providedSessions = [ "sway" ];
}; };
in { in {
options.programs.sway = { options.programs.sway = {
@ -88,7 +89,7 @@ in {
fonts.enableDefaultFonts = mkDefault true; fonts.enableDefaultFonts = mkDefault true;
programs.dconf.enable = mkDefault true; programs.dconf.enable = mkDefault true;
# To make a Sway session available if a display manager like SDDM is enabled: # To make a Sway session available if a display manager like SDDM is enabled:
services.xserver.displayManager.extraSessionFilePackages = [ swayJoined ]; services.xserver.displayManager.sessionPackages = [ swayJoined ];
}; };
meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ]; meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ];

View file

@ -86,23 +86,14 @@ in
}; };
default = mkOption { default = mkOption {
type = types.str; type = types.nullOr types.str;
default = ""; default = null;
example = "none"; example = "none";
description = "Default desktop manager loaded if none have been chosen."; description = ''
apply = defaultDM: <emphasis role="strong">Deprecated</emphasis>, please use <xref linkend="opt-services.xserver.displayManager.defaultSession"/> instead.
if defaultDM == "" && cfg.session.list != [] then
(head cfg.session.list).name Default desktop manager loaded if none have been chosen.
else if any (w: w.name == defaultDM) cfg.session.list then '';
defaultDM
else
builtins.trace ''
Default desktop manager (${defaultDM}) not found at evaluation time.
These are the known valid session names:
${concatMapStringsSep "\n " (w: "services.xserver.desktopManager.default = \"${w.name}\";") cfg.session.list}
It's also possible the default can be found in one of these packages:
${concatMapStringsSep "\n " (p: p.name) config.services.xserver.displayManager.extraSessionFilePackages}
'' defaultDM;
}; };
}; };

View file

@ -144,7 +144,7 @@ in
services.gnome3.core-shell.enable = true; services.gnome3.core-shell.enable = true;
services.gnome3.core-utilities.enable = mkDefault true; services.gnome3.core-utilities.enable = mkDefault true;
services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ]; services.xserver.displayManager.sessionPackages = [ pkgs.gnome3.gnome-session ];
environment.extraInit = '' environment.extraInit = ''
${concatMapStrings (p: '' ${concatMapStrings (p: ''
@ -171,7 +171,7 @@ in
}) })
(mkIf flashbackEnabled { (mkIf flashbackEnabled {
services.xserver.displayManager.extraSessionFilePackages = map services.xserver.displayManager.sessionPackages = map
(wm: pkgs.gnome3.gnome-flashback.mkSessionForWm { (wm: pkgs.gnome3.gnome-flashback.mkSessionForWm {
inherit (wm) wmName wmLabel wmCommand; inherit (wm) wmName wmLabel wmCommand;
}) (optional cfg.flashback.enableMetacity { }) (optional cfg.flashback.enableMetacity {

View file

@ -69,7 +69,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.xserver.displayManager.extraSessionFilePackages = [ pkgs.pantheon.elementary-session-settings ]; services.xserver.displayManager.sessionPackages = [ pkgs.pantheon.elementary-session-settings ];
# Ensure lightdm is used when Pantheon is enabled # Ensure lightdm is used when Pantheon is enabled
# Without it screen locking will be nonfunctional because of the use of lightlocker # Without it screen locking will be nonfunctional because of the use of lightlocker
@ -81,9 +81,9 @@ in
services.xserver.displayManager.lightdm.greeters.pantheon.enable = mkDefault true; services.xserver.displayManager.lightdm.greeters.pantheon.enable = mkDefault true;
# If not set manually Pantheon session cannot be started # Without this, Elementary LightDM greeter will pre-select non-existent `default` session
# Known issue of https://github.com/NixOS/nixpkgs/pull/43992 # https://github.com/elementary/greeter/issues/368
services.xserver.desktopManager.default = mkForce "pantheon"; services.xserver.displayManager.defaultSession = "pantheon";
services.xserver.displayManager.sessionCommands = '' services.xserver.displayManager.sessionCommands = ''
if test "$XDG_CURRENT_DESKTOP" = "Pantheon"; then if test "$XDG_CURRENT_DESKTOP" = "Pantheon"; then

View file

@ -118,7 +118,7 @@ in {
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.xserver.displayManager.extraSessionFilePackages = [ services.xserver.displayManager.sessionPackages = [
pkgs.surf-display pkgs.surf-display
]; ];

View file

@ -0,0 +1,39 @@
{ accountsservice
, glib
, gobject-introspection
, python3
, wrapGAppsHook
}:
python3.pkgs.buildPythonApplication {
name = "set-session";
format = "other";
src = ./set-session.py;
dontUnpack = true;
strictDeps = false;
nativeBuildInputs = [
wrapGAppsHook
gobject-introspection
];
buildInputs = [
accountsservice
glib
];
propagatedBuildInputs = with python3.pkgs; [
pygobject3
ordered-set
];
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/set-session
chmod +x $out/bin/set-session
'';
}

View file

@ -27,16 +27,7 @@ let
Xft.hintstyle: hintslight Xft.hintstyle: hintslight
''; '';
mkCases = session: # file provided by services.xserver.displayManager.sessionData.wrapper
concatStrings (
mapAttrsToList (name: starts: ''
(${name})
${concatMapStringsSep "\n " (n: n.start) starts}
;;
'') (lib.groupBy (n: n.name) session)
);
# file provided by services.xserver.displayManager.session.wrapper
xsessionWrapper = pkgs.writeScript "xsession-wrapper" xsessionWrapper = pkgs.writeScript "xsession-wrapper"
'' ''
#! ${pkgs.bash}/bin/bash #! ${pkgs.bash}/bin/bash
@ -116,94 +107,44 @@ let
# Run the supplied session command. Remove any double quotes with eval. # Run the supplied session command. Remove any double quotes with eval.
eval exec "$@" eval exec "$@"
else else
# Fall back to the default window/desktopManager # TODO: Do we need this? Should not the session always exist?
exec ${cfg.displayManager.session.script} echo "error: unknown session $1" 1>&2
exit 1
fi fi
''; '';
# file provided by services.xserver.displayManager.session.script installedSessions = pkgs.runCommand "desktops"
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:
# http://wiki.bash-hackers.org/syntax/pe#substring_removal).
windowManager="''${sessionType##*+}"
: ''${windowManager:=${cfg.windowManager.default}}
desktopManager="''${sessionType%%+*}"
: ''${desktopManager:=${cfg.desktopManager.default}}
# Start the window manager.
case "$windowManager" in
${mkCases wm}
(*) echo "$0: Window manager '$windowManager' not found.";;
esac
# Start the desktop manager.
case "$desktopManager" in
${mkCases dm}
(*) echo "$0: Desktop manager '$desktopManager' not found.";;
esac
${optionalString cfg.updateDbusEnvironment ''
${lib.getBin pkgs.dbus}/bin/dbus-update-activation-environment --systemd --all
''}
test -n "$waitPID" && wait "$waitPID"
${config.systemd.package}/bin/systemctl --user stop graphical-session.target
exit 0
'';
# Desktop Entry Specification:
# - https://standards.freedesktop.org/desktop-entry-spec/latest/
# - https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
mkDesktops = names: pkgs.runCommand "desktops"
{ # trivial derivation { # trivial derivation
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
} }
'' ''
mkdir -p "$out/share/xsessions" mkdir -p "$out/share/"{xsessions,wayland-sessions}
${concatMapStrings (n: ''
cat - > "$out/share/xsessions/${n}.desktop" << EODESKTOP
[Desktop Entry]
Version=1.0
Type=XSession
TryExec=${cfg.displayManager.session.script}
Exec=${cfg.displayManager.session.script} "${n}"
Name=${n}
Comment=
EODESKTOP
'') names}
${concatMapStrings (pkg: '' ${concatMapStrings (pkg: ''
for n in ${concatStringsSep " " pkg.providedSessions}; do
if ! test -f ${pkg}/share/wayland-sessions/$n.desktop -o \
-f ${pkg}/share/xsessions/$n.desktop; then
echo "Couldn't find provided session name, $n.desktop, in session package ${pkg.name}:"
echo " ${pkg}"
return 1
fi
done
if test -d ${pkg}/share/xsessions; then if test -d ${pkg}/share/xsessions; then
${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions
fi fi
'') cfg.displayManager.extraSessionFilePackages}
${concatMapStrings (pkg: ''
if test -d ${pkg}/share/wayland-sessions; then if test -d ${pkg}/share/wayland-sessions; then
mkdir -p "$out/share/wayland-sessions"
${xorg.lndir}/bin/lndir ${pkg}/share/wayland-sessions $out/share/wayland-sessions ${xorg.lndir}/bin/lndir ${pkg}/share/wayland-sessions $out/share/wayland-sessions
fi fi
'') cfg.displayManager.extraSessionFilePackages} '') cfg.displayManager.sessionPackages}
''; '';
dmDefault = cfg.desktopManager.default;
wmDefault = cfg.windowManager.default;
defaultSessionFromLegacyOptions = concatStringsSep "+" (filter (s: s != null) ([ dmDefault ] ++ optional (wmDefault != "none") wmDefault));
in in
{ {
@ -261,11 +202,24 @@ in
''; '';
}; };
extraSessionFilePackages = mkOption { sessionPackages = mkOption {
type = types.listOf types.package; type = with types; listOf (package // {
description = "package with provided sessions";
check = p: assertMsg
(package.check p && p ? providedSessions
&& p.providedSessions != [] && all isString p.providedSessions)
''
Package, '${p.name}', did not specify any session names, as strings, in
'passthru.providedSessions'. This is required when used as a session package.
The session names can be looked up in:
${p}/share/xsessions
${p}/share/wayland-sessions
'';
});
default = []; default = [];
description = '' description = ''
A list of packages containing xsession files to be passed to the display manager. A list of packages containing x11 or wayland session files to be passed to the display manager.
''; '';
}; };
@ -296,18 +250,50 @@ in
inside the display manager with the desktop manager name inside the display manager with the desktop manager name
followed by the window 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; sessionData = mkOption {
names = flip concatMap dm description = "Data exported for display managers convenience";
(d: map (w: d.name + optionalString (w.name != "none") ("+" + w.name)) internal = true;
(filter (w: d.name != "none" || w.name != "none") wm)); default = {};
desktops = mkDesktops names; apply = val: {
script = xsession wm dm;
wrapper = xsessionWrapper; wrapper = xsessionWrapper;
desktops = installedSessions;
sessionNames = concatMap (p: p.providedSessions) cfg.displayManager.sessionPackages;
# We do not want to force users to set defaultSession when they have only single DE.
autologinSession =
if cfg.displayManager.defaultSession != null then
cfg.displayManager.defaultSession
else if cfg.displayManager.sessionData.sessionNames != [] then
head cfg.displayManager.sessionData.sessionNames
else
null;
}; };
}; };
defaultSession = mkOption {
type = with types; nullOr str // {
description = "session name";
check = d:
assertMsg (d != null -> (str.check d && elem d cfg.displayManager.sessionData.sessionNames)) ''
Default graphical session, '${d}', not found.
Valid names for 'services.xserver.displayManager.defaultSession' are:
${concatStringsSep "\n " cfg.displayManager.sessionData.sessionNames}
'';
};
default =
if dmDefault != null || wmDefault != null then
defaultSessionFromLegacyOptions
else
null;
example = "gnome";
description = ''
Graphical session to pre-select in the session chooser (only effective for GDM and LightDM).
On GDM, LightDM and SDDM, it will also be used as a session for auto-login.
'';
};
job = { job = {
preStart = mkOption { preStart = mkOption {
@ -356,6 +342,27 @@ in
}; };
config = { config = {
assertions = [
{
assertion = cfg.desktopManager.default != null || cfg.windowManager.default != null -> cfg.displayManager.defaultSession == defaultSessionFromLegacyOptions;
message = "You cannot use both services.xserver.displayManager.defaultSession option and legacy options (services.xserver.desktopManager.default and services.xserver.windowManager.default).";
}
];
warnings =
mkIf (dmDefault != null || wmDefault != null) [
''
The following options are deprecated:
${concatStringsSep "\n " (map ({c, t}: t) (filter ({c, t}: c != null) [
{ c = dmDefault; t = "- services.xserver.desktopManager.default"; }
{ c = wmDefault; t = "- services.xserver.windowManager.default"; }
]))}
Please use
services.xserver.displayManager.defaultSession = "${concatStringsSep "+" (filter (s: s != null) [ dmDefault wmDefault ])}";
instead.
''
];
services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X"; services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X";
systemd.user.targets.graphical-session = { systemd.user.targets.graphical-session = {
@ -364,6 +371,67 @@ in
StopWhenUnneeded = false; StopWhenUnneeded = false;
}; };
}; };
# Create desktop files and scripts for starting sessions for WMs/DMs
# that do not have upstream session files (those defined using services.{display,desktop,window}Manager.session options).
services.xserver.displayManager.sessionPackages =
let
dms = filter (s: s.manage == "desktop") cfg.displayManager.session;
wms = filter (s: s.manage == "window") cfg.displayManager.session;
# Script responsible for starting the window manager and the desktop manager.
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`.
# Start the window manager.
${wm.start}
# Start the desktop manager.
${dm.start}
${optionalString cfg.updateDbusEnvironment ''
${lib.getBin pkgs.dbus}/bin/dbus-update-activation-environment --systemd --all
''}
test -n "$waitPID" && wait "$waitPID"
${config.systemd.package}/bin/systemctl --user stop graphical-session.target
exit 0
'';
in
# We will generate every possible pair of WM and DM.
concatLists (
crossLists
(dm: wm: let
sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}";
script = xsession dm wm;
in
optional (dm.name != "none" || wm.name != "none")
(pkgs.writeTextFile {
name = "${sessionName}-xsession";
destination = "/share/xsessions/${sessionName}.desktop";
# Desktop Entry Specification:
# - https://standards.freedesktop.org/desktop-entry-spec/latest/
# - https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
text = ''
[Desktop Entry]
Version=1.0
Type=XSession
TryExec=${script}
Exec=${script}
Name=${sessionName}
'';
} // {
providedSessions = [ sessionName ];
})
)
[dms wms]
);
}; };
imports = [ imports = [
@ -371,6 +439,7 @@ in
"The option is no longer necessary because all display managers have already delegated lid management to systemd.") "The option is no longer necessary because all display managers have already delegated lid management to systemd.")
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "xserver" "displayManager" "job" "logToFile" ]) (mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "xserver" "displayManager" "job" "logToFile" ])
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "xserver" "displayManager" "job" "logToJournal" ]) (mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "xserver" "displayManager" "job" "logToJournal" ])
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "xserver" "displayManager" "sessionPackages" ])
]; ];
} }

View file

@ -31,44 +31,9 @@ let
load-module module-position-event-sounds load-module module-position-event-sounds
''; '';
dmDefault = config.services.xserver.desktopManager.default; defaultSessionName = config.services.xserver.displayManager.defaultSession;
wmDefault = config.services.xserver.windowManager.default;
hasDefaultUserSession = dmDefault != "none" || wmDefault != "none";
defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault);
setSessionScript = pkgs.python3.pkgs.buildPythonApplication {
name = "set-session";
format = "other";
src = ./set-session.py;
dontUnpack = true;
strictDeps = false;
nativeBuildInputs = with pkgs; [
wrapGAppsHook
gobject-introspection
];
buildInputs = with pkgs; [
accountsservice
glib
];
propagatedBuildInputs = with pkgs.python3.pkgs; [
pygobject3
ordered-set
];
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/set-session
chmod +x $out/bin/set-session
'';
};
setSessionScript = pkgs.callPackage ./account-service-util.nix { };
in in
{ {
@ -186,7 +151,7 @@ in
environment = { environment = {
GDM_X_SERVER_EXTRA_ARGS = toString GDM_X_SERVER_EXTRA_ARGS = toString
(filter (arg: arg != "-terminate") cfg.xserverArgs); (filter (arg: arg != "-terminate") cfg.xserverArgs);
XDG_DATA_DIRS = "${cfg.session.desktops}/share/"; XDG_DATA_DIRS = "${cfg.sessionData.desktops}/share/";
} // optionalAttrs (xSessionWrapper != null) { } // optionalAttrs (xSessionWrapper != null) {
# Make GDM use this wrapper before running the session, which runs the # Make GDM use this wrapper before running the session, which runs the
# configured setupCommands. This relies on a patched GDM which supports # configured setupCommands. This relies on a patched GDM which supports
@ -204,16 +169,19 @@ in
cat - > /run/gdm/.config/gnome-initial-setup-done <<- EOF cat - > /run/gdm/.config/gnome-initial-setup-done <<- EOF
yes yes
EOF EOF
'' '' + optionalString (defaultSessionName != null) ''
# TODO: Make setSessionScript aware of previously used sessions # Set default session in session chooser to a specified values basically ignore session history.
# + optionalString hasDefaultUserSession '' ${setSessionScript}/bin/set-session ${cfg.sessionData.autologinSession}
# ${setSessionScript}/bin/set-session ${defaultSessionName} '';
# ''
;
}; };
# Because sd_login_monitor_new requires /run/systemd/machines systemd.services.display-manager.wants = [
systemd.services.display-manager.wants = [ "systemd-machined.service" ]; # Because sd_login_monitor_new requires /run/systemd/machines
"systemd-machined.service"
# setSessionScript wants AccountsService
"accounts-daemon.service"
];
systemd.services.display-manager.after = [ systemd.services.display-manager.after = [
"rc-local.service" "rc-local.service"
"systemd-machined.service" "systemd-machined.service"
@ -329,7 +297,7 @@ in
${optionalString cfg.gdm.debug "Enable=true"} ${optionalString cfg.gdm.debug "Enable=true"}
''; '';
environment.etc."gdm/Xsession".source = config.services.xserver.displayManager.session.wrapper; environment.etc."gdm/Xsession".source = config.services.xserver.displayManager.sessionData.wrapper;
# GDM LFS PAM modules, adapted somehow to NixOS # GDM LFS PAM modules, adapted somehow to NixOS
security.pam.services = { security.pam.services = {

View file

@ -53,9 +53,8 @@ in
Whether to enable lightdm-mini-greeter as the lightdm greeter. Whether to enable lightdm-mini-greeter as the lightdm greeter.
Note that this greeter starts only the default X session. Note that this greeter starts only the default X session.
You can configure the default X session by You can configure the default X session using
<option>services.xserver.desktopManager.default</option> and <xref linkend="opt-services.xserver.displayManager.defaultSession"/>.
<option>services.xserver.windowManager.default</option>.
''; '';
}; };

View file

@ -8,10 +8,9 @@ let
dmcfg = xcfg.displayManager; dmcfg = xcfg.displayManager;
xEnv = config.systemd.services.display-manager.environment; xEnv = config.systemd.services.display-manager.environment;
cfg = dmcfg.lightdm; cfg = dmcfg.lightdm;
sessionData = dmcfg.sessionData;
dmDefault = xcfg.desktopManager.default; setSessionScript = pkgs.callPackage ./account-service-util.nix { };
wmDefault = xcfg.windowManager.default;
hasDefaultUserSession = dmDefault != "none" || wmDefault != "none";
inherit (pkgs) lightdm writeScript writeText; inherit (pkgs) lightdm writeScript writeText;
@ -45,22 +44,19 @@ let
greeter-user = ${config.users.users.lightdm.name} greeter-user = ${config.users.users.lightdm.name}
greeters-directory = ${cfg.greeter.package} greeters-directory = ${cfg.greeter.package}
''} ''}
sessions-directory = ${dmcfg.session.desktops}/share/xsessions sessions-directory = ${dmcfg.sessionData.desktops}/share/xsessions:${dmcfg.sessionData.desktops}/share/wayland-sessions
${cfg.extraConfig} ${cfg.extraConfig}
[Seat:*] [Seat:*]
xserver-command = ${xserverWrapper} xserver-command = ${xserverWrapper}
session-wrapper = ${dmcfg.session.wrapper} session-wrapper = ${dmcfg.sessionData.wrapper}
${optionalString cfg.greeter.enable '' ${optionalString cfg.greeter.enable ''
greeter-session = ${cfg.greeter.name} greeter-session = ${cfg.greeter.name}
''} ''}
${optionalString cfg.autoLogin.enable '' ${optionalString cfg.autoLogin.enable ''
autologin-user = ${cfg.autoLogin.user} autologin-user = ${cfg.autoLogin.user}
autologin-user-timeout = ${toString cfg.autoLogin.timeout} autologin-user-timeout = ${toString cfg.autoLogin.timeout}
autologin-session = ${defaultSessionName} autologin-session = ${sessionData.autologinSession}
''}
${optionalString hasDefaultUserSession ''
user-session=${defaultSessionName}
''} ''}
${optionalString (dmcfg.setupCommands != "") '' ${optionalString (dmcfg.setupCommands != "") ''
display-setup-script=${pkgs.writeScript "lightdm-display-setup" '' display-setup-script=${pkgs.writeScript "lightdm-display-setup" ''
@ -71,7 +67,6 @@ let
${cfg.extraSeatDefaults} ${cfg.extraSeatDefaults}
''; '';
defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault);
in in
{ {
# Note: the order in which lightdm greeter modules are imported # Note: the order in which lightdm greeter modules are imported
@ -199,11 +194,9 @@ in
LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set
''; '';
} }
{ assertion = cfg.autoLogin.enable -> dmDefault != "none" || wmDefault != "none"; { assertion = cfg.autoLogin.enable -> sessionData.autologinSession != null;
message = '' message = ''
LightDM auto-login requires that services.xserver.desktopManager.default and LightDM auto-login requires that services.xserver.displayManager.defaultSession is set.
services.xserver.windowManager.default are set to valid values. The current
default session: ${defaultSessionName} is not valid.
''; '';
} }
{ assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0); { assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0);
@ -214,6 +207,20 @@ in
} }
]; ];
# Set default session in session chooser to a specified values basically ignore session history.
# Auto-login is already covered by a config value.
services.xserver.displayManager.job.preStart = optionalString (!cfg.autoLogin.enable && dmcfg.defaultSession != null) ''
${setSessionScript}/bin/set-session ${dmcfg.defaultSession}
'';
# setSessionScript needs session-files in XDG_DATA_DIRS
services.xserver.displayManager.job.environment.XDG_DATA_DIRS = "${dmcfg.sessionData.desktops}/share/";
# setSessionScript wants AccountsService
systemd.services.display-manager.wants = [
"accounts-daemon.service"
];
# lightdm relaunches itself via just `lightdm`, so needs to be on the PATH # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH
services.xserver.displayManager.job.execCmd = '' services.xserver.displayManager.job.execCmd = ''
export PATH=${lightdm}/sbin:$PATH export PATH=${lightdm}/sbin:$PATH

View file

@ -50,8 +50,8 @@ let
MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)} MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)}
ServerPath=${xserverWrapper} ServerPath=${xserverWrapper}
XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr
SessionCommand=${dmcfg.session.wrapper} SessionCommand=${dmcfg.sessionData.wrapper}
SessionDir=${dmcfg.session.desktops}/share/xsessions SessionDir=${dmcfg.sessionData.desktops}/share/xsessions
XauthPath=${pkgs.xorg.xauth}/bin/xauth XauthPath=${pkgs.xorg.xauth}/bin/xauth
DisplayCommand=${Xsetup} DisplayCommand=${Xsetup}
DisplayStopCommand=${Xstop} DisplayStopCommand=${Xstop}
@ -59,23 +59,19 @@ let
[Wayland] [Wayland]
EnableHidpi=${if cfg.enableHidpi then "true" else "false"} EnableHidpi=${if cfg.enableHidpi then "true" else "false"}
SessionDir=${dmcfg.session.desktops}/share/wayland-sessions SessionDir=${dmcfg.sessionData.desktops}/share/wayland-sessions
${optionalString cfg.autoLogin.enable '' ${optionalString cfg.autoLogin.enable ''
[Autologin] [Autologin]
User=${cfg.autoLogin.user} User=${cfg.autoLogin.user}
Session=${defaultSessionName}.desktop Session=${autoLoginSessionName}.desktop
Relogin=${boolToString cfg.autoLogin.relogin} Relogin=${boolToString cfg.autoLogin.relogin}
''} ''}
${cfg.extraConfig} ${cfg.extraConfig}
''; '';
defaultSessionName = autoLoginSessionName = dmcfg.sessionData.autologinSession;
let
dm = xcfg.desktopManager.default;
wm = xcfg.windowManager.default;
in dm + optionalString (wm != "none") ("+" + wm);
in in
{ {
@ -210,11 +206,9 @@ in
SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set
''; '';
} }
{ assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names; { assertion = cfg.autoLogin.enable -> autoLoginSessionName != null;
message = '' message = ''
SDDM auto-login requires that services.xserver.desktopManager.default and SDDM auto-login requires that services.xserver.displayManager.defaultSession is set.
services.xserver.windowManager.default are set to valid values. The current
default session: ${defaultSessionName} is not valid.
''; '';
} }
]; ];

View file

@ -59,15 +59,14 @@ in
}; };
default = mkOption { default = mkOption {
type = types.str; type = types.nullOr types.str;
default = "none"; default = null;
example = "wmii"; example = "wmii";
description = "Default window manager loaded if none have been chosen."; description = ''
apply = defaultWM: <emphasis role="strong">Deprecated</emphasis>, please use <xref linkend="opt-services.xserver.displayManager.defaultSession"/> instead.
if any (w: w.name == defaultWM) cfg.session then
defaultWM Default window manager loaded if none have been chosen.
else '';
throw "Default window manager (${defaultWM}) not found.";
}; };
}; };

View file

@ -1,12 +1,12 @@
{ lib, ... }:
{ services.xserver.enable = true; { services.xserver.enable = true;
# Automatically log in. # Automatically log in.
services.xserver.displayManager.auto.enable = true; services.xserver.displayManager.auto.enable = true;
# Use IceWM as the window manager. # Use IceWM as the window manager.
services.xserver.windowManager.default = "icewm";
services.xserver.windowManager.icewm.enable = true;
# Don't use a desktop manager. # Don't use a desktop manager.
services.xserver.desktopManager.default = "none"; services.xserver.displayManager.defaultSession = lib.mkDefault "none+icewm";
services.xserver.windowManager.icewm.enable = true;
} }

View file

@ -16,7 +16,7 @@ import ./make-test.nix ({ pkgs, ...} : {
services.xserver.displayManager.lightdm.autoLogin.enable = true; services.xserver.displayManager.lightdm.autoLogin.enable = true;
services.xserver.displayManager.lightdm.autoLogin.user = "alice"; services.xserver.displayManager.lightdm.autoLogin.user = "alice";
services.xserver.desktopManager.gnome3.enable = true; services.xserver.desktopManager.gnome3.enable = true;
services.xserver.desktopManager.default = "gnome-xorg"; services.xserver.displayManager.defaultSession = "gnome-xorg";
virtualisation.memorySize = 1024; virtualisation.memorySize = 1024;
}; };

View file

@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
machine = { lib, ... }: { machine = { lib, ... }: {
imports = [ ./common/x11.nix ./common/user-account.nix ]; imports = [ ./common/x11.nix ./common/user-account.nix ];
services.xserver.displayManager.auto.user = "alice"; services.xserver.displayManager.auto.user = "alice";
services.xserver.windowManager.default = lib.mkForce "i3"; services.xserver.displayManager.defaultSession = lib.mkForce "none+i3";
services.xserver.windowManager.i3.enable = true; services.xserver.windowManager.i3.enable = true;
}; };

View file

@ -8,9 +8,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
imports = [ ./common/user-account.nix ]; imports = [ ./common/user-account.nix ];
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.lightdm.enable = true; services.xserver.displayManager.lightdm.enable = true;
services.xserver.windowManager.default = "icewm"; services.xserver.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true; services.xserver.windowManager.icewm.enable = true;
services.xserver.desktopManager.default = "none";
}; };
enableOCR = true; enableOCR = true;

View file

@ -12,8 +12,8 @@ import ./make-test-python.nix ({ pkgs, ...} :
imports = [ ./common/user-account.nix ]; imports = [ ./common/user-account.nix ];
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.sddm.enable = true; services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.defaultSession = "plasma5";
services.xserver.desktopManager.plasma5.enable = true; services.xserver.desktopManager.plasma5.enable = true;
services.xserver.desktopManager.default = "plasma5";
services.xserver.displayManager.sddm.autoLogin = { services.xserver.displayManager.sddm.autoLogin = {
enable = true; enable = true;
user = "alice"; user = "alice";

View file

@ -16,9 +16,8 @@ let
imports = [ ./common/user-account.nix ]; imports = [ ./common/user-account.nix ];
services.xserver.enable = true; services.xserver.enable = true;
services.xserver.displayManager.sddm.enable = true; services.xserver.displayManager.sddm.enable = true;
services.xserver.windowManager.default = "icewm"; services.xserver.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true; services.xserver.windowManager.icewm.enable = true;
services.xserver.desktopManager.default = "none";
}; };
enableOCR = true; enableOCR = true;
@ -52,9 +51,8 @@ let
user = "alice"; user = "alice";
}; };
}; };
services.xserver.windowManager.default = "icewm"; services.xserver.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true; services.xserver.windowManager.icewm.enable = true;
services.xserver.desktopManager.default = "none";
}; };
testScript = { nodes, ... }: let testScript = { nodes, ... }: let

View file

@ -4,10 +4,10 @@ import ./make-test-python.nix ({ pkgs, ...} : {
maintainers = [ nequissimus ]; maintainers = [ nequissimus ];
}; };
machine = { lib, pkgs, ... }: { machine = { pkgs, ... }: {
imports = [ ./common/x11.nix ./common/user-account.nix ]; imports = [ ./common/x11.nix ./common/user-account.nix ];
services.xserver.displayManager.auto.user = "alice"; services.xserver.displayManager.auto.user = "alice";
services.xserver.windowManager.default = lib.mkForce "xmonad"; services.xserver.displayManager.defaultSession = "none+xmonad";
services.xserver.windowManager.xmonad = { services.xserver.windowManager.xmonad = {
enable = true; enable = true;
enableContribAndExtras = true; enableContribAndExtras = true;

View file

@ -55,6 +55,7 @@ stdenv.mkDerivation rec {
packageName = "gnome-session"; packageName = "gnome-session";
attrPath = "gnome3.gnome-session"; attrPath = "gnome3.gnome-session";
}; };
providedSessions = [ "gnome" "gnome-xorg" ];
}; };
meta = with stdenv.lib; { meta = with stdenv.lib; {

View file

@ -141,6 +141,8 @@ let
Type=Application Type=Application
DesktopNames=GNOME-Flashback;GNOME; DesktopNames=GNOME-Flashback;GNOME;
''; '';
} // {
providedSessions = [ "gnome-flashback-${wmName}" ];
}; };
mkSystemdTargetForWm = { wmName }: mkSystemdTargetForWm = { wmName }:

View file

@ -131,6 +131,7 @@ stdenv.mkDerivation rec {
inherit repoName; inherit repoName;
attrPath = pname; attrPath = pname;
}; };
providedSessions = [ "pantheon" ];
}; };
meta = with stdenv.lib; { meta = with stdenv.lib; {

View file

@ -43,6 +43,10 @@ stdenv.mkDerivation rec {
makeFlags = [ "PREFIX=${placeholder "out"}" ]; makeFlags = [ "PREFIX=${placeholder "out"}" ];
passthru = {
providedSessions = [ "surf-display" ];
};
meta = with stdenv.lib; { meta = with stdenv.lib; {
description = "Kiosk browser session manager based on the surf browser"; description = "Kiosk browser session manager based on the surf browser";
homepage = "https://code.it-zukunft-schule.de/cgit/surf-display/"; homepage = "https://code.it-zukunft-schule.de/cgit/surf-display/";