Bash – How to detect from script when the user’s desktop is loaded

bashdesktopscriptingsession

I have a daemon, implemented in bash and running by means of cron and the @reboot option, that shows the desktop in inactivity.
The script is as following (timings are short for testing purposes):

#!/bin/bash
P_STATE=0
while :
do
    sleep 5
    if [ $P_STATE == 0 ]; then
         [ `xprintidle` -ge 25000 ] && P_STATE=1 && wmctrl -k on
    else
         [ `xprintidle` -le 25000 ] && P_STATE=0
done

Problem: If a user is still, for example, in the login screen, xprintidle and wmctrl fails since the desktop isn't yet loaded.
In order to avoid this, I've put the next lines at the very beginning of the script:

while:
do
    sleep 10s
    [ -n `who | grep "$USER"` ] && break
done

So, the script waits the user (the USER variable is set to my user-name in the crontab file) is logged. But, it a user begins, for example, a terminal session (and not a graphical session like KDE or GNOME), the script also continue.

How can I determine if a user is already in a "graphical" session capable of "showing desktop mode" or not? And moreover, how can I ensure that a "graphical" session is completely loaded and not in process of loading or something like that?

My solution:
My (informal) solution is adding in the main loop the grep line:

WAIT_TIME=180

while:
do
    sleep $WAIT_TIME

    [ ! -n "`ps -ef | grep "$WM_CMD" | grep -v "grep"`" ] && continue

    ## My actions here
done

Being "$WM_CMD" the target windows manager command. I assume that, if the windows manager command is running in the system, it means the desktop is completely loaded and any "graphic" command is sure.

Where is WM_CMD variable defined? In the crontab line:

 @reboot DISPLAY=:0 WM_CMD=/usr/bin/gnome-shell exec script_path/myscript.sh &> /dev/null

But also I think that it would be possible to detect the "windows manager command" by means of other system requests. However, for me defining WM_CMD in the crontab file is enough.

Best Answer

Try to use D-Bus to query session information from logind service. It has org.freedesktop.login1.Manager interface with several signal like SessionNew and SeatNew. org.freedesktop.login1.Seat and org.freedesktop.login1.User interfaces. It can help to get Session/Seat/User state.

Related Question