c - 我如何获取并同步所有 X11 窗口的完整列表?

标签 c linux x11 race-condition xorg

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

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

我主要担心的是第1点,在递归过程中,会多次调用XQueryTree。有什么方法可以确保树不会同时发生变化?换句话说,要在某个时间点获取整棵树的“快照”?

此外,我注意到在某些 X11 系统下,并非所有事件都能正确到达。例如,当在桌面上打开一个新窗口时,该窗口的 MapNotify 可能永远不会到达我的监控应用程序。怎么会这样?有没有可能还没到就扔掉了?

更新:

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

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

就是这样。 我从未收到有关真实窗口 (0x4a0005b) 被销毁的通知。甚至都没有映射! 谁能告诉我为什么不呢? SubStructureNotifyMask 是否仅导致发送直接 子窗口的事件而不是整个子树?

顺便说一句,这显然不会在 Compiz 运行时发生。然后没有重新设置:

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

监控程序源码:

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

最佳答案

看看 xwininfo

您可能还喜欢 xpropxspy 以获得更多信息。

更新:是的。尝试将 xwininfo-root-tree-children 一起使用以获取所有窗口。

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

关于c - 我如何获取并同步所有 X11 窗口的完整列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1018052/

相关文章:

将 1d 缓冲区重新组织为 2d 数组时崩溃

c - 尝试了解 .h 文件或其 .c 实现文件中声明结构之间的差异

linux - sh 文件无法正常工作,但 sh 中的命令可以

linux - 对 git 配置使用 INCLUDE

R - 无法安装包 "rgl"

c++ - X11 键按下导致键按下和释放

x11 - gnome-terminal:如何以编程方式消除滚动条?

c++ - Nintendo DS Homebrew 中的 Alpha 混合 Sprite

c - Pthread - time.h::sleep() 和 pthread.h::pthread_yield() 有什么区别?

linux - 如何在 Ubuntu 中获取/安装 Source Insight