19

Does anyone know how to get the PID of the top active window and then how to get the properties of the window using the PID? I mean properties like process name, program name, etc.

I'm using Qt under Linux (Ubuntu 9.10).

Charles Stewart
  • 11,185
  • 4
  • 43
  • 84
user247991
  • 209
  • 1
  • 2
  • 4
  • Your app knows its own pid, is that what you want? – Tobu Jan 11 '10 at 11:43
  • 2
    QT is not a language, it's a toolkit. QT is written in C++, but has bindings for many other languages. Are you using C++? – James Polley Jan 11 '10 at 11:45
  • @JamesPolley QT is not entirely unlike a language in that it can act as a 'write once, compile everywhere' tool, where porting something like POSIX calls would require writing separate code for WinAPI, Android, etc.. – Wyatt Ward Dec 05 '16 at 00:49

9 Answers9

25

there is a command in linux call xprop which is a utility for displaying window properties in an X server. In linux xprop -root gives you the root windows properties and also other active programs. then you can get the ID of the active window using this command:

xprop -root | grep _NET_ACTIVE_WINDOW\(WINDOW\)

to get just the active window ID ( without "_NET_ACTIVE_WINDOW(WINDOW): window id # " in the beginning of the line ) use this command:

xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'

now you can save this command output in a user defined variable:

myid=xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'

xprop have an attribute call -id. This argument allows the user to select window id on the command line. We should look for _NET_WM_PID(CARDINAL) in output ... so we use this command:

xprop -id $myid | awk '/_NET_WM_PID\(CARDINAL\)/{print $NF}'

this gives you the topmost active window process ID.

to be more trickey and do all things in just 1 command ... :

 xprop -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}') | awk '/_NET_WM_PID\(CARDINAL\)/{print $NF}'

Now I can run these commands via my C++ program ( in linux ) using popen function, grab stdout and print or save it. popen creates a pipe so we can read the output of the program we are invoking.

( you can also use '/proc' file system and get more detail of a PID ('/proc/YOUR_PID/status') )

#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;

inline std::string exec(char* cmd) {
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[128];
    std::string result = "";
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL)
                result += buffer;
    }
    pclose(pipe);
    return result;
}

int main()
{
    //we uses \\ instead of \ ( \ is a escape character ) in this string
 cout << exec("xprop -id $(xprop -root | awk '/_NET_ACTIVE_WINDOW\\(WINDOW\\)/{print $NF}') | awk '/_NET_WM_PID\\(CARDINAL\\)/{print $NF}'").c_str(); 
 return 0;
}
Michel Gokan Khan
  • 2,332
  • 3
  • 26
  • 52
  • But note that this will often fail because as several other answer have noted, _NET_WM_PID is an attribute that often is not there. – Charles Stewart Feb 24 '11 at 09:11
  • 6
    you know you can specify the variables on xprop command line? like in `xprop _NET_WM_PID -id $window_id` – nonchip Mar 14 '12 at 14:50
19

One of things about X is that it's network transparent. It's quite possible that the actual window being displayed at the top (which has focus) is running on a machine other than your own in which case, the process id of the process running inside the window will make no sense on your machine.

Can you elaborate a little on what you want to do? I think there are some missing details here. Ideally, you should work at the X level rather than at the machine specific one.

Noufal Ibrahim
  • 66,768
  • 11
  • 123
  • 160
  • 1
    The window with focus need not be on top. – Charles Stewart Jan 12 '10 at 08:33
  • I guess having focus is what the OP meant but he had his WM configured to focus only on the raised window. In any case, my point about the network transparency stands. – Noufal Ibrahim Jan 12 '10 at 09:05
  • @Noufal: I agree that focus is what he probably wants (see my answer), but that's not what he asked... You could say the pid of the X server is the right pid in this case, since it is (usually!) the process that listens to the port 6000 (or whatever). – Charles Stewart Jan 12 '10 at 09:25
  • He wants the pid of the client. The application using the window. Not that of the X server. What I'm saying is that X is network transparent and so the pid of the process inside the window might not make sense (if the client is another machine etc.). The pid of the X server will be the same regardless of which window you're checking on that server. I fail to see what you're driving at. – Noufal Ibrahim Jan 12 '10 at 09:34
6

The PID of a window owner is stored in the X property _NET_WM_PID. Note that this is only a de-facto standard.

You have to find the id of the window first, then you can query for the property. I don't know of any abstraction QT provides for this, so you will probably have to use xlib or xcb.

Play with the tool xprop for starters.

ypnos
  • 45,954
  • 14
  • 88
  • 130
5

Am very very late to the party, but I had a similar problem, and I think this can help someone else who has the same problem. There is a command line trick to do this, you can try execvp'ing it, or executing it redirecting the output to your code

xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) _NET_WM_NAME WM_CLASS

gives the window name, as well as the program name. Eg, for this tab, it gives me

_NET_WM_NAME(UTF8_STRING) = "linux - Getting pid and details for topmost window - Stack Overflow - Mozilla Firefox"

WM_CLASS(STRING) = "Navigator", "Firefox"
Arun
  • 2,629
  • 3
  • 14
  • 13
5

xlib's XGetInputFocus will tell you which window has focus, which is probably more interesting than which is topmost. Cf. Xfree86's XGetInputFocus manpage.

If it's really the topmost window, and not the window-with-focus you're after, well, I don't think there is a simple call to do that, because xlib doesn't seem to offer any way of querying the global stacking order, which is the data structure that tells you which windows are in front of which others.

Once you have the right window id, xprop will list the pid under _NET_WM_PID_ - though not all windows have such a property...

Postscript More thoughts; long time since I've thought about xlib...

To summarise:

  1. X does not offer any reliable association between window ids and pids, and as Noufal observes, the windows served on an X desktop may come from many different machines, and two remote clients might happen to use the same PID, since it is only unique per machine. Cf. How to get an X11 Window from a Process ID?

  2. X does not seem to offer an interface asking which is the topmost window, or whether one window occludes another. Likewise with privileged access... Cf. How to identify top-level X11 windows using xlib?

  3. Commonly available window managers and Qt don't give you privileged access to X

  4. Without both a way of finding the topmost window, and a reliable association of the window id to the matching pid, we can't solve the question.

  5. We can find which window has focus, and this is probably what we want. But again, without the wid to pid map ...

So, sorry, it looks like it can't be done.

Community
  • 1
  • 1
Charles Stewart
  • 11,185
  • 4
  • 43
  • 84
3

I am voting up Michel Kogan’s answer, and adding this concise summary of it:

ps -o pid,comm,args $(xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") -f _NET_WM_PID 0c " \$0\\n" _NET_WM_PID | awk "{print \$2}")

The above will show the following for the currently active window: PID, command name (only the executable name), command with all its arguments.

Community
  • 1
  • 1
Amir
  • 593
  • 5
  • 16
1

I run this command on a terminal:

sleep 5s; ps -Flwwp $(xdotool getwindowpid $(xdotool getwindowfocus))

Run it, change the focus to the relevant window, wait 5 seconds, then back to terminal. Voilà!

Pablo Bianchi
  • 1,039
  • 1
  • 15
  • 23
0

Extracted the gist of xprop into https://github.com/mondalaci/current-window-linux

Works but sometimes segfaults - needs to be fixed and cleaned up.

László Monda
  • 1,289
  • 1
  • 14
  • 23
0

Install wmctrl (from the repositories). wmctrl -lp could be what you want. You can always take a look at the source if you need it from your program.

Diego Torres Milano
  • 57,580
  • 7
  • 101
  • 124
  • Cf. what wmctrl says about the -p option: "Include PIDs in the window list. Very few X applications support this feature." Note also that the WM may or may not support EWMH; Qt can be used with noncomformant WMs. – Charles Stewart Jan 12 '10 at 08:32