1

If I run these commands:

...
geany --new-instance --no-msgwin --no-session --no-terminal -c pathtoconfig/ &
pid=$!
echo $pid
wmctrl -lp
read -p "waiting..."
...

the resulting PID does not match that of the geany process launched. But if a sleep 1 command is inserted before reading the PID (after the geany line), then the PID is correct. The reason for this is that windowing takes some time, so wmctrl -lp provides preliminary information which does not much precisely the right PID. What would be the best way to wait for geany to complete launching before the new window has stabilized and wmctrl is aware of it?

Update: - Run on Lubuntu 16.04 / HP ProBook 6360b.

  • Actual PID for comparison was obtained with wmctrl -lp that includes PID in the list.

  • PID is fetched correctly by $!, what takes some time to update is the one provided by wmctrl -lp, that is different after some time (some 0.27s for geany, some 0.16s for leafpad), as if the window manager would take some time to update the PID.

  • Can't reproduce this behaviour. Can you try run the geany this two ways: geany & and geany --new-instance --no-msgwin --no-session --no-terminal &. Did the problem remained? – MiniMax Jul 23 '17 at 15:18
  • @MiniMax strangely enough, yes and no. In a battery of tests, have tried the original configuration (doesn't get the correct PID), and then the simplified one, only geany & (it does get the correct PID). Then tried several alternatives, removing some options (doesn't get the correct PID), and finally the simplified one again (and now, does NOT get the correct PID). This was done isolating the piece of code, to make sure that it only relies on launching geany. – nightcod3r Jul 23 '17 at 22:12
  • Can you try another program the same way? May be Netbeans or Libreoffice. I tried Netbeans, it was launching about 10 second, but both PIDs the same. I think geany launching time, does not matter because of how fork–exec works. And another helpful answer about & operator: process in the background. By the way, how you get second PID for comparing? – MiniMax Jul 23 '17 at 23:04
  • @MiniMax Trying with geany & the PID after settling is 11078, $! got 11118, with leafpad was 11078, and $! got 11173. In both cases, the PID matches perfectly when sleep 1 is added. So, in principle it doesn't seem to be related to launching time, but waiting for some time actually helps. – nightcod3r Jul 24 '17 at 07:33
  • @MiniMax To be more precise, geany & will work fine for a delay of 0.27s, while leafpad & does work for delays over 0.16s. Something is going on after the program is launched. (Technical data added to the question.) – nightcod3r Jul 24 '17 at 07:46
  • Please, @MiniMax, check the update in the question. The problem now focuses on wmctrl, as $! seems to work just fine. – nightcod3r Jul 24 '17 at 08:09
  • Now I understand, why I could not reproduce the problem. I was not using wmctrl, I just was doing geany & pid=$!; echo $pid, then was running ps manually and checking geany's actual PID. I thought, that wmctrl -lp read -p "waiting..." was added for context only. :) – MiniMax Jul 24 '17 at 09:07
  • @MiniMax I should had make it clear, my fault. So, now your system reproduces the problem, correct? About the same delays to make it work? – nightcod3r Jul 24 '17 at 11:56
  • Yes, the same behavior now. But it is not only about PID, but whole program's entry appearing with delay. For example, Netbeans appears in the wmctrl -lp list after 3 seconds it was launched. And this is logical, because this list shows "windows being managed by the window manager". And running program's binary file and appearing this program in the window, happens at the not same time. Hence, we have a delay, between these two events. Now, the question is: how catch this event, right? – MiniMax Jul 24 '17 at 13:33
  • @MiniMax Correct. The obvious loop checking wmctrl -lp until the window shows up doesn't look like an elegant solution. Any hint in a different direction? (Title has been updated.) – nightcod3r Jul 24 '17 at 13:41
  • You can add sleep 0.1 in to the loop checking. It will check 10 times per second. For reduce the impact to the PC performance. – MiniMax Jul 24 '17 at 14:44

1 Answers1

1

xdotool search --sync --pid "$PID" will do exactly, what you want. I found this method here

--sync - Block until there are results. This is useful when you are launching an application and want to wait until the application window is visible.

Template:

#!/bin/bash

geany &
PID=$!

if xdotool search --sync --pid "$PID" > /dev/null; then
     # if window with the specific PID has appeared
     # then doing something here
fi

Note:

Doesn't work with some applications, Netbeans for example, because of this:

--pid PID - Match windows that belong to a specific process id. This may not work for some X applications that do not set this metadata on its windows.

If change --pid "$PID" to --name netbeans or --class netbeans it works too.

Working example:

This script calculate delay in milliseconds, between launching geany & and the geany's window appearing.

#!/bin/bash

geany &
PID=$!
time_start=$(date '+%s%3N')
if xdotool search --sync --pid "$PID" > /dev/null; then
    time_end=$(date '+%s%3N')
    time_interval=$((time_end - time_start))
    printf "%'d ms\n" "$time_interval"
fi

Output:

$ ./delay_calculate.sh 
553 ms
MiniMax
  • 4,123