XClients is a perfect and cannonical way to autostart graphical application. But personnaly I don’t like to keep various settings in a single file, so let’s add some modularity to XClients.
/etc/X11/Xclients (or somewhere else depending on your system)
text files are meant to contain programs which are to be executed on X server startup.
To be more precise,
/etc/X11/XClients sources user’s
$HOME/.Xclients file and adds
some user independent startup code.
Usual XClients file would look something like this:
# /home/user/.XClients xset ... xrandr ... gdm # kdm, xmonad, whatever
NOTICE: commands specified in this file must be either fast enough or detached from terminal
& at the end of the line. This is so because long-running command will hang further execution.
Typically, the last command in
XClients is the window manager, which is conversely left attached to the terminal.
NOTICE: this file should be executable by the user.
When the system is meant to be configured and used manually, this is perfectly fine approach. But once I was to create a collection of rpms, containing not only executables and documentation, but user’s initialization code as well. And this code was meant to be:
To make this a bit clearer: there is some code, that needs to be executed before applications, and window manager is meant to be loaded first. A list of applications is not known beforehand, and this applications were not installed in the system at the moment.
Here I thought it would be nice to split configuration pieces into one-purpose files, that can be packed as rpms. Something like initd or nginx’s sites-available would do.
There are several problems, though:
First, create a directory inside the $HOME directory called something like
Then add some config files:
#!/bin/bash # ~/.xclients.d/00-set-resolution.sh xrandr --output HDMI-1 --mode '1920x1080'
#!/bin/bash # ~/.xclients.d/01-xset.sh xset -r
#!/bin/bash # ~/.xclients.d/99-wm.sh gdm
Okay, now make them executable:
$> chmod a+x ~/.xclients.d/*
Notice the number in file names – these are used to control the order of execution, just like in init or modern xorg.conf.d.
To execute these files add the following to
#!/bin/bash if [ -d $HOME/.xclients.d ]; then for file in $(find $HOME/.xclients.d -type f | sort); do exec $file done end
I did all the packaging, so I added 10-application.sh files to applications’ rpms.
#!/bin/bash # ~/.xclients.d/10-application.sh /path/to/application & # <= notice the ampersand, this application is interactive # and would hang further execution, # thus must be datached
As you detach the application from shell (as I did in previous section), they stay alive despite of shell spawned them. It’s your business to watch these don’t bloat the system. One way is to just check if it is running and kill it if so:
#!/bin/bash # ~/.xclients.d/10-application.sh pgrep "^application" &>/dev/null if [ $? -neq 0 ]; then pkill "^application" fi