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 = ""; - }]; - }; - }; - }; -}