Describe the bug
services.xserver.displayManager.startx.enable = true creates a buggy X environment. The bottom cause seems to be that nixpkgs.xorg.xinit requires patching as upstream is not providing a well-maintained startx script. This affects all nix channels.
There 2 majors issues:
dbus is never spawned and the environment variable DBUS_SESSION_BUS_ADDRESS is not set. Some programs relying on dbus fail. For example, when gpg asks for a password, pinentry has to fall back to a non X version.xauth is never written.To Reproduce
Steps to reproduce the behavior:
services.xserver.enable = trueservices.xserver.windowManager.stumpwm.enable = trueservices.xserver.displayManager.startx.enable = true~/.xinitrc to execute your window managerstartxExpected behavior
startx should behave similarly to the default lightdm display manager. In particular, programs relying on dbus should work fine.
Additional context
startx is not properly maintained by upstream. All 3 patches applied to Arch Linux xorg-xinit package seem necessary. Note Arch is one of the few distributions where startx is actively used and maintained.
Some of the patches applied by Arch remove code upstream developers do not know why was added originally.
Furthermore, Nix has to make sure the script share/factory/etc/X11/xinit/xinitrc.d/50-systemd-user.sh in package systemd is sourced. This script is usually placed in /etc/X11/xinit/xinitrc.d by common distros and calls dbus-update-activation-environment.
Notify maintainers
@xeji @mlvzk @xaverdh
Metadata
"x86_64-linux"Linux 5.4.54, NixOS, 20.03.2676.38516a273cd (Markhor)yesyesnix-env (Nix) 2.3.6"""nixos-20.03.2676.38516a273cd, nixpkgs-18.09-darwin-18.09pre153253.7e88992a8c7"/nix/var/nix/profiles/per-user/root/channels/nixosMaintainer information:
# a list of nixpkgs attributes affected by the problem
attribute: xorg.xinit
# a list of nixos modules affected by the problem
module: services.xserver.displayManager.startx
I can confirm the 2 issues:
A user dbus is never spawned and the environment variable DBUS_SESSION_BUS_ADDRESS is not set. Some programs relying on dbus fail. For example, when gpg asks for a password, pinentry has to fall back to a non X version.
I fixed that for my self with this in my .xinitrc:
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
eval $(dbus-launch --exit-with-session --sh-syntax)
fi
systemctl --user import-environment DISPLAY XAUTHORITY
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
dbus-update-activation-environment --all --systemd --verbose
fi
And only then, I had no issues at all with dbus related programs.
Besides that, I can also confirm the 2nd issue but it was harmless and unsolvable for as far as I searched.
I think dbus-launch and DBUS_SESSIONBUS_ADDRESS are deprecated or will soon be.
I start the bus and user session like this
dbus-daemon --session --address="unix:path=/run/user/$(id -u)/bus" &
systemctl --user import-environment DISPLAY XAUTHORITY
systemctl --user start graphical-session.target
I can't confirm whether this works instead, as I moved to Gnome (just a few days ago :sweat_smile: ).
@rnhmjoj I don't know exactly all the details about dbus, but after doing a diff of my env with startx vs lightdm, DBUS_SESSION_BUS_ADDRESS was the only remarkable difference (aside from no user dbus spawned). The bug report in Xorg and patches in Arch seemed to confirm this. It breaks lots of things.
I'm happy with any other modification, as long as startx becomes less broken in NixOS.
Aside, there are xauth errors due to the lack of a magic cookie file.
I don't think it's broken. The point of the startx (pseudo-)display-manager is to give users compete freedom - and responsibility - to define their session setup via their own ~/.xinitrc. It is not an option that is supposed to work out of the box.
See the documentation of services.xserver.displayManager.startx.enable:
Description:
Whether to enable the dummy "startx" pseudo-display manager,
which allows users to start X manually via the "startx" command
from a vt shell. The X server runs under the user's id, not as root.
The user must provide a ~/.xinitrc file containing session startup
commands, see startx(1). This is not automatically generated
from the desktopManager and windowManager settings.
So setting up dbus etc. is up to the user here. Just provide your own .xinitrc and do whatever you want.
I would prefer not to include any particular session setup code in the system-wide X configs by default so users have full control. Otherwise we would have to make general assumptions about what all users want to do with their X session, which I feel is somewhat contrary to the do-it-yourself approach of displayManager.startx.
@xeji, I agree with you on the principle flexibility, and I'm not expecting things to work out of the box. Perhaps I didn't explain this well. I expect users to have to write a ~/.xinitrc.
It's just that the startx script provided by the xinitrc package is not properly maintained and thus broken. They don't know why e.g. the line unset DBUS_SESSION_BUS_ADDRESS was originally introduced in the startx script, which breaks many things. There are other similar issues too.
I think avoiding to patch packages is a good policy, I also prefer these to be as close as possible to upstream. But the xinit package is a bit of an exception where patching may be required. It's not actively maintained and the few distributions where many users run startx instead of a display manager apply a series of patches to the startx script so that it's functioning properly:
Arch applies 3 patches to fix cookie creation and avoid unsetting DBUS global variable
Debian applies some similar patches
Aside from this, Nix does not seem to be sourcing systemd scripts share/factory/etc/X11/xinit/xinitrc.d/50-systemd-user.sh correctly. The other distributions do without any code as the script is placed in xinitrc.d when xinit package is installed.
Hence, a ~/.xinitrc that works in another systemd-based distribution like Arch won't work in NixOS without lots of modifications. If users want to override some behavior, they can always write their own startx, but I think the startx provided by a distribution should not be broken.
@solna86 thank you for clarifying. If the situation can be improved by appying some simple patches to xorg.xinit, I'm fine with that. But we should also take care not to break existing installations or other packages depending on xorg.xinit.
Hence, a ~/.xinitrc that works in another systemd-based distribution like Arch won't work in NixOS without lots of modifications.
Maybe we can try to get a little closer but let's not expect 100% compatiblity. There is no common standard for X session startup, and some differences between distros are normal.
Are we sure patching xinit will break existing configurations?
No. It's just something to consider when reviewing and testing patches.
As a starting point for further discussion, it would be useful to get some answers to these questions:
~/.xinitrc do you use?~/.xinitrc should work across distributions with minimal modifications?My ~/.xinitrc is very simple:
if test -z "$DBUS_SESSION_BUS_ADDRESS"; then
exec dbus-launch --exit-with-x11 $HOME/.xsession
else
exec $HOME/.xsession
fi
The ~/.xsession script loads the keyboard layout and Xresources, then starts the i3 window manager.
What minimal ~/.xinitrc should work across distributions with minimal modifications?
I don't have an answer to that, and doubt there is one. People use very different X session setups.
There is an xsession wrapper in nixos/modules/services/x11/display-managers/default.nix related to the problem described in issue 1. For startx this logic is not considered.
It seems only GDM uses this?
$rg services.xserver.displayManager.sessionData
nixos/modules/services/x11/display-managers/default.nix
30: # file provided by services.xserver.displayManager.sessionData.wrapper
nixos/modules/services/x11/display-managers/gdm.nix
296: environment.etc."gdm/Xsession".source = config.services.xserver.displayManager.sessionData.wrapper;
I have very little familiarity with most components involved here but it looks to me that dbus has nothing to do with graphical environment... I see no reason why a 100% cli app, running as a server of sorts should not be able to subscribe to dbus.
Not fixing any problem but if anyone wants to start from 0, I came across a link today- https://nixers.net/Thread-How-Many-Ways-To-Start-An-Xserver
Most helpful comment
@xeji, I agree with you on the principle flexibility, and I'm not expecting things to work out of the box. Perhaps I didn't explain this well. I expect users to have to write a
~/.xinitrc.It's just that the
startxscript provided by thexinitrcpackage is not properly maintained and thus broken. They don't know why e.g. the lineunset DBUS_SESSION_BUS_ADDRESSwas originally introduced in thestartxscript, which breaks many things. There are other similar issues too.I think avoiding to patch packages is a good policy, I also prefer these to be as close as possible to upstream. But the
xinitpackage is a bit of an exception where patching may be required. It's not actively maintained and the few distributions where many users runstartxinstead of a display manager apply a series of patches to thestartxscript so that it's functioning properly:Arch applies 3 patches to fix cookie creation and avoid unsetting DBUS global variable
Debian applies some similar patches
Aside from this, Nix does not seem to be sourcing systemd scripts
share/factory/etc/X11/xinit/xinitrc.d/50-systemd-user.shcorrectly. The other distributions do without any code as the script is placed inxinitrc.dwhenxinitpackage is installed.Hence, a
~/.xinitrcthat works in another systemd-based distribution like Arch won't work in NixOS without lots of modifications. If users want to override some behavior, they can always write their ownstartx, but I think thestartxprovided by a distribution should not be broken.