Search code examples
linuxscreensaverinit.d

Starting a custom screensaver on boot behaves differently than manually starting the screensaver


I have a touchscreen kiosk on which I'm running a webserver. I want to show a slideshow if the screen hasn't been touched for a certain amount of time. For that purpose I have the script below.

#!/bin/sh

# Wanted trigger timeout in milliseconds.
IDLE_TIME=$((15*1000))

# Sequence to execute when timeout triggers.
trigger_cmd() {
DISPLAY=:0 feh -ZXYrzFD 10 /home/pi/screensaver/img --zoom fill &
    echo '"pkill -n feh; pkill -n xbindkeys"'>/home/pi/screensaver/xbindkeys.temp
    echo "b:1">>/home/pi/screensaver/xbindkeys.temp
    DISPLAY=:0 xbindkeys -n -f /home/pi/screensaver/xbindkeys.temp
    sudo rm /home/pi/screensaver/xbindkeys.temp
}

sleep_time=$IDLE_TIME
triggered=false

# ceil() instead of floor()
while sleep $(((sleep_time+999)/1000)); do
    idle=$(DISPLAY=:0 xprintidle)
    if [ $idle -gt $IDLE_TIME ]; then
        if ! $triggered; then
            trigger_cmd
            triggered=true
            sleep_time=$IDLE_TIME
        fi
    else
        triggered=false
        # Give 100 ms buffer to avoid frantic loops shortly before triggers.
        sleep_time=$((IDLE_TIME-idle+100))
    fi
done

I use xprintidle to check how long the screen has been idle. The xbindkeys part is for killing feh when the screen is touched. When I start the script manually I can close the slideshow by touching the screen once and it will reopen after the given idle time. When I start the script via a script in init.d I have to touch the screen twice before it will open the slideshow again, and will never reopen the slideshow if you only touched the screen once.
The script in init.d simply starts the script above as the user pi.

Can someone help me figure out why starting the script on boot apparently causes the script to require two clicks instead of one to start the idle timer?


Solution

  • The touchscreen script is most likely being run by init.d before your DISPLAY environment variable is set (i.e. user pi is not logged in).

    Try running this from .bash_profile. That way all your user environment variables will be set especially $DISPLAY and the script will run once upon login.