如何从进程 ID 获取 X11 窗口? [英] How to get an X11 Window from a Process ID?

查看:59
本文介绍了如何从进程 ID 获取 X11 窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Linux 下,我的 C++ 应用程序使用 fork() 和 execv() 来启动 OpenOffice 的多个实例,以便查看一些幻灯片放映.这部分有效.

Under Linux, my C++ application is using fork() and execv() to launch multiple instances of OpenOffice so as to view some powerpoint slide shows. This part works.

接下来我希望能够将 OpenOffice 窗口移动到显示器上的特定位置.我可以使用 XMoveResizeWindow() 函数来做到这一点,但我需要为每个实例找到 Window.

Next I want to be able to move the OpenOffice windows to specific locations on the display. I can do that with the XMoveResizeWindow() function but I need to find the Window for each instance.

我有每个实例的进程 ID,我如何从中找到 X11 窗口?

I have the process ID of each instance, how can I find the X11 Window from that ?

更新 - 感谢安迪的建议,我已经完成了这个.我在这里发布代码是为了与 Stack Overflow 社区分享.

UPDATE - Thanks to Andy's suggestion, I have pulled this off. I'm posting the code here to share it with the Stack Overflow community.

不幸的是,Open Office 似乎没有设置 _NET_WM_PID 属性,所以这并不能最终解决我的问题,但它确实回答了这个问题.

Unfortunately Open Office does not seem to set the _NET_WM_PID property so this doesn't ultimately solve my problem but it does answer the question.

// Attempt to identify a window by name or attribute.
// by Adam Pierce <adam@doctort.org>

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>
#include <list>

using namespace std;

class WindowsMatchingPid
{
public:
    WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
        : _display(display)
        , _pid(pid)
    {
    // Get the PID property atom.
        _atomPID = XInternAtom(display, "_NET_WM_PID", True);
        if(_atomPID == None)
        {
            cout << "No such atom" << endl;
            return;
        }

        search(wRoot);
    }

    const list<Window> &result() const { return _result; }

private:
    unsigned long  _pid;
    Atom           _atomPID;
    Display       *_display;
    list<Window>   _result;

    void search(Window w)
    {
    // Get the PID for the current Window.
        Atom           type;
        int            format;
        unsigned long  nItems;
        unsigned long  bytesAfter;
        unsigned char *propPID = 0;
        if(Success == XGetWindowProperty(_display, w, _atomPID, 0, 1, False, XA_CARDINAL,
                                         &type, &format, &nItems, &bytesAfter, &propPID))
        {
            if(propPID != 0)
            {
            // If the PID matches, add this window to the result set.
                if(_pid == *((unsigned long *)propPID))
                    _result.push_back(w);

                XFree(propPID);
            }
        }

    // Recurse into child windows.
        Window    wRoot;
        Window    wParent;
        Window   *wChild;
        unsigned  nChildren;
        if(0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
        {
            for(unsigned i = 0; i < nChildren; i++)
                search(wChild[i]);
        }
    }
};

int main(int argc, char **argv)
{
    if(argc < 2)
        return 1;

    int pid = atoi(argv[1]);
    cout << "Searching for windows associated with PID " << pid << endl;

// Start with the root window.
    Display *display = XOpenDisplay(0);

    WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);

// Print the result.
    const list<Window> &result = match.result();
    for(list<Window>::const_iterator it = result.begin(); it != result.end(); it++)
        cout << "Window #" << (unsigned long)(*it) << endl;

    return 0;
}

推荐答案

我所知道的唯一方法是遍历窗口树,直到找到所需的内容.遍历并不难(如果需要示例,请查看 xwininfo.c 来查看 xwininfo -root -tree 的作用).

但是您如何识别您正在寻找的窗口呢?某些 应用程序设置了一个名为 _NET_WM_PID 的窗口属性.

我相信 OpenOffice 设置该属性的应用程序之一(大多数 Gnome 应用程序也是如此),所以您很幸运.

The only way I know to do this is to traverse the tree of windows until you find what you're looking for. Traversing isn't hard (just see what xwininfo -root -tree does by looking at xwininfo.c if you need an example).

But how do you identify the window you are looking for? Some applications set a window property called _NET_WM_PID.

I believe that OpenOffice is one of the applications that sets that property (as do most Gnome apps), so you're in luck.

这篇关于如何从进程 ID 获取 X11 窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆