You are not logged in.

#1 2011-02-11 00:04:43

rich_o
Member
Registered: 2008-07-28
Posts: 49

How to get Window ID with python?

Hello,

how do i get the window id of a specific window, eg. a movie played with mplayer in python? I can do s.th. like

xwininfo -name MPlayer 

, but can't find a more pythonic way. Any ideas?

Thanks,
rich_o

Last edited by rich_o (2011-02-11 00:15:20)

Offline

#2 2011-02-12 16:38:05

hbekel
Member
Registered: 2008-10-04
Posts: 311

Re: How to get Window ID with python?

Afaik there are direct python to Xlib bindings. In Xlib, the XQueryTree() function can be used to traverse the window hierarchy. It starts from the root window or a specific window and gives you a list of window ids of the windows child windows. XGetClassHint allows you to receive the class name and class for a specific window id. That's the c way to do it. If you have a direct binding for python, you'll likely have to do it the same way. There may be other libs that provide Xlib bindings in a more pythonic fashion.

Last edited by hbekel (2011-02-12 16:48:21)

Offline

#3 2011-02-13 20:58:19

Eratosthenes
Member
Registered: 2009-11-02
Posts: 19

Re: How to get Window ID with python?

This is python-xlib in community. I have been using it in fpdb and found it to be a pain in the butt. It has been causing some crashes on various systems. It also doesn't handle things like non-ascii chars in window titles. I have gone back to using xwininfo to get the same information.

Offline

#4 2011-02-13 22:39:39

BurntSushi
Member
From: Massachusetts
Registered: 2009-06-28
Posts: 362
Website

Re: How to get Window ID with python?

This is actually sufficiently more complex that it would seem at first. Iterating over the QueryList of the root window isn't quite enough---since you're going to get a lot more results than you otherwise would. (There are many windows that usually make up each client.)

There are two approaches here. You can go with the QueryList idea, but you'll need to check that WM_STATE is defined for each particular window (this is how you tell whether it's a top-level window or not). Alternatively, if you're using any sort of standardized window manager, you could rely on the _NET_CLIENT_LIST property that is defined on the root window. (This is an EWMH standard.) In fact, in the former method, whether WM_STATE is set or not is also a standard, but an older one (the ICCCM standard).

I prefer using the _NET_CLIENT_LIST way. The property is maintained by the window manager and contains a list of all window IDs that the window manager is currently "managing."

While you can use python-xlib (and in my experience, it is perfectly suitable), you might also try xpyb, which is the Python version of XCB. The following should do the job you're looking for:

import struct

import xcb, xcb.xproto

winname = 'Geany'

def get_property_value(property_reply):
    assert isinstance(property_reply, xcb.xproto.GetPropertyReply)

    if property_reply.format == 8:
        if 0 in property_reply.value:
            ret = []
            s = ''
            for o in property_reply.value:
                if o == 0:
                    ret.append(s)
                    s = ''
                else:
                    s += chr(o)
        else:
            ret = str(property_reply.value.buf())

        return ret
    elif property_reply.format in (16, 32):
        return list(struct.unpack('I' * property_reply.value_len,
                                  property_reply.value.buf()))

    return None

def contains(needle, haystack):
    return haystack.lower().find(needle.lower()) > -1

c = xcb.connect()
root = c.get_setup().roots[0].root

_NET_CLIENT_LIST = c.core.InternAtom(True, len('_NET_CLIENT_LIST'),
                                     '_NET_CLIENT_LIST').reply().atom

raw_clientlist = c.core.GetProperty(False, root, _NET_CLIENT_LIST,
                                    xcb.xproto.GetPropertyType.Any,
                                    0, 2 ** 32 - 1).reply()
clientlist = get_property_value(raw_clientlist)

cookies = {}
for ident in clientlist:
    cookies[ident] = c.core.GetProperty(False, ident, xcb.xproto.Atom.WM_CLASS,
                                        xcb.xproto.GetPropertyType.Any,
                                        0, 2 ** 32 - 1)

for ident in cookies:
    winclass = get_property_value(cookies[ident].reply())
    if any([contains(winname, wncls) for wncls in winclass]):
        print ident, winclass

Note: The above searches on WM_CLASS. You may also want to search on _NET_WM_NAME (or maybe even WM_NAME, if you're dealing with some legacy applications).

Finally, if you're going to do any more heavy lifting, may I suggest you check out my xpyb-util git repository? The above could be condensed into this with xpyb-util:

import struct

import xcb
import xcb.xproto

import util
import icccm
import ewmh

winname = 'Geany'

def contains(needle, haystack):
    return haystack.lower().find(needle.lower()) > -1

c = xcb.connect()
root = c.get_setup().roots[0].root

clientlist = ewmh.get_client_list(c, root).reply()

cookies = {}
for ident in clientlist:
    cookies[ident] = icccm.get_wm_class(c, ident)

for ident in cookies:
    winclass = cookies[ident].reply()
    if any([contains(winname, wncls) for wncls in winclass]):
        print ident, winclass

My repo can be found here: https://github.com/BurntSushi/xpyb-util

(If you import the image module, you'll need PIL installed.)


Education is favorable to liberty. Freedom can exist only in a society of knowledge. Without learning, men are incapable of knowing their rights, and where learning is confined to a few people, liberty can be neither equal nor universal.

Tu ne cede malis sed contra audentior ito

Offline

#5 2011-02-14 05:38:33

hbekel
Member
Registered: 2008-10-04
Posts: 311

Re: How to get Window ID with python?

@BurntSushi: You're probably right about checking WM_STATE when using XQueryTree. I found that in practice i get the correct (toplevel) window id when I simply traverse the window tree top down and choose the first window that matches the desired WM_CLASS name property, but maybe i've just been lucky so far... So thanks for clarifying this.

Offline

#6 2011-02-14 13:14:58

rich_o
Member
Registered: 2008-07-28
Posts: 49

Re: How to get Window ID with python?

Thank you all,

glad to see it's possible without external programs. A special thank you to BurntSushi for the additional insight, never thought the matter is so complicated. But well, that's what modules and extra utils are for, right?

rich_o

Offline

Board footer

Powered by FluxBB