Verax
Verax

Reputation: 2519

How to get top-level windows and their names using libxcb

I have a Linux desktop with 2 open windows: a terminal and a browser. I'm trying to get the name of those windows with libxcb. Here's my code based on examples I found at https://www.systutorials.com/docs/linux/man/3-xcb_query_tree_reply/

Here's my code:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <xcb/xcb.h>

void get_children(xcb_connection_t* c, xcb_window_t window, xcb_window_t** children, int* count)
{
    *count = 0;
    *children = NULL;

    auto cookie = xcb_query_tree(c, window);
    auto reply = xcb_query_tree_reply(c, cookie, NULL);
    if (reply)
    {
        *count = xcb_query_tree_children_length(reply);
        *children = xcb_query_tree_children(reply);

        free(reply);
    }
}

void get_name(xcb_connection_t* c, xcb_window_t window, char** name, int* length)
{
    *length = 0;
    *name = NULL;

    auto cookie = xcb_get_property(c, 0, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 0);
    auto reply = xcb_get_property_reply(c, cookie, NULL);
    if (reply)
    {
        *length = xcb_get_property_value_length(reply);
        *name = (char*)xcb_get_property_value(reply);

        free(reply);
    }
}

int main()
{
    auto c = xcb_connect(":0.0", NULL);
    auto screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
    auto rootWindow = screen->root;

    int nChildren;
    xcb_window_t* children;
    get_children(c, screen->root, &children, &nChildren);
    for (int i = 0; i < nChildren; i++)
    {
        auto wid = children[i];

        int length;
        char* name;
        get_name(c, wid, &name, &length);
        printf("%u %d\n", wid, length);
    }

    return 0;
}

This returns 40 windows all with their name's length of 0. For example:

20971989 0
20971802 0
20972112 0
20972308 0
... (truncated for brevity)

I'm trying to get something like the output of wmctrl -l.

What am I doing wrong?

Upvotes: 0

Views: 365

Answers (1)

Verax
Verax

Reputation: 2519

I figured out the problem. I needed to add a length to the xcb_get_property function call. The following code works.

auto cookie = xcb_get_property(c, 0, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000);

Upvotes: 1

Related Questions