rust-x-bindings / rust-xcb

Rust bindings and wrapper for XCB.
MIT License
165 stars 64 forks source link

Using `GetProperty` to get `_NET_CLIENT_LIST` #143

Closed RealKC closed 2 years ago

RealKC commented 2 years ago

Hello!

I'm trying to use your library to get a list of all windows on the screen, I've managed to do something like this:

    let wm_client_list = connection.send_request(&x::InternAtom {
        only_if_exists: true,
        name: "_NET_CLIENT_LIST".as_bytes(),
    });
    let wm_client_list = connection.wait_for_reply(wm_client_list)?;
    let wm_client_list = if wm_client_list.atom() == ATOM_NONE {
        return Err(Error::WmDoesNotSupportEwmh);
    } else {
        wm_client_list.atom()
    };
    for root_screen in setup.roots() {
        let window = root_screen.root();
        let pointer_cookie = connection.send_request(&x::QueryPointer { window });

        let pointer_reply = connection.wait_for_reply(pointer_cookie)?;
        if pointer_reply.same_screen() {
            let list = connection.send_request(&x::GetProperty {
                delete: false,
                window,
                property: wm_client_list,
                r#type: ATOM_NONE, // FIXME: This should be ATOM_ANY, but xcb doesn't expose it, I looked in the xproto.h header and they seem to have the same value tho
                long_offset: 0,
                long_length: 0,
            });
            let list = connection.wait_for_reply(list)?;
        }
    }

However, I'm not sure how to proceed further, inspecting the type of the list gives me Atom("Window" ; 33) but inspecting the length gives me 0. And I'm unsure how to get a list of windows from this either.

Looking at the spec I see that the type of the propriety should be WINDOW[]/32, I assume that means it's an array of windows where each element is 32 bits?

(Also I'm not entirely sure r#type: ATOM_ANY(had it existed) is necessarily correct, but that's what I found in a stackoverflow post, and changing it to ATOM_WINDOW doesn't change anything)

Also my WM does support EWMH, see here (awesomewm's source code).

(I'm using 1.0.0-beta.3 from crates.io)

RealKC commented 2 years ago

Closing as the linked PR adds an example (Thanks btw!) and I figured my issue (long_length has to be nonzero, and I believe you'll get (at most) that many values back).

rtbo commented 2 years ago

Yes, after you can cast value to u32 and use Window::new. I pushed a few minutes ago a change allowing to cast value to Window directly. Will be in the fourth beta (if any) or in 1.0

RealKC commented 2 years ago

Thanks a lot!