如何获取和同步,所有X11窗口的完整列表? [英] How do I obtain, and synchronize, a complete list of all X11 windows?

查看:1544
本文介绍了如何获取和同步,所有X11窗口的完整列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 最初由递归从根窗口
  2. 调用XQueryTree走在整个树
  3. 监听整个桌面上变化子: XSelectInput(显示器,root_window,SubstructureNotifyMask | PropertyChangeMask)

  4. 处理所有MapNotify,UnmapNotify和DestroyNotify事件,更新的过程中我自己的窗口列表

我主要是担心点1.在递归,XQueryTree将被调用多次。有没有什么办法,以保证树没有在此期间改变?换言之,以在某个时间点获得整个树的快照?

另外,我注意到,在某些X11系统上,不是所有的事件正确到达。例如,在桌面上打开一个新的窗口时,MapNotify该窗口可能从来没有在我的监控应用到达。这怎么可能?有没有可能是前到达扔掉?

更新:

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

 重设父:0x4a0005b到0x1001e40
映射:0x1001e40
摧毁:0x1001e40

就是这样。 我从来没有通知被破坏真正的窗口(0x4a0005b)的。甚至不是它映射!谁能告诉我为什么不呢?难道只有SubStructureNotifyMask造成的直接子窗口的事件被发送,而不是整个子树?

顺便说一句,这显然不Compiz的时候运行发生。然后,没有重排根目录完成:

 映射:0x4a0005b
映射:0x4e00233
摧毁:0x4a0005b
摧毁:0x4e00233

监测节目源:

 的#include< X11 / Xlib.h>
#包括LT&;&cstdio GT;诠释的main()
{
    显示*显示;
    窗口rootwin;    显示= XOpenDisplay(NULL);
    rootwin = DefaultRootWindow(显示);
    XSelectInput(显示,rootwin,SubstructureNotifyMask);    XEvent事件;    而(1){
        XNextEvent例行(显示器,功放及;事件);
        如果(event.type == MapNotify){
            XMapEvent * mapevent =(XMapEvent *)及事件;
            的printf(映射:0X%X \\ n,(无符号整数)(mapevent->窗口));
        }
        如果(event.type == DestroyNotify){
            XDestroyWindowEvent * destroywindowevent =(XDestroyWindowEvent *)及事件;
            的printf(灭亡:0X%X \\ n,(无符号整数)(destroywindowevent->窗口));
        }
        如果(event.type == ReparentNotify){
            XReparentEvent * reparentevent =(XReparentEvent *)及事件;
            的printf(重设父:为0x%x可为0x%X \\ n,(无符号整数)(reparentevent->窗口),(无符号整数)(reparentevent->母公司));
        }
    }    返回0;
}


解决方案

有一个看看 xwininfo

您可能还喜欢 xprop xspy 获取更多信息。

更新:没错。尝试使用 xwininfo -root 与任 - 树 - 儿童涉足所有窗口。

和变化可以用 xprop -spy 进行跟踪。

I want to monitor all the open windows under X11. Currently, I'm doing this as follows:

  1. Initially walking the whole tree by recursively calling XQueryTree from the root window
  2. Listening for substructure changes on the whole desktop: XSelectInput( display, root_window, SubstructureNotifyMask | PropertyChangeMask )
  3. Handling all MapNotify, UnmapNotify and DestroyNotify events, updating my own list of windows in the process

I'm mainly worried about point 1. During the recursion, XQueryTree will be called multiple times. Is there any way to ensure that the tree does not change in the meantime? In other words, to get a 'snapshot' of the whole tree at one point in time?

Also, I've noticed that under some X11 systems, not all events arrive correctly. For example, when opening a new window on the desktop, MapNotify for that window may never arrive at my monitoring application. How can this be? Is it possible that it is thrown away before arriving?

Update:

I've written a small program that will monitor X events on the root window (see below). Now, when I run this program and start and quit xcalc, I get the following output:

Reparented: 0x4a0005b to 0x1001e40
Mapped    : 0x1001e40
Destroyed : 0x1001e40

That's it. I'm never notified of the real window (0x4a0005b) being destroyed. Not even of it being mapped! Can anyone tell me why not? Does SubStructureNotifyMask only cause events of direct subwindows to be sent instead of the whole subtree?

By the way, this apparently does not happen when Compiz is running. Then no reparenting is done:

Mapped    : 0x4a0005b
Mapped    : 0x4e00233
Destroyed : 0x4a0005b
Destroyed : 0x4e00233

Monitoring program source:

#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;
}

解决方案

Have a look at xwininfo.

You might also like xprop and xspy for getting more info.

Update: Yep. Try using xwininfo and -root with either -tree or -children to get all windows involved.

And changes can be tracked with xprop -spy.

这篇关于如何获取和同步,所有X11窗口的完整列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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