56

Anyone got an idea how to get from an Xserver the list of all open windows?

codingbadger
  • 42,678
  • 13
  • 95
  • 110
kender
  • 85,663
  • 26
  • 103
  • 145

3 Answers3

130

From the CLI you can use

xwininfo -tree -root

If you need to do this within your own code then you need to use the XQueryTree function from the Xlib library.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
21

If your window manager implements EWMH specification, you can also take a look at the _NET_CLIENT_LIST value of the root window. This is set by most modern window managers:

xprop -root|grep ^_NET_CLIENT_LIST

That value can easily be obtained programmatically, see your Xlib documentation!

L29Ah
  • 268
  • 1
  • 16
Marten
  • 1,136
  • 1
  • 8
  • 15
  • 2
    I like this; it is consistently faster than xwininfo or xdotool (though xdotool can easily exclude visible windows). – Paul Brannan Apr 12 '17 at 16:02
14

Building off of Marten's answer, (assuming your window manager supports Extended Window Manager Hints) you can feed that list of window ids back into xprop to get the _NET_WM_NAME property:

$ xprop -root _NET_CLIENT_LIST |
    pcregrep -o1 '# (.*)' |
    sed 's/, /\n/g' |
    xargs -I{} -n1 xprop -id {} _NET_WM_NAME

But at the command line, it would just be easier to use wmctrl:

$ wmctrl -l

Programmatically, with python-xlib, you can do the same with:

#!/usr/bin/env python
from Xlib.display import Display
from Xlib.X import AnyPropertyType

display = Display()
root = display.screen().root

_NET_CLIENT_LIST = display.get_atom('_NET_CLIENT_LIST')
_NET_WM_NAME = display.get_atom('_NET_WM_NAME')

client_list = root.get_full_property(
    _NET_CLIENT_LIST,
    property_type=AnyPropertyType,
).value

for window_id in client_list:
    window = display.create_resource_object('window', window_id)
    window_name = window.get_full_property(
        _NET_WM_NAME,
        property_type=AnyPropertyType,
    ).value
    print(window_name)

Or, better yet, using the EWMH library:

#!/usr/bin/env python
from ewmh import EWMH

window_manager_manager = EWMH()
client_list = window_manager_manager.getClientList()

for window in client_list:
    print(window_manager_manager.getWmName(window))
  • I like the ease of **EWMH** module however I'm abbreviating `window_manager_manager` object name to `wm`. Also I received an error on **xlib** example line `property_type=AnyPropertyType` that readsi: ***TypeError: get_full_property() got an unexpected keyword argument 'property_type'*** – WinEunuuchs2Unix Jun 22 '21 at 23:44
  • 1
    @WinEunuuchs2Unix why I called it that eludes me now, lol. And it's weird that you're getting that error. I just pulled out my Linux laptop to test the script and it ran without an issue for me, but perhaps we're using different versions of `python-xlib`? In any case, if you just remove the `property_type=` part, it should work as a positional argument. – Christian Reall-Fluharty Jun 23 '21 at 02:25