When is the appropriate time to start Redshift using upstart

lightdmservicesstartupupstartx11

I have been trying to get Redshift to start before login so that the bright welcome screen does not blind me, in particular when switching users.

Running Redshift as a service does not seem fully supported (see e.g. this bug) but it seems to be possible in principle.

After trying some things found on AskUbuntu without success, my current attempt is set up my own upstart task; here is my /etc/init/redshift.conf:

# Redshift

description "Redshift"
author      "dude@somewhere.com"

start on (started lightdm)

script
  exec redshift -c /etc/redshift.conf
end script

stop on runlevel [016]

I figured that starting after LightDM is running should work out, and stopping with it as well.

Now, this ends up in my log file /var/log/upstart/redshift.log:

`RANDR Query Version' returned error -1
Initialization of randr failed.

Googling for the error was not very informative. I guess I am still too early and some service or the other related to display magicks is not running yet.

What should be my start on expression?

Ubuntu 14.04 LTS; 3.13.0-77-generic #121-Ubuntu SMP … x86_64 GNU/Linux;
redshift 1.8; RandR server version 1.4; upstart 1.12.1

Best Answer

Redshift is tied to an X server. While you can start it as part of the system startup, that's fragile; the robust way to start it is within the context of the X server session (which is broader than the X login session).

There can be multiple X servers running on the same machine at a given time. They are assigned display numbers on a first-come, first-served basis. The display number is how a program knows which server to contact, and programs look for it in the DISPLAY environment variable. The natural way to start a GUI program is in a context where the DISPLAY environment variable is set to the desired value.

You can make the assumption that lightdm is the first entity that starts an X server, so it's display :0, and hard-code the environment variable DISPLAY=:0 in your upstart job. You'll also need to set the XAUTHORITY variable (see Open a window on a remote X display (why "Cannot open display")?). I think lightdm on Ubuntu stores the cookie in /var/lib/lightdm/.Xauthority.

env DISPLAY=":0"
env XAUTHORITY="/var/lib/lightdm/.Xauthority"

But this is fragile: it assumes that the display lightdm ends up on is :0. I think it won't work in its current form because of a race condition: the lightdm job might be considered started before the X server is up and running (I'm not sure about that though, I don't know at what point the job counts as started).

The clean way is to make lightdm start Redshift. That way it's started at the right time in the right context. Edit /etc/lightdm/lightdm.conf and add redshift -c /etc/redshift.conf to the display-setup-script line in the SeatDefaults section:

[SeatDefaults]
…
display-setup-script=redshift -c /etc/redshift.conf &

Note the & to start redshift in the background (otherwise lightdm would wait for it to finish). I think Redshift will exit when the X server exits (X applications usually exit when their display goes away, so there's no need to track the process and kill it explicitly.

Related Question