Mercurial > minori
annotate dep/animia/src/win/x11.cc @ 215:031a257ee019
dep/animia: fd/proc: use std::filesystem, etc. changes
i.e. don't use std::stoi so we don't get exceptions...
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Sun, 07 Jan 2024 11:44:40 -0500 |
| parents | 8d35061e7505 |
| children | 8ccf0302afb1 |
| 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 |
|
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 | 35 unsigned char* data; |
| 166 | 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 | 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 | 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 | 44 ::XFree(data); |
| 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 | 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 | 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 | 86 &type, &format, &num_of_items, &leftover_bytes, &data); |
| 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 | 92 ::XFree(data); |
| 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 | 99 return true; |
| 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 | 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 | 116 int count; |
|
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
117 |
| 157 | 118 int status = ::XmbTextPropertyToTextList(display, &text, &list, &count); |
| 166 | 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 | 135 return false; |
| 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 | 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 | 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 | 200 |
| 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 | 204 |
| 205 if (num_children < 1) { | |
| 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 | 215 } |
| 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 | 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 | 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 | 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 | 234 } |
| 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 | 244 return true; |
| 245 } | |
| 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 | 252 if (!display) |
| 253 return false; | |
| 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 | 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 | 263 { |
| 264 ::XClassHint* hint = ::XAllocClassHint(); | |
| 265 if (::XGetClassHint(display, window, hint)) { | |
| 266 win.class_name = hint->res_class; | |
| 267 ::XFree(hint); | |
| 268 } | |
| 269 } | |
| 166 | 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 } |
