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):

while :
    sleep 5
    if [ $P_STATE == 0 ]; then
         [ `xprintidle` -ge 25000 ] && P_STATE=1 && wmctrl -k on
         [ `xprintidle` -le 25000 ] && P_STATE=0

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:

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

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:


    sleep $WAIT_TIME

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

    ## My actions here

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.

  • What login manager are you using?
    – mmtauqir
    Apr 18, 2013 at 15:01
  • My login manager is lightdm
    – ABu
    Apr 18, 2013 at 21:57
  • This Super User question might be of help to you. I'm not sure it will answer your question completely though. Apr 20, 2013 at 0:32
  • 1
    It's not particularly robust, but you could check for the Gnome/KDE process...
    – jasonwryan
    Apr 20, 2013 at 1:17
  • 1
    You should document what you did as an answer; it may assist others.
    – jasonwryan
    Apr 20, 2013 at 10:55

6 Answers 6


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.


Use login session startup script ~/.xprofile to create some flag file for you. Be it ~/.xlogin_flag, then in your other script use inotifywatch from package inotify-tools to see it being created, touched or deleted.


Check output of w command. You will see login type (X display) in LOGIN@ field.


I think the simplest way to check if a user is connected in X11 is to check for processes that write to $HOME/.xsession-errors since when you login graphically, all you stderr is redirected there.

Otherwise just use the w command, as already suggested by @Grzegorz: if the FROM column starts with : then it is a graphical session.


Check in lightdm's runtime directory. On Arch with systemd and lightdm, when a user logs in, an xauthority file gets created.

$ whoami
$ sudo ls -al /run/lightdm/carl
total 4
drwx------ 2 carl    carl     60 Dec 11 19:40 .
drwx--x--x 8 lightdm lightdm 160 Dec 11 19:40 ..
-rw------- 1 carl    carl     55 Dec 11 19:40 xauthority

You could test for this with something like this in your while loop.

[[ -f /run/lightdm/${USER}/xauthority ]] && continue

If you're using systemd, you can interact with logind via D-Bus.

There's also a utility for that, loginctl.

So you do something simple like:

if [ -n "`loginctl | grep seat0`" ]; then
    ## user is logged in ##

Also, instead of polling, you can wait on a SessionNew D-Bus signal


while read line; do [[ $line == *"SessionNew"* ]] && break; done < \
<(dbus-monitor --system "type=signal,interface=org.freedesktop.login1.Manager,member=SessionNew")

# user session has started ...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .