annotate dep/animia/src/win/x11.cc @ 233:0a5b6a088886

dep/animia: fix proc readlink
author Paper <mrpapersonic@gmail.com>
date Mon, 15 Jan 2024 08:10:58 -0500
parents 8d35061e7505
children 8ccf0302afb1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
1 #include "animia/win/x11.h"
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
2 #include "animia/win.h"
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
3 #include "animia.h"
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
4
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
5 #include <X11/Xlib.h>
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
6 #include <X11/Xutil.h>
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
7 #include <X11/Xatom.h> // XA_*
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
8 #ifdef HAVE_XRES
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
9 #include <X11/extensions/XRes.h>
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
10 #endif
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 157
diff changeset
11
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
12 #include <cstdint>
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
13 #include <string>
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 157
diff changeset
14 #include <set>
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
15
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
16 namespace animia::internal::x11 {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
17
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
18 /* specify that these are X types. */
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
19 typedef ::Window XWindow;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
20 typedef ::Display XDisplay;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
21 typedef ::Atom XAtom;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
22
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
23 /* should return UTF8_STRING or STRING. this means we are not
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
24 * *guaranteed* a UTF-8 string back.
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
25 */
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
26 static bool GetWindowPropertyAsString(XDisplay* display, XWindow window, XAtom atom, std::string& result) {
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
27 if (atom == None)
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
28 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
29
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
30 XAtom Atom_UTF8_STRING = ::XInternAtom(display, "UTF8_STRING", False);
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
31
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
32 int format;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
33 unsigned long leftover_bytes, num_of_items;
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
34 XAtom type;
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
35 unsigned char* data;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
36
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
37 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, AnyPropertyType,
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
38 &type, &format, &num_of_items, &leftover_bytes, &data);
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
39 if (status != Success || !(type == Atom_UTF8_STRING || type == XA_STRING) || !num_of_items)
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
40 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
41
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
42 result = std::string((char*)data, num_of_items);
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
43
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
44 ::XFree(data);
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
45
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
46 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
47 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
48
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
49 /* this should return CARDINAL, a 32-bit integer */
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
50 static bool GetWindowPID(XDisplay* display, XWindow window, pid_t& result) {
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
51 #ifdef HAVE_XRES
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
52 {
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
53 long num_ids;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
54 XResClientIdValue *client_ids;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
55 XResClientIdSpec spec = {
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
56 .client = window,
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
57 .mask = XRES_CLIENT_ID_PID_MASK
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
58 };
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
59
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
60 ::XResQueryClientIds(display, 1, &spec, &num_ids, &client_ids);
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
61
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
62 for (long i = 0; i < num_ids; i++) {
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
63 if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) {
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
64 result = ::XResGetClientPid(&client_ids[i]);
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
65 ::XResClientIdsDestroy(num_ids, client_ids);
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
66 return true;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
67 }
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
68 }
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
69
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
70 ::XResClientIdsDestroy(num_ids, client_ids);
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
71
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
72 return false;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
73 }
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
74 #endif
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
75
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
76 XAtom Atom__NET_WM_PID = ::XInternAtom(display, "_NET_WM_PID", True);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
77 if (Atom__NET_WM_PID == None)
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
78 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
79
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
80 int format;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
81 unsigned long leftover_bytes, num_of_items;
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
82 XAtom type;
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
83 unsigned char* data;
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
84
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
85 int status = ::XGetWindowProperty(display, window, Atom__NET_WM_PID, 0L, (~0L), False, XA_CARDINAL,
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
86 &type, &format, &num_of_items, &leftover_bytes, &data);
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
87 if (status != Success || type != XA_CARDINAL || num_of_items < 1)
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
88 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
89
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
90 result = static_cast<pid_t>(*reinterpret_cast<uint32_t*>(data));
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
91
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
92 ::XFree(data);
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
93
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
94 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
95 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
96
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
97 static bool FetchName(XDisplay* display, XWindow window, std::string& result) {
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
98 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", True), result))
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
99 return true;
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
100
214
8d35061e7505 dep/animia: win/x11: simplify getting strings
Paper <mrpapersonic@gmail.com>
parents: 213
diff changeset
101 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "WM_NAME", True), result))
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
102 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
103
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
104 /* Fallback to XGetWMName() */
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
105 XTextProperty text;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
106
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
107 {
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
108 int status = ::XGetWMName(display, window, &text);
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
109 if (!status || !text.value || !text.nitems)
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
110 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
111 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
112
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
113 char** list;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
114
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
115 {
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
116 int count;
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
117
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
118 int status = ::XmbTextPropertyToTextList(display, &text, &list, &count);
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
119 if (status != Success || !count || !*list)
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
120 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
121 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
122
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
123 ::XFree(text.value);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
124
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
125 result = *list;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
126
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
127 ::XFreeStringList(list);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
128
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
129 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
130 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
131
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
132 static bool GetAllTopLevelWindowsEWMH(XDisplay* display, XWindow root, std::set<XWindow>& result) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
133 XAtom Atom__NET_CLIENT_LIST = XInternAtom(display, "_NET_CLIENT_LIST", True);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
134 if (Atom__NET_CLIENT_LIST == None)
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
135 return false;
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
136
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
137 XAtom actual_type;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
138 int format;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
139 unsigned long num_of_items, bytes_after;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
140 unsigned char* data = nullptr;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
141
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
142 {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
143 int status = ::XGetWindowProperty(
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
144 display, root, Atom__NET_CLIENT_LIST,
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
145 0L, (~0L), false, AnyPropertyType, &actual_type,
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
146 &format, &num_of_items, &bytes_after, &data
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
147 );
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
148
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
149 if (status < Success || !num_of_items)
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
150 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
151 }
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
152
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
153 XWindow* arr = (XWindow*)data;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
154
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
155 for (uint32_t i = 0; i < num_of_items; i++)
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
156 result.insert(arr[i]);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
157
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
158 ::XFree(data);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
159
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
160 return true;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
161 }
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
162
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
163 static bool GetAllTopLevelWindows(XDisplay* display, XWindow root, std::set<XWindow>& result) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
164 // EWMH. Takes about 15 ms on a fairly good PC.
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
165 if (GetAllTopLevelWindowsEWMH(display, root, result))
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
166 return true;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
167
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
168 // Fallback to ICCCM. Takes about the same time on a good PC.
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
169 XAtom Atom_WM_STATE = XInternAtom(display, "WM_STATE", True);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
170 if (Atom_WM_STATE == None)
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
171 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
172
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
173 auto window_has_wm_state = [&](XWindow window) -> bool {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
174 int format;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
175 Atom actual_type;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
176 unsigned long num_of_items, bytes_after;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
177 unsigned char* data = nullptr;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
178
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
179 int status = ::XGetWindowProperty(
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
180 display, window, Atom_WM_STATE,
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
181 0L, (~0L), false, AnyPropertyType, &actual_type,
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
182 &format, &num_of_items, &bytes_after, &data
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
183 );
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
184
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
185 ::XFree(data);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
186
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
187 return !(actual_type == None && !format && !bytes_after);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
188 };
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
189
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
190 std::function<bool(XWindow, XWindow&)> immediate_child_get_toplevel = [&](XWindow window, XWindow& result) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
191 result = window;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
192 if (window_has_wm_state(window))
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
193 return true;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
194
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
195 unsigned int num_children = 0;
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
196 XWindow* children_arr = nullptr;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
197
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
198 XWindow root_return;
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
199 XWindow parent_return;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
200
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
201 int status = ::XQueryTree(display, window, &root_return, &parent_return, &children_arr, &num_children);
167
31735c8592bc dep/animia: make x11 window walking actually work
paper@DavesDouble.local
parents: 166
diff changeset
202 if (!status || !children_arr)
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
203 return false;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
204
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
205 if (num_children < 1) {
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
206 ::XFree(children_arr);
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
207 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
208 }
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
209
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
210 for (unsigned int i = 0; i < num_children; i++) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
211 if (immediate_child_get_toplevel(children_arr[i], result)) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
212 ::XFree(children_arr);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
213 return true;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
214 }
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
215 }
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
216
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
217 ::XFree(children_arr);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
218 return false;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
219 };
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
220
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
221 unsigned int num_children = 0;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
222 XWindow* children_arr = nullptr;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
223
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
224 XWindow root_return;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
225 XWindow parent_return;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
226
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
227 int status = ::XQueryTree(display, root, &root_return, &parent_return, &children_arr, &num_children);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
228 if (!status || !children_arr)
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
229 return false; // how
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
230
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
231 if (num_children < 1) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
232 ::XFree(children_arr);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
233 return false;
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
234 }
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
235
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
236 for (unsigned int i = 0; i < num_children; i++) {
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
237 XWindow res;
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
238 if (immediate_child_get_toplevel(children_arr[i], res))
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
239 result.insert(res);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
240 }
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
241
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
242 ::XFree(children_arr);
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
243
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
244 return true;
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
245 }
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
246
198
bc1ae1810855 dep/animia: switch from using classes to global functions
Paper <mrpapersonic@gmail.com>
parents: 191
diff changeset
247 bool EnumerateWindows(window_proc_t window_proc) {
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 157
diff changeset
248 if (!window_proc)
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 157
diff changeset
249 return false;
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
250
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
251 XDisplay* display = ::XOpenDisplay(nullptr);
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
252 if (!display)
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
253 return false;
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
254
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
255 XWindow root = ::XDefaultRootWindow(display);
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
256
199
9f3534f6b8c4 dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents: 198
diff changeset
257 std::set<XWindow> windows;
213
58e81b42a0d6 dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents: 199
diff changeset
258 GetAllTopLevelWindows(display, root, windows);
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
259
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
260 for (const auto& window : windows) {
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
261 Window win;
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 157
diff changeset
262 win.id = window;
157
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
263 {
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
264 ::XClassHint* hint = ::XAllocClassHint();
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
265 if (::XGetClassHint(display, window, hint)) {
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
266 win.class_name = hint->res_class;
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
267 ::XFree(hint);
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
268 }
18c8eb5d1edc x11: make it work
Paper <mrpapersonic@gmail.com>
parents: 156
diff changeset
269 }
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 158
diff changeset
270 FetchName(display, window, win.text);
156
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
271
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
272 Process proc;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
273 GetWindowPID(display, window, proc.pid);
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
274
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
275 if (!window_proc(proc, win))
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
276 return false;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
277 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
278
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
279 return true;
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
280 }
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
281
cdf79282d647 dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
282 }