Skip to content
Artemios edited this page Mar 27, 2020 · 1 revision

Adopting the XDG specification

This page should help anyone who wants to adopt the XDG Base Directory Specification. The specification contains 6 environment variables:

Variable Function Recommended default
$XDG_DATA_HOME user specific data files $HOME/.local/share
$XDG_CONFIG_HOME user specific configuration files $HOME/.config
$XDG_DATA_DIRS set of ordered directories for data files /usr/local/share/:/usr/share/
$XDG_CONFIG_DIRS set of ordered directorries for configuration files /etc/xdg
$XDG_CACHE_HOME user specific, non-essential (cached) data $HOME/.cache
$XDG_RUNTIME_DIR user specific runtime files not defined

You are free to choose whatever path you like. However in this example, I'm going to stick to the recommended defaults. If you choose to alter these, keep this in mind:

All paths set in these environment variables must be absolute. If an implementation encounters a relative path in any of these variables it should consider the path invalid and ignore it.

For the $XDG_RUNTIME_DIR there is no default, but there are a couple of requirements:

  • The directory MUST be owned by the user
  • The user MUST be the only one having read and write access to it
  • Its access mode MUST be 0700
  • The lifetime of the directory MUST be bound to the user being logged in
  • It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed
  • If the user logs in more than once he should get pointed to the same directory
  • Files in the directory MUST not survive reboot or a full logout/login cycle

Setting directories

One must choose a sensible place to set these variables. I chose /etc/profile.d/xdg.sh. Create the file and add the following:

# XDG base directories
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_DATA_DIRS="/usr/local/share:/usr/share"
export XDG_CONFIG_DIRS="/etc/xdg"

# Setting $XDG_RUNTIME_DIR
if test -z "${XDG_RUNTIME_DIR}"; then
     export XDG_RUNTIME_DIR=/tmp/${UID}-runtime-dir
     if ! test -d "${XDG_RUNTIME_DIR}"; then
         mkdir "${XDG_RUNTIME_DIR}"
         chmod 0700 "${XDG_RUNTIME_DIR}"
     fi
 fi

At this point it may be a good idea to reboot and check whether all the variables have been set correctly using printenv.

Moving over config files

Applications that already implemented the XDG specification will now attempt to create their config files inside $XDG_CONFIG_HOME. For example $XDG_CONFIG_HOME/polybar. To find out whether or net an application supports the specification already or if one has to do some extra work to get it done, use the ArchWiki page. Simply search for your application. For example CTRL-F: zsh.

Moving xorg files

In order to successfully move over all xorg related config files, one indeed has to do some extra work. First it's a good idea to choose a dedicated folder inside $XDG_CONFIG_HOME for all xorg config files:

mkdir "$XDG_CONFIG_HOME"/X11

xinit

To move ~/.xinitrc and ~/.xserverrc, one has to tell xorg where the config files are now. A good place to do so would be a .bash_profile or equivalent:

export XINITRC="$XDG_CONFIG_HOME"/X11/xinitrc
export XSERVERRC="$XDG_CONFIG_HOME"/X11/xserverrc

After that the files can be copied to the new location:

cp ~/.xinitrc "$XDG_CONFIG_HOME"/X11/xinitrc
cp ~/.xserverrc "$XDG_CONFIG_HOME"/X11/xserverrc

Starting an Xsession with startx should now work like so: startx "$XINITRC" -- "$XSERVERRC" vt1

xauth

It is similar with xauth. Add the following to your .bash_profile or equivalent:

export XAUTHORITY="$XDG_RUNTIME_DIR"/Xauthority

Note: You can delete your old ~/.Xauthority and don't need to copy it. It will get created automatically. Note: You have to add xhost +SI:localuser:$USER to your xinitrc, otherwise you're likely to run into this:

error in process filter: [XELB] Connection failed: No protocol specified

xrdb

You may also copy your ~/.Xresources to the new location:

cp ~/.Xresources "$XDG_CONFIG_HOME"/X11/Xresources

xrdb doesn't know this path, so you have to specify it every time you load or merge your Xresources (See next section).

Minimal EXWM xinitrc example

With the changes explained, a minimal xinitrc example would be:

# Set permissions
xhost +SI:localuser:$USER

# Set fallback cursor
xsetroot -cursor_name left_ptr

# Set keyboard repeat rate
xset r rate 200 60

export VISUAL=emacsclient
export EDITOR="$VISUAL"

# Load resources
xrdb -load "$XDG_CONFIG_HOME"/X11/Xresources

exec emacs

Start the Xsession with startx "$XINITRC" or startx "$XDG_CONFIG_HOME"/X11/xinitrc.

Cleanup

If everything works as expected, you maybe now delete the old config files inside $HOME.