3 local INDENT_PER_LEVEL
=2
10 function internatom(this
, name
)
11 this
[name
] = dpy
:intern_atom_reply(dpy
:intern_atom(false, string.len(name
), name
)).atom
16 io
.output():write(string.format(...))
19 function DumpTree(id
, indent
)
20 -- Show the information for this window
21 local win
= window
[id
]
24 printf("%s0x%08X ", string.rep(" ", indent
), id
);
26 printf("%s(0x%08X)", string.rep(" ", indent
), id
);
30 printf(" %d: %d,%d [%dx%d]", geom
.depth
, geom
.x
, geom
.y
, geom
.width
, geom
.height
)
32 printf(" %s\n", win
.name
or "");
34 -- Recursively show the information for the rest of the tree
35 for k
, v
in ipairs(win
.children
) do
36 DumpTree(v
, indent
+ INDENT_PER_LEVEL
)
41 function QueueInternAtom(name
)
42 local cookie
= dpy
:intern_atom(false, string.len(name
), name
)
43 table.insert(queue
, function()
44 atom
[name
] = dpy
:intern_atom_reply(cookie
).atom
48 function QueueWindowName(id
)
49 local cookie
= dpy
:get_property(false, id
, atom
.WM_NAME
, dpy
.GET_PROPERTY_TYPE
.ANY
, 0, 80)
50 table.insert(queue
, function()
51 local prop
= dpy
:get_property_reply(cookie
)
53 window
[id
].name
= string.char(unpack(prop
.value
))
58 function QueueWindowGeometry(id
)
59 local cookie
= dpy
:get_geometry(id
)
60 table.insert(queue
, function()
61 window
[id
].geom
= dpy
:get_geometry_reply(cookie
)
65 function QueueWindowMapped(id
)
66 local cookie
= dpy
:get_window_attributes(id
)
67 table.insert(queue
, function()
68 local xwa
= dpy
:get_window_attributes_reply(cookie
)
69 window
[id
].mapped
= (xwa
.map_state
== dpy
.MAP_STATE
.VIEWABLE
)
73 function QueueWindowChildren(id
)
74 local cookie
= dpy
:query_tree(id
)
75 table.insert(queue
, function()
76 local tree
= dpy
:query_tree_reply(cookie
)
77 window
[id
].children
= tree
.children
79 -- For each window, query the children first
80 -- (since that's the one that'll cause recursive
81 -- queries), and then query incidental per-window data
82 -- (hopefully overlapping with the child queries)
84 for k
, v
in ipairs(tree
.children
) do
86 QueueWindowChildren(v
)
89 for k
, v
in ipairs(tree
.children
) do
91 QueueWindowGeometry(v
)
97 function ProcessQueue()
99 while (#queue
>= next) do
106 setmetatable(atom
, { __index
= internatom
})
110 dpy
, screen
= lxcb
.connect("")
113 print("Error: Cannot open default display.")
118 root
= tonumber(arg
[1])
120 print("Usage: DumpTree [starting window]")
124 root
= dpy
:get_setup().roots
[screen
+1].root
127 window
[root
] = { mapped
= true }
128 QueueWindowChildren(root
)
129 QueueInternAtom('WM_NAME')
130 QueueWindowGeometry(root
)