Mercurial > minori
annotate dep/animia/src/win/x11.cc @ 213:58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
completely different approach. oops!
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Sun, 07 Jan 2024 11:11:27 -0500 |
| parents | 9f3534f6b8c4 |
| children | 8d35061e7505 |
| rev | line source |
|---|---|
| 157 | 1 #include "animia/win/x11.h" |
| 2 #include "animia/win.h" | |
| 3 #include "animia.h" | |
| 4 | |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 #include <X11/Xlib.h> |
| 157 | 6 #include <X11/Xutil.h> |
| 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 | 12 #include <cstdint> |
| 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 |
| 157 | 23 /* should return UTF8_STRING or STRING */ |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
24 static bool GetWindowPropertyAsString(XDisplay* display, XWindow window, XAtom atom, std::string& result, XAtom reqtype = AnyPropertyType) { |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
25 if (atom == None || reqtype == None) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
26 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
27 |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
28 int format; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 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
|
30 XAtom type; |
| 157 | 31 unsigned char* data; |
| 166 | 32 |
| 33 int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, | |
| 34 &type, &format, &num_of_items, &leftover_bytes, &data); | |
| 35 if (status != Success || !(reqtype == AnyPropertyType || type == reqtype) || !num_of_items) | |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 return false; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
37 |
| 157 | 38 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
|
39 |
| 166 | 40 ::XFree(data); |
| 41 | |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
42 return true; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
43 } |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
44 |
| 157 | 45 /* 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
|
46 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
|
47 #ifdef HAVE_XRES |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
48 { |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
49 long num_ids; |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
50 XResClientIdValue *client_ids; |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
51 XResClientIdSpec spec = { |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
52 .client = window, |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
53 .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
|
54 }; |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
55 |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
56 ::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
|
57 |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
58 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
|
59 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
|
60 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
|
61 ::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
|
62 return true; |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
63 } |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
64 } |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
65 |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
66 ::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
|
67 |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
68 return false; |
|
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 #endif |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
71 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
72 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
|
73 if (Atom__NET_WM_PID == None) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
74 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
75 |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 int format; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
77 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
|
78 XAtom type; |
| 157 | 79 unsigned char* data; |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
80 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
81 int status = ::XGetWindowProperty(display, window, Atom__NET_WM_PID, 0L, (~0L), False, XA_CARDINAL, |
| 166 | 82 &type, &format, &num_of_items, &leftover_bytes, &data); |
| 83 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
|
84 return false; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
85 |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
86 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
|
87 |
| 166 | 88 ::XFree(data); |
| 89 | |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
90 return true; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
91 } |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
92 |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
93 static bool FetchName(XDisplay* display, XWindow window, std::string& result) { |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
94 /* TODO: Check if XInternAtom created None or not... */ |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
95 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", True), |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
96 result, ::XInternAtom(display, "UTF8_STRING", True))) |
| 166 | 97 return true; |
| 98 | |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
99 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "WM_NAME", True), |
| 166 | 100 result, XA_STRING)) |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
101 return true; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
102 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
103 /* Fallback to XGetWMName() */ |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
104 XTextProperty text; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
105 |
|
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 int status = ::XGetWMName(display, window, &text); |
| 157 | 108 if (!status || !text.value || !text.nitems) |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
109 return false; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
110 } |
|
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 char** list; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
113 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
114 { |
| 157 | 115 int count; |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
116 |
| 157 | 117 int status = ::XmbTextPropertyToTextList(display, &text, &list, &count); |
| 166 | 118 if (status != Success || !count || !*list) |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
119 return false; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
120 } |
|
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 ::XFree(text.value); |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
123 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
124 result = *list; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
125 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
126 ::XFreeStringList(list); |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
127 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
128 return true; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
129 } |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
130 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
131 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
|
132 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
|
133 if (Atom__NET_CLIENT_LIST == None) |
| 166 | 134 return false; |
| 135 | |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
136 XAtom actual_type; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
137 int format; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
138 unsigned long num_of_items, bytes_after; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
139 unsigned char* data = nullptr; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
140 |
|
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 int status = ::XGetWindowProperty( |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
143 display, root, Atom__NET_CLIENT_LIST, |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
144 0L, (~0L), false, AnyPropertyType, &actual_type, |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
145 &format, &num_of_items, &bytes_after, &data |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
146 ); |
|
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 if (status < Success || !num_of_items) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
149 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
150 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
151 if (format != 32) { |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
152 ::XFree(data); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
153 return false; |
|
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 } |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
156 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
157 XWindow* arr = (XWindow*)data; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
158 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
159 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
|
160 result.insert(arr[i]); |
|
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 ::XFree(data); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
163 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
164 return true; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
165 } |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
166 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
167 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
|
168 // 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
|
169 if (GetAllTopLevelWindowsEWMH(display, root, result)) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
170 return true; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
171 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
172 // 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
|
173 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
|
174 if (Atom_WM_STATE == None) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
175 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
176 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
177 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
|
178 int format; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
179 Atom actual_type; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
180 unsigned long num_of_items, bytes_after; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
181 unsigned char* data = nullptr; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
182 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
183 int status = ::XGetWindowProperty( |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
184 display, window, Atom_WM_STATE, |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
185 0L, (~0L), false, AnyPropertyType, &actual_type, |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
186 &format, &num_of_items, &bytes_after, &data |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
187 ); |
|
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 ::XFree(data); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
190 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
191 return !(actual_type == None && !format && !bytes_after); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
192 }; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
193 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
194 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
|
195 result = window; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
196 if (window_has_wm_state(window)) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
197 return true; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
198 |
| 166 | 199 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
|
200 XWindow* children_arr = nullptr; |
| 166 | 201 |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
202 XWindow root_return; |
|
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
203 XWindow parent_return; |
| 166 | 204 |
| 205 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
|
206 if (!status || !children_arr) |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
207 return false; |
| 166 | 208 |
| 209 if (num_children < 1) { | |
| 210 ::XFree(children_arr); | |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
211 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
212 } |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
213 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
214 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
|
215 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
|
216 ::XFree(children_arr); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
217 return true; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
218 } |
| 166 | 219 } |
| 220 | |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
221 ::XFree(children_arr); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
222 return false; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
223 }; |
| 166 | 224 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
225 unsigned int num_children = 0; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
226 XWindow* children_arr = nullptr; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
227 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
228 XWindow root_return; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
229 XWindow parent_return; |
| 166 | 230 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
231 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
|
232 if (!status || !children_arr) |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
233 return false; // how |
| 166 | 234 |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
235 if (num_children < 1) { |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
236 ::XFree(children_arr); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
237 return false; |
| 166 | 238 } |
| 239 | |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
240 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
|
241 XWindow res; |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
242 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
|
243 result.insert(res); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
244 } |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
245 |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
246 ::XFree(children_arr); |
|
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
247 |
| 166 | 248 return true; |
| 249 } | |
| 250 | |
|
198
bc1ae1810855
dep/animia: switch from using classes to global functions
Paper <mrpapersonic@gmail.com>
parents:
191
diff
changeset
|
251 bool EnumerateWindows(window_proc_t window_proc) { |
|
158
80d6b28eb29f
dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents:
157
diff
changeset
|
252 if (!window_proc) |
|
80d6b28eb29f
dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents:
157
diff
changeset
|
253 return false; |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
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 XDisplay* display = ::XOpenDisplay(nullptr); |
| 166 | 256 if (!display) |
| 257 return false; | |
| 258 | |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
259 XWindow root = ::XDefaultRootWindow(display); |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
260 |
|
199
9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
Paper <mrpapersonic@gmail.com>
parents:
198
diff
changeset
|
261 std::set<XWindow> windows; |
|
213
58e81b42a0d6
dep/animia: win/x11: find toplevels WAY faster
Paper <mrpapersonic@gmail.com>
parents:
199
diff
changeset
|
262 GetAllTopLevelWindows(display, root, windows); |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
263 |
| 166 | 264 for (const auto& window : windows) { |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
265 Window win; |
|
158
80d6b28eb29f
dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents:
157
diff
changeset
|
266 win.id = window; |
| 157 | 267 { |
| 268 ::XClassHint* hint = ::XAllocClassHint(); | |
| 269 if (::XGetClassHint(display, window, hint)) { | |
| 270 win.class_name = hint->res_class; | |
| 271 ::XFree(hint); | |
| 272 } | |
| 273 } | |
| 166 | 274 FetchName(display, window, win.text); |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
275 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
276 Process proc; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
277 GetWindowPID(display, window, proc.pid); |
|
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 if (!window_proc(proc, win)) |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
280 return false; |
|
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 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
283 return true; |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
284 } |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
285 |
|
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
286 } |
