Control Debian X Sessions with Xsession.options.d

Drop-in files in Xsession.options.d let you override one X session option without touching a vendor file. This guide adds one, checks precedence, and undoes it cleanly. The examples use the installed x11-common version 1:7.7+23ubuntu3.

Allow about fifteen minutes. You need a shell and administrator access for changes under /etc/X11. This changes login-session behaviour, so test it on a machine where you have another way back in, such as an existing shell or a second desktop session.

The option files are read by Xsession, the Bourne shell script that starts an X session. They do not configure the X server itself, and they do not create any user files.

1. Inspect the current configuration

Start with ordinary, read-only commands. No sudo yet:

$ dpkg-query -W -f='${Package} ${Version}\n' x11-common
x11-common 1:7.7+23ubuntu3
$ sed -n '1,160p' /etc/X11/Xsession.options
# configuration options for /etc/X11/Xsession
allow-failsafe
allow-user-resources
allow-user-xsession
use-ssh-agent
use-session-dbus

Your package version and file contents may differ. The installed manual documents five standard options: allow-failsafe, allow-user-resources, allow-user-xsession, use-session-dbus and use-ssh-agent. All five are enabled by default according to the manual, though an explicit no- line can disable any one of them.

Checkpoint: Confirm the reader script and the fragment directory before changing anything.

$ grep -n -A8 -B2 'Xsession.options' /etc/X11/Xsession
$ if [ -d /etc/X11/Xsession.options.d ]; then
>     run-parts --list --regex '\.conf$' /etc/X11/Xsession.options.d
> else
>     echo 'fragment directory is absent'
> fi
fragment directory is absent

An absent directory is normal. The base file still works fine on its own.

2. Choose the option and its safety boundary

Enable an option by writing its name; disable it by writing the same name with no- in front. The practical effects differ quite a bit:

Disabling allow-user-xsession or allow-user-resources can deliberately cut down user-controlled session customisation. It can also break a workflow that depends on those files. Do not change these options during a remote desktop outage unless you have an independent recovery route.

3. Add one ordered fragment

Fragments must be regular files whose names end in .conf. They are read after /etc/X11/Xsession.options, in sorted order, and later occurrences win whether they enable or disable an option.

For example, this fragment disables user startup scripts for all X sessions:

$ sudo install -d -m 0755 /etc/X11/Xsession.options.d
$ sudo sh -c 'printf "%s\n" "# Keep X sessions from using per-user startup scripts" "no-allow-user-xsession" > /etc/X11/Xsession.options.d/90-local-policy.conf'
$ sudo chmod 0644 /etc/X11/Xsession.options.d/90-local-policy.conf

Both the directory creation and the file write need elevated privileges. The filename is deliberately late in sort order, so it overrides an earlier fragment or the base file. It is still only a policy input: it does not terminate an existing session.

Checkpoint: Inspect the exact inputs and their order.

$ sudo sh -c 'cat /etc/X11/Xsession.options; run-parts --list --regex '\''\.conf$'\'' /etc/X11/Xsession.options.d | xargs -d "\n" cat'
...base options...
no-allow-user-xsession

Keep one option per line. Blank lines and lines beginning with # are comments. Do not write shell assignments, quoted values or multiple options on one line; the documented format is a plain list of hyphen-separated words.

4. Override a fragment without deleting it

To restore the normal behaviour, remove the local fragment or replace its line with allow-user-xsession. Removing the file is a destructive configuration change, so preserve it first if you might need to explain or restore the policy later:

$ sudo cp --preserve=all /etc/X11/Xsession.options.d/90-local-policy.conf /etc/X11/Xsession.options.d/90-local-policy.conf.bak
$ sudo sh -c 'printf "%s\n" "# Restore per-user startup scripts" "allow-user-xsession" > /etc/X11/Xsession.options.d/90-local-policy.conf'

That backup sits outside the .conf pattern, so Xsession ignores it. If you need to undo the change completely, compare the backup, then remove the active fragment only after checking that no other administrator owns it:

$ sudo diff -u /etc/X11/Xsession.options.d/90-local-policy.conf.bak /etc/X11/Xsession.options.d/90-local-policy.conf
$ sudo rm /etc/X11/Xsession.options.d/90-local-policy.conf

The last command is irreversible unless you kept the backup. It affects future X sessions, not one that is already running.

5. Diagnose an option that appears to be ignored

First check the filename: a file named 90-local-policy is ignored because it does not end in .conf, and a file with spaces or unusual punctuation may also be skipped by run-parts. Next, check sorted order and search for every occurrence:

$ sudo find /etc/X11/Xsession.options.d -maxdepth 1 -type f -name '*.conf' -printf '%f\n' | sort
$ sudo grep -R --line-number -- 'allow-user-xsession\|no-allow-user-xsession' /etc/X11/Xsession.options /etc/X11/Xsession.options.d

If both forms appear, the last one in the reader's order wins. Check the combined stream rather than trusting ls, whose ordering and output are not the contract here:

$ sudo sh -c 'run-parts --list --regex '\''\.conf$'\'' /etc/X11/Xsession.options.d | xargs -d "\n" -r cat'
no-allow-user-xsession

None of this proves that a user's file is valid, that dbus is installed, or that an X terminal emulator exists. It only verifies the option inputs. Log out and start a fresh X session before judging whether the change worked.

Done means