首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得和同步所有X11窗口的完整列表?

如何获得和同步所有X11窗口的完整列表?
EN

Stack Overflow用户
提问于 2009-06-19 13:47:43
回答 3查看 11.2K关注 0票数 13

我想监视X11下所有打开的窗口。目前,我这样做如下:

  1. 最初,通过从根窗口递归调用XQueryTree来遍历整棵树
  2. 监听整个桌面上的子结构变化:XSelectInput( display, root_window, SubstructureNotifyMask | PropertyChangeMask )
  3. 处理所有MapNotify、UnmapNotify和DestroyNotify事件,更新进程中的窗口列表

我主要担心的是第一点,在递归过程中,XQueryTree将被多次调用。有没有办法确保这棵树在这段时间内不发生变化?换句话说,在某个时间点获得整棵树的“快照”?

另外,我注意到在某些X11系统中,并不是所有事件都能正确到达。例如,当在桌面上打开一个新窗口时,该窗口的MapNotify可能永远不会到达我的监视应用程序。这怎么可能呢?它有可能在到达前被扔掉吗?

更新:

我编写了一个小程序来监视根窗口上的X事件(见下文)。现在,当我运行这个程序并启动和退出xcalc时,我得到以下输出:

代码语言:javascript
复制
Reparented: 0x4a0005b to 0x1001e40
Mapped    : 0x1001e40
Destroyed : 0x1001e40

就这样。我从未被告知真正的窗口(0x4a0005b)正在被销毁。甚至连地图都没有!有人能告诉我为什么吗?SubStructureNotifyMask只会导致直接子窗口的事件被发送而不是整个子树吗?

顺便说一下,这显然不是在Compiz运行时发生的。然后不进行任何赔偿:

代码语言:javascript
复制
Mapped    : 0x4a0005b
Mapped    : 0x4e00233
Destroyed : 0x4a0005b
Destroyed : 0x4e00233

监测程序来源:

代码语言:javascript
复制
#include <X11/Xlib.h>
#include <cstdio>

int main()
{
    Display *display;
    Window rootwin;

    display = XOpenDisplay( NULL );
    rootwin = DefaultRootWindow( display );
    XSelectInput( display, rootwin, SubstructureNotifyMask );

    XEvent event;

    while ( 1 ) {
        XNextEvent( display, &event );
        if ( event.type == MapNotify ) {
            XMapEvent *mapevent = (XMapEvent *)&event;
            printf( "Mapped    : 0x%x\n", (unsigned int)(mapevent->window) );
        }
        if ( event.type == DestroyNotify ) {
            XDestroyWindowEvent *destroywindowevent = (XDestroyWindowEvent *)&event;
            printf( "Destroyed : 0x%x\n", (unsigned int)(destroywindowevent->window) );
        }
        if ( event.type == ReparentNotify ) {
            XReparentEvent *reparentevent = (XReparentEvent *)&event;
            printf( "Reparented: 0x%x to 0x%x\n", (unsigned int)(reparentevent->window), (unsigned int)(reparentevent->parent) );
        }
    }

    return 0;
}
EN

回答 3

Stack Overflow用户

发布于 2009-06-19 14:17:50

看看xwininfo

您可能还喜欢xpropxspy来获取更多信息。

更新:是的。尝试将xwininfo-root-tree-children一起使用,以使所有的窗口都参与进来。

并且可以使用xprop -spy跟踪更改。

票数 16
EN

Stack Overflow用户

发布于 2010-03-17 11:53:04

我相信抓取X服务器(XGrabServer(3))将防止对窗口层次结构的更改。这是一个有点沉重的手,所以你可能应该做它,只有当你真的需要它。

对于一个代码示例,它可以遍历窗口层次结构、构建树、使用窗口事件来保持其最新,并忽略由于种族而不可避免的X协议错误,请参阅VirtualBox源代码中的文件VirtualBox。

票数 3
EN

Stack Overflow用户

发布于 2013-08-15 07:54:03

X11是一种远程协议。这意味着当您查询X服务器的任何信息时,总是会得到您自己的副本。当X服务器更新其内部数据结构时,您的副本不会更改。

这意味着当您遍历树时,树不会突然改变,但是当您使用其中的信息(比如检查窗口)时,该信息可能会过时(可能有人已经关闭了该窗口)。这就是为什么您需要进行正确的错误处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1018052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档