How to identify top-level X11 windows using xlib?

前端 未结 3 672
南旧
南旧 2020-12-05 03:27

I\'m trying to get a list of all top level desktop windows in an X11 session. Basically, I want to get a list of all windows that are shown in the window managers applicatio

相关标签:
3条回答
  • 2020-12-05 04:01

    If you don't have to use Xlib, using GDK's gdk_screen_get_window_stack() and gdk_window_get_window_type() may help you out for your needs.

    0 讨论(0)
  • 2020-12-05 04:14

    I have a solution!

    Well, sort of.

    If your window manager uses the extended window manager hints (EWMH), you can query the root window using the "_NET_CLIENT_LIST" atom. This returna list of client windows the window manager is managing. For more information, see here.

    However, there are some issues with this. For a start, the window manager in use must support the EWMH. KDE and GNOME do, and I'm sure some others do as well. However, I'm sure there are many that don't. Also, I've noticed a few issues with KDE. Basically, some non-KDE applications don't get included in the list. For example, if you run xcalc under KDE it won't show up in this list.

    If anyone can provide any improvements on this method, I'd be glad to hear them. For reference, the code I'm using is listed below:

        Atom a = XInternAtom(m_pDisplay, "_NET_CLIENT_LIST" , true);
        Atom actualType;
        int format;
        unsigned long numItems, bytesAfter;
        unsigned char *data =0;
        int status = XGetWindowProperty(m_pDisplay,
                                    rootWindow,
                                    a,
                                    0L,
                                    (~0L),
                                    false,
                                    AnyPropertyType,
                                    &actualType,
                                    &format,
                                    &numItems,
                                    &bytesAfter,
                                    &data);
    
        if (status >= Success && numItems)
        {
            // success - we have data: Format should always be 32:
            Q_ASSERT(format == 32);
            // cast to proper format, and iterate through values:
            quint32 *array = (quint32*) data;
            for (quint32 k = 0; k < numItems; k++)
            {
                // get window Id:
                Window w = (Window) array[k];
    
                qDebug() << "Scanned client window:" << w;
            }
            XFree(data);
        }
    
    0 讨论(0)
  • 2020-12-05 04:16

    To expand on the previous solution, if you want to then get the window names:

    // get window Id:
    Window w = (Window) array[k];
    
    char* name = '\0';
    status = XFetchName(display, w, &name);
    if (status >= Success)
    {
        if (name == NULL)
            printf("Found: %ul  NULL\n", w);
        else
            printf("Found: %ul  %s\n", w, name);
    }
    XFree(name);
    
    0 讨论(0)
提交回复
热议问题