116 lines
3.1 KiB
Nix
116 lines
3.1 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
|
|
cfg = config.services.xserver.displayManager.startx;
|
|
|
|
# WM session script
|
|
# Note: this assumes a single WM has been enabled
|
|
sessionScript = lib.concatMapStringsSep "\n" (
|
|
i: i.start
|
|
) config.services.xserver.windowManager.session;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
###### interface
|
|
|
|
options = {
|
|
services.xserver.displayManager.startx = {
|
|
enable = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to enable the dummy "startx" pseudo-display manager, which
|
|
allows users to start X manually via the `startx` command from a
|
|
virtual terminal.
|
|
|
|
::: {.note}
|
|
The X server will run under the current user, not as root.
|
|
:::
|
|
'';
|
|
};
|
|
|
|
generateScript = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = ''
|
|
Whether to generate the system-wide xinitrc script (/etc/X11/xinit/xinitrc).
|
|
This script will take care of setting up the session for systemd user
|
|
services, running the window manager and cleaning up on exit.
|
|
|
|
::: {.note}
|
|
This script will only be used by `startx` when both `.xinitrc` does not
|
|
exists and the `XINITRC` environment variable is unset.
|
|
:::
|
|
'';
|
|
};
|
|
|
|
extraCommands = lib.mkOption {
|
|
type = lib.types.lines;
|
|
default = "";
|
|
description = ''
|
|
Shell commands to be added to the system-wide xinitrc script.
|
|
'';
|
|
};
|
|
|
|
};
|
|
};
|
|
|
|
###### implementation
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
services.xserver.exportConfiguration = true;
|
|
|
|
# Other displayManagers log to /dev/null because they're services and put
|
|
# Xorg's stdout in the journal
|
|
#
|
|
# To send log to Xorg's default log location ($XDG_DATA_HOME/xorg/), we do
|
|
# not specify a log file when running X
|
|
services.xserver.logFile = lib.mkDefault null;
|
|
|
|
# Implement xserverArgs via xinit's system-wide xserverrc
|
|
environment.etc."X11/xinit/xserverrc".source = pkgs.writeShellScript "xserverrc" ''
|
|
exec ${pkgs.xorg.xorgserver}/bin/X \
|
|
${toString config.services.xserver.displayManager.xserverArgs} "$@"
|
|
'';
|
|
|
|
# Add a sane system-wide xinitrc script
|
|
environment.etc."X11/xinit/xinitrc" = lib.mkIf cfg.generateScript {
|
|
source = pkgs.writeShellScript "xinitrc" ''
|
|
${cfg.extraCommands}
|
|
|
|
# start user services
|
|
systemctl --user import-environment DISPLAY XDG_SESSION_ID
|
|
systemctl --user start nixos-fake-graphical-session.target
|
|
|
|
# run the window manager script
|
|
${sessionScript}
|
|
wait $waitPID
|
|
|
|
# stop services and all subprocesses
|
|
systemctl --user stop nixos-fake-graphical-session.target
|
|
kill 0
|
|
'';
|
|
};
|
|
|
|
environment.systemPackages = with pkgs; [ xorg.xinit ];
|
|
|
|
# Make graphical-session fail if the user environment has not been imported
|
|
systemd.user.targets.graphical-session = {
|
|
unitConfig.AssertEnvironment = [
|
|
"DISPLAY"
|
|
"XDG_SESSION_ID"
|
|
];
|
|
};
|
|
|
|
};
|
|
|
|
}
|