Bash Scripting – Wait for X Window to Appear or Disappear

bashpythonshellwindow

Inside a shell script, I need to wait for a window that has a string on its title to appear, do some action, and then wait for it to disappear, and do some other action.

Until yesterday, I had this simple code. The problem with it is that the disk can't be put in a power saving state while the script is left running, and it can be for many hours:

while :; do
    until wmctrl -l | grep -q "$string"; do   # until
        sleep 0.5
    done
    : do action 1

    while wmctrl -l | grep -q "$string"; do   # while
        sleep 0.5
    done
    : do action 2
done

Since I decided the mentioned code was insanely waking the disk, I went through the documentation of a few command line tools, and decided on xdotool to wait for the window to appear, and xprop to figure out when the window has vanished:

while :; do
    # we use `until' because sometimes xdotool just crashes
    until xdotool search -sync -all -onlyvisible -pid $pid -name "$string"; do
        :
    done

    # xdotool isn't trustworthy either, so check again
    wmctrl -l | grep -q "$string" ||
        continue

    : do action 1

    xprop -spy -root _NET_CLIENT_LIST_STACKING | while read line; do
        if [[ ! ${_line:-} || $_line = $line ]]; then
            _line=$line
            continue
        else
            _line=$line
            if wmctrl -l | grep -q "$string"; then
                continue
            else
                : do action 2
                break
            fi
        fi
    done
done

Now I have two new problems with the code above:

  • xdotool not only crashes and gives strange results, as I have workarounded before, but it also sucks about 15% of CPU while left waiting for the window to appear. So that means I got rid of simple code that wakes the disk, to write code that is left wasting the CPU for hours, and my intention was saving power in the first place.
  • xprop -spy will notify me every time I change focus (which I have workarounded through $_line) or create and destroy windows. That wakes the disk more frequently than xdotool.

I'm looking for a simple program that just waits for the window with the title $string to appear or disappear. It can be an existing command line tool, a python script, compilable C code…, but I should be able to integrate it somehow to my script (even if it just writes some information to a fifo)!

Best Answer

This should give you all (OK: most. What have I forgotten? Sockets?) file system activities which include writes:

strace -f command 2>&1 | 
  grep -e '^open.*O_CREAT' \
    -e ^write   \
    -e ^mkdir   \
    -e ^rmdir   \
    -e ^unlink  \
    -e ^rename  \
    -e ^chmod   \
    -e ^link    \
    -e ^symlink \
    -e ^mknod

With this information a working chroot environment can be created in tmpfs (as an action of last resort; maybe symlinks to tmpfs are enough). If the program is started in a RAM chroot then it does not have a chance to wake the disk directly. No write to its file system hierarchy is ever written to disk.

Related Question