diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index f64f2dbb2cb25..0739572cd8b14 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -965,7 +965,6 @@
./services/x11/window-managers/icewm.nix
./services/x11/window-managers/bspwm.nix
./services/x11/window-managers/metacity.nix
- ./services/x11/window-managers/none.nix
./services/x11/window-managers/twm.nix
./services/x11/window-managers/windowlab.nix
./services/x11/window-managers/wmii.nix
diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix
index f5559eb535419..7f14f66b925cc 100644
--- a/nixos/modules/services/x11/desktop-managers/default.nix
+++ b/nixos/modules/services/x11/desktop-managers/default.nix
@@ -69,15 +69,23 @@ in
scripts before forwarding the value to the
displayManager.
'';
- apply = map (d: d // {
- manage = "desktop";
- start = d.start
- + optionalString (needBGCond d) ''
- if [ -e $HOME/.background-image ]; then
- ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image
- fi
- '';
- });
+ apply = map (d:
+ let
+ dm = { supportExternalWM = false; } // d;
+ str = optionalString (needBGCond d) ''
+ if [ -e $HOME/.background-image ]; then
+ ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image
+ fi
+ '';
+ in
+ dm //(
+ if dm.supportExternalWM
+ then {
+ genStart = wm: dm.genStart wm + str;
+ }
+ else {
+ start = d.start + str;
+ }));
};
default = mkOption {
@@ -95,5 +103,5 @@ in
};
- config.services.xserver.displayManager.session = cfg.session;
+ config.services.xserver.displayManager.dmSessions = cfg.session;
}
diff --git a/nixos/modules/services/x11/desktop-managers/none.nix b/nixos/modules/services/x11/desktop-managers/none.nix
index af7a376ae0296..c97a74ddb8fb6 100644
--- a/nixos/modules/services/x11/desktop-managers/none.nix
+++ b/nixos/modules/services/x11/desktop-managers/none.nix
@@ -1,7 +1,10 @@
{
services.xserver.desktopManager.session =
[ { name = "none";
- start = "";
+ supportExternalWM = true;
+ genStart = wm: ''
+ ${wm}
+ '';
}
];
}
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
index d6cf86d3a2e61..1d282a965ef14 100644
--- a/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -194,7 +194,15 @@ in
services.xserver.desktopManager.session = singleton {
name = "plasma5";
bgSupport = true;
- start = startplasma;
+ genStart = wm:
+ if pkg == null
+ then startplasma
+ else ''
+ export KDEWM=${wm}
+
+ ${startplasma}
+ '';
+ supportExternalWM = true;
};
security.wrappers = {
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 9fdbe753dad50..677dc31e77420 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -210,32 +210,26 @@ in
'';
};
- session = mkOption {
+ dmSessions = mkOption {
+ default = [];
+ description = ''
+ List of enabled desktop manager sessions. Each session can
+ either support or not support the use of external window
+ managers. If external window are supported, it must provide
+ a function genStart that takes a package
+ (the window manager's startup script) and returns a string
+ (the desktop manager's startup script), otherwise it should
+ provide a string start that represents its
+ startup script.
+ '';
+ };
+
+ wmSessions = mkOption {
default = [];
- example = literalExample
- ''
- [ { manage = "desktop";
- name = "xterm";
- start = '''
- ''${pkgs.xterm}/bin/xterm -ls &
- waitPID=$!
- ''';
- }
- ]
- '';
description = ''
- List of sessions supported with the command used to start each
- session. Each session script can set the
- waitPID shell variable to make this script
- wait until the end of the user session. Each script is used
- to define either a window 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.
+ List of enabled window manager sessions. All sessions should
+ provide a string start that represents its
+ startup script
'';
};
@@ -414,22 +408,17 @@ in
# 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;
+ dms = cfg.displayManager.dmSessions;
+ wms = cfg.displayManager.wmSessions;
# Script responsible for starting the window manager and the desktop manager.
- xsession = dm: wm: pkgs.writeScript "xsession" ''
- #! ${pkgs.bash}/bin/bash
-
+ xsession = startup: pkgs.writeShellScript "xsession" ''
# 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}
+ # Run the startup script.
+ ${startup}
${optionalString cfg.updateDbusEnvironment ''
${lib.getBin pkgs.dbus}/bin/dbus-update-activation-environment --systemd --all
@@ -441,39 +430,60 @@ in
exit 0
'';
+ writeSessionFile = {sessionName, script, desktopNames}:
+ 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}
+ DesktopNames=${desktopNames}
+ '';
+ } // {
+ providedSessions = [ sessionName ];
+ };
in
# We will generate every possible pair of WM and DM.
concatLists (
- builtins.map
- ({dm, wm}: let
- sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}";
- script = xsession dm wm;
- desktopNames = if dm ? desktopNames
- then concatStringsSep ";" dm.desktopNames
- else sessionName;
- 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}
- DesktopNames=${desktopNames}
- '';
- } // {
- providedSessions = [ sessionName ];
- })
- )
+ builtins.map
+ ({dm, wm}: optional dm.supportExternalWM
+ (let
+ sessionName = "${dm.name}+${wm.name}";
+ startup = dm.genStart wm.bin;
+ script = xsession startup;
+ desktopNames = if dm ? desktopNames
+ then concatStringsSep ";" dm.desktopNames
+ else sessionName;
+ in
+ writeSessionFile {
+ inherit sessionName script desktopNames;
+ }
+ ))
(cartesianProductOfSets { dm = dms; wm = wms; })
- );
+ ) ++ map (dm:
+ let
+ sessionName = dm.name;
+ startup =
+ if dm.supportExternalWM
+ then dm.genStart null
+ else dm.start;
+ script = xsession startup;
+ desktopNames =
+ if dm ? desktopNames
+ then concatStringsSep ";" dm.desktopNames
+ else sessionName;
+ in
+ writeSessionFile {
+ inherit sessionName script desktopNames;
+ }
+ ) (filter (dm: dm.name != "none") dms);
# Make xsessions and wayland sessions available in XDG_DATA_DIRS
# as some programs have behavior that depends on them being present
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index 9ca24310e5673..8064147e27b90 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -1,4 +1,4 @@
-{ config, lib, ... }:
+{ config, lib, pkgs, ... }:
with lib;
@@ -41,7 +41,7 @@ in
./xmonad.nix
./yeahwm.nix
./qtile.nix
- ./none.nix ];
+ ];
options = {
@@ -59,9 +59,10 @@ in
scripts before forwarding the value to the
displayManager.
'';
- apply = map (d: d // {
- manage = "window";
- });
+ apply = map (w:
+ w // {
+ bin = pkgs.writeShellScript "run-${w.name}" w.start;
+ });
};
default = mkOption {
@@ -80,6 +81,6 @@ in
};
config = {
- services.xserver.displayManager.session = cfg.session;
+ services.xserver.displayManager.wmSessions = cfg.session;
};
}
diff --git a/nixos/modules/services/x11/window-managers/none.nix b/nixos/modules/services/x11/window-managers/none.nix
deleted file mode 100644
index 84cf1d7707768..0000000000000
--- a/nixos/modules/services/x11/window-managers/none.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- services = {
- xserver = {
- windowManager = {
- session = [{
- name = "none";
- start = "";
- }];
- };
- };
- };
-}