Using X without a Display Manager: Difference between revisions

From NixOS Wiki
imported>Giraffito
rewrite entirely. xlaunch does not exist since 2016: https://github.com/NixOS/nixpkgs/commit/20fe51661dcea78682420767fb8afd1170b06781 and there is no need for additional setuid wrappers
Klinger (talk | contribs)
mNo edit summary
 
(11 intermediate revisions by 6 users not shown)
Line 1: Line 1:
'''''Please note''': this page is presently being rewritten by someone very new to nixOS, so do not use it as an example of best practices. The previous content of this page was 2 years out of date and factually incorrect.''
{{note|This page is a WIP, it doesn't describe best-practices with nix and NixOS and should be updated to use a nix derivation generating the necessary files instead of manipulating the contents of the store.}}


To run X11 as a regular user, ''without'' `services.xserver.enable = true;` in configuration.nix, do the following:
== Setting up Xorg without system wide modifications ==


First, '''install packages'''; you need X11 itself, some X11 input modules (e.g. xf86-input-evdev, xf86-input-synaptics, xf86-input-libinput), and possibly video modules as well (xf86-video-intel, xf86-video-ati, xf86-video-nouveau).
To run X11 as a regular user, ''without'' <code>services.xserver.enable = true;</code> in configuration.nix, do the following:


You probably want to use '''DRI acceleration''' for X; enable it and OpenGL in /etc/nixos/configuration.nix: `hardware.opengl.enable = true;` and `hardware.opengl.driSupport = true;`.
First, '''install packages''':
* X11 itself:
** <code>xorg.xorgserver</code>
* X11 input modules
** <code>xorg.xf86inputevdev</code>
** <code>xorg.xf86inputsynaptics</code>
** <code>xorg.xf86inputlibinput</code>
*X11 video modules
** <code>xorg.xf86videointel</code>
** <code>xorg.xf86videoati</code>
** <code>xorg.xf86videonouveau</code>


Then, it's just necessary to '''gather X configuration files''' into one directory and create a config file that also points X at the correct module paths.
You probably want to use '''DRI acceleration''' for X; enable it and OpenGL in configuration.nix: <code>hardware.opengl.enable = true;</code> and <code>hardware.opengl.driSupport = true;</code>.


This script does that (though it hard-codes `pkgs` which should instead be computed from the current configuration):
Then, it's just necessary to '''gather X configuration files''' into one directory and create a config file that also points X at the correct module paths, by running the following script (which should be re-run each time you run <code>nixos-rebuild switch</code>), but you will need to add or remove to the <code>pkgs</code> and <code>fontpkgs</code> arrays according to your preferences:
<syntaxhighlight lang="sh">
<syntaxhighlight lang="sh">
generateXorgConf.sh
------------------------------------------------
#!/bin/sh
#!/bin/sh
#generate unprivileged user xorg.conf for nixOS
#generate unprivileged user xorg.conf for nixOS
#TODO: obey XDG guidelines rather than assuming ~/.config
#before running:
#    install any desired packages by placing them in `/etc/nixos/configuration.nix`
#    update by running `nix-channel --update` and `nixos-rebuild switch`


mkdir -p ~/.config/xorg.conf.d
config_dir=${XDG_CONFIG_HOME:-~/.config}/xorg.conf.d
cd ~/.config/xorg.conf.d
 
mkdir -p "$config_dir"
cd "$config_dir"


#failed glob expansions become empty, not literal 'foo/*'
#failed glob expansions become empty, not literal 'foo/*'
shopt -s nullglob
shopt -s nullglob


#TODO: don't hard-code package names!
get_pkg_path() {
attr=$1
nix show-derivation -f '<nixpkgs>' "$attr" | jq -r '.[].env.out'
}
 
#add to this set according to your driver needs
pkgs="
pkgs="
i0r09miwjk8z9wd2261gh3a3mdzln4w4-xf86-input-evdev-2.10.5
xorg.xf86inputevdev
av8542xr7kn44abja120hk3ppd2vp8l8-xf86-video-intel-2017-10-19
xorg.xf86videointel
8vp93ci2lkcg9c5jh7csfz24npjcnhhx-xf86-input-synaptics-1.9.0
xorg.xf86inputsynaptics
660q2zwjrn0cqkjj6cy861pkazs6yrs0-xorg-server-1.19.6
xorg.xorgserver
"
"


echo 'Section "Files"' > 00-nix-module-paths
#make the intel backlight helper setuid if it isn't already
xf86videointel_path=$(get_pkg_path xorg.xf86videointel)
backlight_helper_path="${xf86_video_intel_path}/libexec/xf86-video-intel-backlight-helper"
if [ -e "$backlight_helper_path" -a ! -u "$backlight_helper_path" ]; then
sudo chmod +s ${xf86_video_intel_path}/libexec/xf86-video-intel-backlight-helper
fi
 
echo 'Section "Files"' > 00-nix-module-paths.conf
for pkg in $pkgs; do
for pkg in $pkgs; do
for conf in /nix/store/"$pkg"/share/X11/xorg.conf.d/*; do  
pkg_path=$(get_pkg_path $pkg)
ln -s "$conf" ./
for conf in "$pkg_path"/share/X11/xorg.conf.d/*; do  
ln -sf "$conf" ./
done
done
echo ' ModulePath "/nix/store/'"$pkg"'/lib/xorg/modules/"' >> 00-nix-module-paths.conf
echo ' ModulePath "'"$pkg_path"'/lib/xorg/modules/"' >> 00-nix-module-paths.conf
done
 
#add to this set according to your font preferences
fontpkgs="
xorg.fontmiscmisc
ucsFonts
"
 
for pkg in $fontpkgs; do
pkg_path=$(get_pkg_path $pkg)
path="$pkg_path"'/share/fonts/'
[ -d "$path" ] && echo ' FontPath "'"$path"'"' >> 00-nix-module-paths.conf
path="$pkg_path"'/lib/X11/fonts/misc/'
[ -d "$path" ] && echo ' FontPath "'"$path"'"' >> 00-nix-module-paths.conf
done
done
echo 'EndSection' >> 00-nix-module-paths.conf
echo 'EndSection' >> 00-nix-module-paths.conf
</syntaxhighlight>
</syntaxhighlight>
Line 43: Line 87:
startx -- :0 -configdir ~/.config/xorg.conf.d
startx -- :0 -configdir ~/.config/xorg.conf.d
</syntaxhighlight>
</syntaxhighlight>
== Setting up Xorg system-wide but without a Display Manager ==
If you don't mind having <code>services.xserver.enable = true;</code> but you don't want a display manager, and you want only a TTY login prompt, use the following in your <code>configuration.nix</code>:
<syntaxhighlight lang="nix">
services.xserver.displayManager.startx.enable = true;
</syntaxhighlight>
<code>startx</code> is treated as a displayManager and therefore it is used instead of the default (<code>lightdm</code>).
== Setting up the user's D-Bus Daemon ==
Both of the methods above, don't start the user's dbus-daemon properly on startup. Unfortunately, it is unclear exactly why this is missing, but here's a fix for startx users:
Put the following in your <code>~/.xinitrc</code>:
<syntaxhighlight lang="sh">
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 DISPLAY XAUTHORITY
fi
</syntaxhighlight>
[[Category: Desktop environment]]

Latest revision as of 19:44, 24 April 2024

Note: This page is a WIP, it doesn't describe best-practices with nix and NixOS and should be updated to use a nix derivation generating the necessary files instead of manipulating the contents of the store.

Setting up Xorg without system wide modifications

To run X11 as a regular user, without services.xserver.enable = true; in configuration.nix, do the following:

First, install packages:

  • X11 itself:
    • xorg.xorgserver
  • X11 input modules
    • xorg.xf86inputevdev
    • xorg.xf86inputsynaptics
    • xorg.xf86inputlibinput
  • X11 video modules
    • xorg.xf86videointel
    • xorg.xf86videoati
    • xorg.xf86videonouveau

You probably want to use DRI acceleration for X; enable it and OpenGL in configuration.nix: hardware.opengl.enable = true; and hardware.opengl.driSupport = true;.

Then, it's just necessary to gather X configuration files into one directory and create a config file that also points X at the correct module paths, by running the following script (which should be re-run each time you run nixos-rebuild switch), but you will need to add or remove to the pkgs and fontpkgs arrays according to your preferences:

generateXorgConf.sh
------------------------------------------------
#!/bin/sh
#generate unprivileged user xorg.conf for nixOS
#before running:
#    install any desired packages by placing them in `/etc/nixos/configuration.nix`
#    update by running `nix-channel --update` and `nixos-rebuild switch`

config_dir=${XDG_CONFIG_HOME:-~/.config}/xorg.conf.d

mkdir -p "$config_dir"
cd "$config_dir"

#failed glob expansions become empty, not literal 'foo/*'
shopt -s nullglob

get_pkg_path() {
	attr=$1
	nix show-derivation -f '<nixpkgs>' "$attr" | jq -r '.[].env.out' 
}

#add to this set according to your driver needs
pkgs="
	xorg.xf86inputevdev
	xorg.xf86videointel
	xorg.xf86inputsynaptics
	xorg.xorgserver
"

#make the intel backlight helper setuid if it isn't already
xf86videointel_path=$(get_pkg_path xorg.xf86videointel)
backlight_helper_path="${xf86_video_intel_path}/libexec/xf86-video-intel-backlight-helper"
if [ -e "$backlight_helper_path" -a ! -u "$backlight_helper_path" ]; then
	sudo chmod +s ${xf86_video_intel_path}/libexec/xf86-video-intel-backlight-helper
fi

echo 'Section "Files"' > 00-nix-module-paths.conf
for pkg in $pkgs; do
	pkg_path=$(get_pkg_path $pkg)
	for conf in "$pkg_path"/share/X11/xorg.conf.d/*; do 
		ln -sf "$conf" ./
	done
	echo '	ModulePath "'"$pkg_path"'/lib/xorg/modules/"' >> 00-nix-module-paths.conf
done

#add to this set according to your font preferences
fontpkgs="
	xorg.fontmiscmisc
	ucsFonts
"

for pkg in $fontpkgs; do
	pkg_path=$(get_pkg_path $pkg)
	path="$pkg_path"'/share/fonts/'
	[ -d "$path" ] && echo '	FontPath "'"$path"'"' >> 00-nix-module-paths.conf
	path="$pkg_path"'/lib/X11/fonts/misc/'
	[ -d "$path" ] && echo '	FontPath "'"$path"'"' >> 00-nix-module-paths.conf
done

echo 'EndSection' >> 00-nix-module-paths.conf

You can now start X11 by running:

startx -- :0 -configdir ~/.config/xorg.conf.d

Setting up Xorg system-wide but without a Display Manager

If you don't mind having services.xserver.enable = true; but you don't want a display manager, and you want only a TTY login prompt, use the following in your configuration.nix:

services.xserver.displayManager.startx.enable = true;

startx is treated as a displayManager and therefore it is used instead of the default (lightdm).

Setting up the user's D-Bus Daemon

Both of the methods above, don't start the user's dbus-daemon properly on startup. Unfortunately, it is unclear exactly why this is missing, but here's a fix for startx users:

Put the following in your ~/.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 DISPLAY XAUTHORITY
fi