diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml index 9206f43ea392..55ad9fe6e653 100644 --- a/nixos/doc/manual/configuration/x-windows.xml +++ b/nixos/doc/manual/configuration/x-windows.xml @@ -83,8 +83,7 @@ desktop environment. If you wanted no desktop environment and i3 as your your window manager, you'd define: - = "none"; - = "i3"; + = "none+i3"; And, finally, to enable auto-login for a user johndoe: diff --git a/nixos/doc/manual/configuration/xfce.xml b/nixos/doc/manual/configuration/xfce.xml index 6ac99c6b2bee..027828bb936d 100644 --- a/nixos/doc/manual/configuration/xfce.xml +++ b/nixos/doc/manual/configuration/xfce.xml @@ -7,9 +7,8 @@ To enable the Xfce Desktop Environment, set -services.xserver.desktopManager = { - xfce.enable = true; - default = "xfce"; + = true; + = "xfce"; }; diff --git a/nixos/doc/manual/release-notes/rl-2003.xml b/nixos/doc/manual/release-notes/rl-2003.xml index 2a38b2adbbb4..247e9cd063c6 100644 --- a/nixos/doc/manual/release-notes/rl-2003.xml +++ b/nixos/doc/manual/release-notes/rl-2003.xml @@ -55,6 +55,19 @@ and adding a option which prints all options and their values. + + + and options were replaced by a single option to improve support for upstream session files. If you used something like: + +services.xserver.desktopManager.default = "xfce"; +services.xserver.windowManager.default = "icewm"; + + you should change it to: + +services.xserver.displayManager.defaultSession = "xfce+icewm"; + + + diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index d567d2687653..c4eb9328b1db 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -262,9 +262,8 @@ in rec { virtualisation.memorySize = 1024; services.xserver.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.desktopManager.default = "none"; }; in runInMachine ({ diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix index a5f060a8d8e3..ae8ecd6270ce 100644 --- a/nixos/lib/testing.nix +++ b/nixos/lib/testing.nix @@ -249,9 +249,8 @@ in rec { virtualisation.memorySize = 1024; services.xserver.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.desktopManager.default = "none"; }; in runInMachine ({ diff --git a/nixos/modules/programs/sway.nix b/nixos/modules/programs/sway.nix index 9a15c7734632..d685a5259324 100644 --- a/nixos/modules/programs/sway.nix +++ b/nixos/modules/programs/sway.nix @@ -24,6 +24,7 @@ let swayJoined = pkgs.symlinkJoin { name = "sway-joined"; paths = [ swayWrapped swayPackage ]; + passthru.providedSessions = [ "sway" ]; }; in { options.programs.sway = { @@ -88,7 +89,7 @@ in { fonts.enableDefaultFonts = mkDefault true; programs.dconf.enable = mkDefault true; # 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 ]; diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 671a959cdde1..534551c0c4ab 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -86,23 +86,14 @@ in }; default = mkOption { - type = types.str; - default = ""; + type = types.nullOr types.str; + default = null; example = "none"; - description = "Default desktop manager loaded if none have been chosen."; - apply = defaultDM: - if defaultDM == "" && cfg.session.list != [] then - (head cfg.session.list).name - 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; + description = '' + Deprecated, please use instead. + + Default desktop manager loaded if none have been chosen. + ''; }; }; diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 6725595e1cfd..6d9bd284bc72 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -144,7 +144,7 @@ in services.gnome3.core-shell.enable = 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 = '' ${concatMapStrings (p: '' @@ -171,7 +171,7 @@ in }) (mkIf flashbackEnabled { - services.xserver.displayManager.extraSessionFilePackages = map + services.xserver.displayManager.sessionPackages = map (wm: pkgs.gnome3.gnome-flashback.mkSessionForWm { inherit (wm) wmName wmLabel wmCommand; }) (optional cfg.flashback.enableMetacity { diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 99db5b17b649..e07d5b5eaad7 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -69,7 +69,7 @@ in 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 # 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; - # If not set manually Pantheon session cannot be started - # Known issue of https://github.com/NixOS/nixpkgs/pull/43992 - services.xserver.desktopManager.default = mkForce "pantheon"; + # Without this, Elementary LightDM greeter will pre-select non-existent `default` session + # https://github.com/elementary/greeter/issues/368 + services.xserver.displayManager.defaultSession = "pantheon"; services.xserver.displayManager.sessionCommands = '' if test "$XDG_CURRENT_DESKTOP" = "Pantheon"; then diff --git a/nixos/modules/services/x11/desktop-managers/surf-display.nix b/nixos/modules/services/x11/desktop-managers/surf-display.nix index 140dde828daa..9aeb0bbd2a88 100644 --- a/nixos/modules/services/x11/desktop-managers/surf-display.nix +++ b/nixos/modules/services/x11/desktop-managers/surf-display.nix @@ -118,7 +118,7 @@ in { }; config = mkIf cfg.enable { - services.xserver.displayManager.extraSessionFilePackages = [ + services.xserver.displayManager.sessionPackages = [ pkgs.surf-display ]; diff --git a/nixos/modules/services/x11/display-managers/account-service-util.nix b/nixos/modules/services/x11/display-managers/account-service-util.nix new file mode 100644 index 000000000000..1dbe703b5662 --- /dev/null +++ b/nixos/modules/services/x11/display-managers/account-service-util.nix @@ -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 + ''; +} diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index c252c3c90c94..2d809b5cc9fd 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -27,16 +27,7 @@ let Xft.hintstyle: hintslight ''; - mkCases = session: - 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 + # file provided by services.xserver.displayManager.sessionData.wrapper xsessionWrapper = pkgs.writeScript "xsession-wrapper" '' #! ${pkgs.bash}/bin/bash @@ -116,94 +107,44 @@ let # Run the supplied session command. Remove any double quotes with eval. eval exec "$@" else - # Fall back to the default window/desktopManager - exec ${cfg.displayManager.session.script} + # TODO: Do we need this? Should not the session always exist? + echo "error: unknown session $1" 1>&2 + exit 1 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 = + - - # The first argument of this script is the session type. - sessionType="$1" - if [ "$sessionType" = default ]; then sessionType=""; fi - - # The session type is "+", 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" + installedSessions = pkgs.runCommand "desktops" { # trivial derivation preferLocalBuild = true; allowSubstitutes = false; } '' - mkdir -p "$out/share/xsessions" - ${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} + mkdir -p "$out/share/"{xsessions,wayland-sessions} ${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 ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions fi - '') cfg.displayManager.extraSessionFilePackages} - - ${concatMapStrings (pkg: '' 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 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 { @@ -261,11 +202,24 @@ in ''; }; - extraSessionFilePackages = mkOption { - type = types.listOf types.package; + sessionPackages = mkOption { + 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 = []; 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 followed by the window manager name. ''; - apply = list: rec { - wm = filter (s: s.manage == "window") list; - dm = filter (s: s.manage == "desktop") list; - names = flip concatMap dm - (d: map (w: d.name + optionalString (w.name != "none") ("+" + w.name)) - (filter (w: d.name != "none" || w.name != "none") wm)); - desktops = mkDesktops names; - script = xsession wm dm; + }; + + sessionData = mkOption { + description = "Data exported for display managers’ convenience"; + internal = true; + default = {}; + apply = val: { 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 = { preStart = mkOption { @@ -356,6 +342,27 @@ in }; 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"; systemd.user.targets.graphical-session = { @@ -364,6 +371,67 @@ in 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 = [ @@ -371,6 +439,7 @@ in "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" "logToJournal" ] [ "services" "xserver" "displayManager" "job" "logToJournal" ]) + (mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "xserver" "displayManager" "sessionPackages" ]) ]; } diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix index 095569fa08aa..6630f012f04f 100644 --- a/nixos/modules/services/x11/display-managers/gdm.nix +++ b/nixos/modules/services/x11/display-managers/gdm.nix @@ -31,44 +31,9 @@ let load-module module-position-event-sounds ''; - dmDefault = config.services.xserver.desktopManager.default; - 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 - ''; - }; + defaultSessionName = config.services.xserver.displayManager.defaultSession; + setSessionScript = pkgs.callPackage ./account-service-util.nix { }; in { @@ -186,7 +151,7 @@ in environment = { GDM_X_SERVER_EXTRA_ARGS = toString (filter (arg: arg != "-terminate") cfg.xserverArgs); - XDG_DATA_DIRS = "${cfg.session.desktops}/share/"; + XDG_DATA_DIRS = "${cfg.sessionData.desktops}/share/"; } // optionalAttrs (xSessionWrapper != null) { # Make GDM use this wrapper before running the session, which runs the # configured setupCommands. This relies on a patched GDM which supports @@ -204,16 +169,19 @@ in cat - > /run/gdm/.config/gnome-initial-setup-done <<- EOF yes EOF - '' - # TODO: Make setSessionScript aware of previously used sessions - # + optionalString hasDefaultUserSession '' - # ${setSessionScript}/bin/set-session ${defaultSessionName} - # '' - ; + '' + optionalString (defaultSessionName != null) '' + # Set default session in session chooser to a specified values – basically ignore session history. + ${setSessionScript}/bin/set-session ${cfg.sessionData.autologinSession} + ''; }; - # Because sd_login_monitor_new requires /run/systemd/machines - systemd.services.display-manager.wants = [ "systemd-machined.service" ]; + systemd.services.display-manager.wants = [ + # Because sd_login_monitor_new requires /run/systemd/machines + "systemd-machined.service" + # setSessionScript wants AccountsService + "accounts-daemon.service" + ]; + systemd.services.display-manager.after = [ "rc-local.service" "systemd-machined.service" @@ -329,7 +297,7 @@ in ${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 security.pam.services = { diff --git a/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix b/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix index fa9445af32e7..0025f9b36037 100644 --- a/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix +++ b/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix @@ -53,9 +53,8 @@ in Whether to enable lightdm-mini-greeter as the lightdm greeter. Note that this greeter starts only the default X session. - You can configure the default X session by - and - . + You can configure the default X session using + . ''; }; diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index cf4c05acbccd..f7face0adb7e 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -8,10 +8,9 @@ let dmcfg = xcfg.displayManager; xEnv = config.systemd.services.display-manager.environment; cfg = dmcfg.lightdm; + sessionData = dmcfg.sessionData; - dmDefault = xcfg.desktopManager.default; - wmDefault = xcfg.windowManager.default; - hasDefaultUserSession = dmDefault != "none" || wmDefault != "none"; + setSessionScript = pkgs.callPackage ./account-service-util.nix { }; inherit (pkgs) lightdm writeScript writeText; @@ -45,22 +44,19 @@ let greeter-user = ${config.users.users.lightdm.name} 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} [Seat:*] xserver-command = ${xserverWrapper} - session-wrapper = ${dmcfg.session.wrapper} + session-wrapper = ${dmcfg.sessionData.wrapper} ${optionalString cfg.greeter.enable '' greeter-session = ${cfg.greeter.name} ''} ${optionalString cfg.autoLogin.enable '' autologin-user = ${cfg.autoLogin.user} autologin-user-timeout = ${toString cfg.autoLogin.timeout} - autologin-session = ${defaultSessionName} - ''} - ${optionalString hasDefaultUserSession '' - user-session=${defaultSessionName} + autologin-session = ${sessionData.autologinSession} ''} ${optionalString (dmcfg.setupCommands != "") '' display-setup-script=${pkgs.writeScript "lightdm-display-setup" '' @@ -71,7 +67,6 @@ let ${cfg.extraSeatDefaults} ''; - defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault); in { # 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 ''; } - { assertion = cfg.autoLogin.enable -> dmDefault != "none" || wmDefault != "none"; + { assertion = cfg.autoLogin.enable -> sessionData.autologinSession != null; message = '' - LightDM auto-login requires that services.xserver.desktopManager.default and - services.xserver.windowManager.default are set to valid values. The current - default session: ${defaultSessionName} is not valid. + LightDM auto-login requires that services.xserver.displayManager.defaultSession is set. ''; } { 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 services.xserver.displayManager.job.execCmd = '' export PATH=${lightdm}/sbin:$PATH diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 24e120c4f2cf..4224c557ed63 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -50,8 +50,8 @@ let MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)} ServerPath=${xserverWrapper} XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr - SessionCommand=${dmcfg.session.wrapper} - SessionDir=${dmcfg.session.desktops}/share/xsessions + SessionCommand=${dmcfg.sessionData.wrapper} + SessionDir=${dmcfg.sessionData.desktops}/share/xsessions XauthPath=${pkgs.xorg.xauth}/bin/xauth DisplayCommand=${Xsetup} DisplayStopCommand=${Xstop} @@ -59,23 +59,19 @@ let [Wayland] 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 '' [Autologin] User=${cfg.autoLogin.user} - Session=${defaultSessionName}.desktop + Session=${autoLoginSessionName}.desktop Relogin=${boolToString cfg.autoLogin.relogin} ''} ${cfg.extraConfig} ''; - defaultSessionName = - let - dm = xcfg.desktopManager.default; - wm = xcfg.windowManager.default; - in dm + optionalString (wm != "none") ("+" + wm); + autoLoginSessionName = dmcfg.sessionData.autologinSession; in { @@ -210,11 +206,9 @@ in 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 = '' - SDDM auto-login requires that services.xserver.desktopManager.default and - services.xserver.windowManager.default are set to valid values. The current - default session: ${defaultSessionName} is not valid. + SDDM auto-login requires that services.xserver.displayManager.defaultSession is set. ''; } ]; diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index c17f3830d0e9..04a9fc46628c 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -59,15 +59,14 @@ in }; default = mkOption { - type = types.str; - default = "none"; + type = types.nullOr types.str; + default = null; example = "wmii"; - description = "Default window manager loaded if none have been chosen."; - apply = defaultWM: - if any (w: w.name == defaultWM) cfg.session then - defaultWM - else - throw "Default window manager (${defaultWM}) not found."; + description = '' + Deprecated, please use instead. + + Default window manager loaded if none have been chosen. + ''; }; }; diff --git a/nixos/tests/common/x11.nix b/nixos/tests/common/x11.nix index c5a7c165d126..5ad0ac20fac8 100644 --- a/nixos/tests/common/x11.nix +++ b/nixos/tests/common/x11.nix @@ -1,12 +1,12 @@ +{ lib, ... }: + { services.xserver.enable = true; # Automatically log in. services.xserver.displayManager.auto.enable = true; # Use IceWM as the window manager. - services.xserver.windowManager.default = "icewm"; - services.xserver.windowManager.icewm.enable = true; - # 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; } diff --git a/nixos/tests/gnome3-xorg.nix b/nixos/tests/gnome3-xorg.nix index eb4c376319be..aa03501f6a55 100644 --- a/nixos/tests/gnome3-xorg.nix +++ b/nixos/tests/gnome3-xorg.nix @@ -16,7 +16,7 @@ import ./make-test.nix ({ pkgs, ...} : { services.xserver.displayManager.lightdm.autoLogin.enable = true; services.xserver.displayManager.lightdm.autoLogin.user = "alice"; services.xserver.desktopManager.gnome3.enable = true; - services.xserver.desktopManager.default = "gnome-xorg"; + services.xserver.displayManager.defaultSession = "gnome-xorg"; virtualisation.memorySize = 1024; }; diff --git a/nixos/tests/i3wm.nix b/nixos/tests/i3wm.nix index 8afa845f1e21..126178d11879 100644 --- a/nixos/tests/i3wm.nix +++ b/nixos/tests/i3wm.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, ...} : { machine = { lib, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; 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; }; diff --git a/nixos/tests/lightdm.nix b/nixos/tests/lightdm.nix index ef30f7741e23..46c2ed7ccc59 100644 --- a/nixos/tests/lightdm.nix +++ b/nixos/tests/lightdm.nix @@ -8,9 +8,8 @@ import ./make-test-python.nix ({ pkgs, ...} : { imports = [ ./common/user-account.nix ]; services.xserver.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.desktopManager.default = "none"; }; enableOCR = true; diff --git a/nixos/tests/plasma5.nix b/nixos/tests/plasma5.nix index 6884f17aabbe..2eccfdf47f59 100644 --- a/nixos/tests/plasma5.nix +++ b/nixos/tests/plasma5.nix @@ -12,8 +12,8 @@ import ./make-test-python.nix ({ pkgs, ...} : imports = [ ./common/user-account.nix ]; services.xserver.enable = true; services.xserver.displayManager.sddm.enable = true; + services.xserver.displayManager.defaultSession = "plasma5"; services.xserver.desktopManager.plasma5.enable = true; - services.xserver.desktopManager.default = "plasma5"; services.xserver.displayManager.sddm.autoLogin = { enable = true; user = "alice"; diff --git a/nixos/tests/sddm.nix b/nixos/tests/sddm.nix index 4bdcd701dcf1..a145705250f7 100644 --- a/nixos/tests/sddm.nix +++ b/nixos/tests/sddm.nix @@ -16,9 +16,8 @@ let imports = [ ./common/user-account.nix ]; services.xserver.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.desktopManager.default = "none"; }; enableOCR = true; @@ -52,9 +51,8 @@ let user = "alice"; }; }; - services.xserver.windowManager.default = "icewm"; + services.xserver.displayManager.defaultSession = "none+icewm"; services.xserver.windowManager.icewm.enable = true; - services.xserver.desktopManager.default = "none"; }; testScript = { nodes, ... }: let diff --git a/nixos/tests/xmonad.nix b/nixos/tests/xmonad.nix index ab3888ca43fc..ef711f8dcf6a 100644 --- a/nixos/tests/xmonad.nix +++ b/nixos/tests/xmonad.nix @@ -4,10 +4,10 @@ import ./make-test-python.nix ({ pkgs, ...} : { maintainers = [ nequissimus ]; }; - machine = { lib, pkgs, ... }: { + machine = { pkgs, ... }: { imports = [ ./common/x11.nix ./common/user-account.nix ]; services.xserver.displayManager.auto.user = "alice"; - services.xserver.windowManager.default = lib.mkForce "xmonad"; + services.xserver.displayManager.defaultSession = "none+xmonad"; services.xserver.windowManager.xmonad = { enable = true; enableContribAndExtras = true; diff --git a/pkgs/desktops/gnome-3/core/gnome-session/default.nix b/pkgs/desktops/gnome-3/core/gnome-session/default.nix index 8aaf68ea1e36..d63435ce2e9a 100644 --- a/pkgs/desktops/gnome-3/core/gnome-session/default.nix +++ b/pkgs/desktops/gnome-3/core/gnome-session/default.nix @@ -55,6 +55,7 @@ stdenv.mkDerivation rec { packageName = "gnome-session"; attrPath = "gnome3.gnome-session"; }; + providedSessions = [ "gnome" "gnome-xorg" ]; }; meta = with stdenv.lib; { diff --git a/pkgs/desktops/gnome-3/misc/gnome-flashback/default.nix b/pkgs/desktops/gnome-3/misc/gnome-flashback/default.nix index 808d36dab95c..c1791ee5bbdc 100644 --- a/pkgs/desktops/gnome-3/misc/gnome-flashback/default.nix +++ b/pkgs/desktops/gnome-3/misc/gnome-flashback/default.nix @@ -141,6 +141,8 @@ let Type=Application DesktopNames=GNOME-Flashback;GNOME; ''; + } // { + providedSessions = [ "gnome-flashback-${wmName}" ]; }; mkSystemdTargetForWm = { wmName }: diff --git a/pkgs/desktops/pantheon/desktop/elementary-session-settings/default.nix b/pkgs/desktops/pantheon/desktop/elementary-session-settings/default.nix index ab7333212a05..07c9e724fc65 100644 --- a/pkgs/desktops/pantheon/desktop/elementary-session-settings/default.nix +++ b/pkgs/desktops/pantheon/desktop/elementary-session-settings/default.nix @@ -131,6 +131,7 @@ stdenv.mkDerivation rec { inherit repoName; attrPath = pname; }; + providedSessions = [ "pantheon" ]; }; meta = with stdenv.lib; { diff --git a/pkgs/desktops/surf-display/default.nix b/pkgs/desktops/surf-display/default.nix index 47b7e1172068..dd0644866478 100644 --- a/pkgs/desktops/surf-display/default.nix +++ b/pkgs/desktops/surf-display/default.nix @@ -43,6 +43,10 @@ stdenv.mkDerivation rec { makeFlags = [ "PREFIX=${placeholder "out"}" ]; + passthru = { + providedSessions = [ "surf-display" ]; + }; + meta = with stdenv.lib; { description = "Kiosk browser session manager based on the surf browser"; homepage = "https://code.it-zukunft-schule.de/cgit/surf-display/";