获取最顶层窗口的pid和详细信息

时间:2010-01-11 11:40:31

标签: linux qt pid xlib

有谁知道如何获得顶部活动窗口的PID,然后如何使用PID获取窗口的属性?我的意思是流程名称,程序名称等属性

我在Linux下使用Qt(Ubuntu 9.10)。

9 个答案:

答案 0 :(得分:24)

linux中有一个命令调用xprop,它是一个用于在X服务器中显示窗口属性的实用程序。在linux xprop -root中为您提供了根窗口属性以及其他活动程序。然后您可以使用以下命令获取活动窗口的ID:

xprop -root | grep _NET_ACTIVE_WINDOW\(WINDOW\)

获取只是活动窗口ID(在行的开头没有“_NET_ACTIVE_WINDOW(WINDOW):window id#”)使用此命令:

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

现在您可以将此命令输出保存在用户定义的变量中:

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

xprop有一个属性call -id。此参数允许用户在命令行上选择窗口ID。我们应该在输出中查找_NET_WM_PID(CARDINAL)...所以我们使用这个命令:

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

这为您提供了最顶层的活动窗口进程ID。

更加三色,只用一个命令做所有事情......:

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

现在我可以使用popen函数通过我的C ++程序(在linux中)运行这些命令,获取stdout并打印或保存它。 popen创建一个管道,以便我们可以读取我们正在调用的程序的输出。

(你也可以使用'/ proc'文件系统获取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;
}

答案 1 :(得分:19)

关于X的一个问题是它的网络是透明的。显示在顶部(具有焦点)的实际窗口很可能在您自己以外的机器上运行,在这种情况下,窗口内运行的进程的进程ID在您的计算机上没有任何意义。

你能详细说明你想做什么吗?我认为这里有一些遗漏的细节。理想情况下,您应该在X级而不是机器级别工作。

答案 2 :(得分:5)

窗口所有者的PID存储在X属性_NET_WM_PID中。请注意,这只是事实上的标准。

您必须先找到窗口的ID,然后才能查询该属性。我不知道QT为此提供了什么抽象,所以你可能不得不使用xlib或xcb。

使用工具xprop为初学者播放。

答案 3 :(得分:5)

xlib的XGetInputFocus会告诉你哪个窗口有焦点,这可能比最顶层的窗口更有趣。参看Xfree86的XGetInputFocus manpage

如果它真的是最顶层的窗口,而不是你所关注的窗口,那么,我认为没有一个简单的调用来做到这一点,因为xlib似乎没有提供任何方式查询全局堆叠顺序,这是一种数据结构,告诉您哪些窗口位于其他窗口的前面。

一旦你有了正确的窗口ID,xprop将列出_NET_WM_PID_下的pid - 虽然并非所有窗口都有这样的属性......

后记更多想法;很长一段时间以来,我一直在考虑xlib ......

总结:

  1. X不提供窗口ID和pids之间的任何可靠关联,并且正如Noufal所观察到的,在X桌面上提供的窗口可能来自许多不同的机器,并且两个远程客户端可能碰巧使用相同的PID,因为它每台机器只有一个。参看How to get an X11 Window from a Process ID?

  2. X似乎没有提供一个界面,询问哪个是最顶层的窗口,或者一个窗口是否遮挡另一个窗口。同样具有特权访问权限...... How to identify top-level X11 windows using xlib?

  3. 常用的窗口管理器和Qt不会授予您对X的特权访问权

  4. 如果没有找到最顶层窗口的方法,以及窗口ID与匹配pid的可靠关联,我们无法解决问题。

  5. 我们可以找到哪个窗口有焦点,这可能就是我们想要的。但是再次,没有wid到pid地图......

  6. 所以,抱歉,看起来无法完成。

答案 4 :(得分:5)

派对非常晚,但我遇到了类似的问题,我认为这可以帮助那些遇到同样问题的人。 有一个命令行技巧来执行此操作,您可以尝试执行execvp,或执行它将输出重定向到您的代码

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

给出窗口名称以及程序名称。 例如,对于这个标签,它给了我

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

WM_CLASS(STRING) = "Navigator", "Firefox"

答案 5 :(得分:2)

我正在投票Michel Kogan’s answer,并添加了这个简明的摘要:

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}")

上面将显示当前活动窗口的以下内容:PID,命令名称(仅可执行文件名称),带有所有参数的命令。

答案 6 :(得分:1)

我在终端上运行此命令:

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

运行它,将焦点更改到相关窗口,等待5秒钟,然后返回终端。瞧!

答案 7 :(得分:0)

安装wmctrl(来自存储库)。 wmctrl -lp可能是你想要的。如果您的程序需要,可以随时查看来源。

答案 8 :(得分:0)

将xprop的要点提取到https://github.com/mondalaci/current-window-linux

工作但有时会出现段错误 - 需要修复和清理。