Wie erhalte und synchronisiere ich eine vollständige Liste aller X11-Fenster?

Ich möchte alle offenen Fenster unter X11 überwachen. Derzeit mache ich das wie folgt:

Durchlaufen Sie zunächst den gesamten Baum, indem Sie XQueryTree rekursiv aus dem Stammfenster aufrufenÜberwachen von Änderungen an der Unterstruktur auf dem gesamten Desktop:XSelectInput( display, root_window, SubstructureNotifyMask | PropertyChangeMask )Behandeln Sie alle MapNotify-, UnmapNotify- und DestroyNotify-Ereignisse und aktualisieren Sie dabei meine eigene Liste von Fenstern

Ich mache mir hauptsächlich Sorgen um Punkt 1. Während der Rekursion wird XQueryTree mehrmals aufgerufen. Gibt es eine Möglichkeit, um sicherzustellen, dass sich der Baum in der Zwischenzeit nicht ändert? Mit anderen Worten, um einen "Schnappschuss" des gesamten Baums zu einem bestimmten Zeitpunkt zu erhalten?

Außerdem ist mir aufgefallen, dass unter einigen X11-Systemen nicht alle Ereignisse korrekt eintreffen. Wenn Sie beispielsweise ein neues Fenster auf dem Desktop öffnen, wird MapNotify für dieses Fenster möglicherweise nie in meiner Überwachungsanwendung angezeigt. Wie kann das sein? Ist es möglich, dass es vor der Ankunft weggeworfen wird?

Aktualisieren:

Ich habe ein kleines Programm geschrieben, das X-Ereignisse im Root-Fenster überwacht (siehe unten). Wenn ich dieses Programm starte und xcalc beende, erhalte ich die folgende Ausgabe:

<code>Reparented: 0x4a0005b to 0x1001e40
Mapped    : 0x1001e40
Destroyed : 0x1001e40
</code>

Das ist es.Ich werde nie darüber informiert, dass das echte Fenster (0x4a0005b) zerstört wird. Nicht einmal davon wird abgebildet! Kann mir jemand sagen warum nicht? Verursacht SubStructureNotifyMask nur Ereignisse vonDirekte Unterfenster, die anstelle des gesamten Teilbaums gesendet werden sollen?

Übrigens passiert dies anscheinend nicht, wenn Compiz ausgeführt wird. Dann wird keine Reparatur durchgeführt:

<code>Mapped    : 0x4a0005b
Mapped    : 0x4e00233
Destroyed : 0x4a0005b
Destroyed : 0x4e00233
</code>

Überwachungsprogrammquelle:

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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage