Mercurial > minori
annotate dep/animone/src/win/x11.cc @ 336:d260549151d6
dep/animone: fix undefined behavior, get correct length value
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 19 Jun 2024 06:32:25 -0400 |
parents | a4257370de16 |
children | a7d4e5107531 |
rev | line source |
---|---|
310
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
1 /* |
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
2 * win/x11.c: support for X11 using XCB |
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
3 * |
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
4 * some things might be wrong here due to |
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
5 * having to use recursive logic, but whatever |
a4257370de16
dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents:
301
diff
changeset
|
6 */ |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
7 #include "animone/win/x11.h" |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
8 #include "animone.h" |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
9 #include "animone/fd.h" /* GetProcessName() */ |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
10 #include "animone/win.h" |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
11 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
12 #include <xcb/res.h> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
13 #include <xcb/xcb.h> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
14 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
15 #include <climits> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
16 #include <cstdint> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
17 #include <cstring> |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
18 #include <cstdlib> |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
19 #include <set> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
20 #include <string> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
21 #include <memory> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
22 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
23 #include <chrono> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
24 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
25 #include <iostream> |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
26 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
27 static size_t str_nlen(const char* s, size_t len) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
28 size_t i = 0; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
29 for (; i < len && s[i]; i++) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
30 ; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
31 return i; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
32 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
33 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
34 namespace animone::internal::x11 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
35 |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
36 template<typename T> |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
37 struct XcbDestructor { |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
38 using pointer = T*; |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
39 void operator()(pointer t) const { std::free(t); }; |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
40 }; |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
41 |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
42 template<typename T> |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
43 using XcbPtr = std::unique_ptr<T, XcbDestructor<T>>; |
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
44 |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
45 static bool GetAllTopLevelWindowsEWMH(xcb_connection_t* connection, const std::vector<xcb_window_t>& roots, |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
46 std::set<xcb_window_t>& result) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
47 const xcb_atom_t Atom__NET_CLIENT_LIST = [connection] { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
48 static constexpr std::string_view name = "_NET_CLIENT_LIST"; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
49 xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
50 XcbPtr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
51 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
52 xcb_atom_t atom = reply->atom; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
53 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
54 return atom; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
55 }(); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
56 if (Atom__NET_CLIENT_LIST == XCB_ATOM_NONE) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
57 return false; // BTFO |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
58 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
59 bool success = false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
60 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
61 std::vector<xcb_get_property_cookie_t> cookies; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
62 cookies.reserve(roots.size()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
63 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
64 for (const auto& root : roots) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
65 cookies.push_back(::xcb_get_property(connection, 0, root, Atom__NET_CLIENT_LIST, XCB_ATOM_ANY, 0L, UINT_MAX)); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
66 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
67 for (const auto& cookie : cookies) { |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
68 XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
69 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
70 if (reply) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
71 xcb_window_t* value = reinterpret_cast<xcb_window_t*>(::xcb_get_property_value(reply.get())); |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
72 int len = ::xcb_get_property_value_length(reply.get()) / sizeof(xcb_window_t); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
73 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
74 for (size_t i = 0; i < len; i++) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
75 result.insert(value[i]); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
76 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
77 success |= true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
78 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
79 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
80 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
81 return success; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
82 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
83 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
84 /* This is called on every window. What this does is: |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
85 * 1. Gets the tree of children |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
86 * 2. Searches all children recursively for a WM_STATE property |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
87 * 3. If that failed... return the original window |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
88 */ |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
89 static bool WalkWindows(xcb_connection_t* connection, int depth, xcb_atom_t Atom_WM_STATE, const xcb_window_t* windows, |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
90 int windows_len, std::set<xcb_window_t>& result) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
91 /* The depth we should start returning at. */ |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
92 static constexpr int CUTOFF = 1; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
93 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
94 bool success = false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
95 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
96 std::vector<xcb_query_tree_cookie_t> cookies; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
97 cookies.reserve(windows_len); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
98 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
99 for (int i = 0; i < windows_len; i++) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
100 cookies.push_back(::xcb_query_tree(connection, windows[i])); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
101 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
102 for (const auto& cookie : cookies) { |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
103 XcbPtr<xcb_query_tree_reply_t> query_tree_reply(::xcb_query_tree_reply(connection, cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
104 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
105 xcb_window_t* tree_children = ::xcb_query_tree_children(query_tree_reply.get()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
106 int tree_children_len = ::xcb_query_tree_children_length(query_tree_reply.get()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
107 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
108 std::vector<xcb_get_property_cookie_t> state_property_cookies; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
109 state_property_cookies.reserve(tree_children_len); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
110 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
111 for (int i = 0; i < tree_children_len; i++) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
112 state_property_cookies.push_back( |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
113 ::xcb_get_property(connection, 0, tree_children[i], Atom_WM_STATE, Atom_WM_STATE, 0, 0)); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
114 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
115 for (int i = 0; i < tree_children_len; i++) { |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
116 XcbPtr<xcb_get_property_reply_t> get_property_reply(::xcb_get_property_reply(connection, state_property_cookies[i], NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
117 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
118 /* X11 is unfriendly here. what this means is "did the property exist?" */ |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
119 if (get_property_reply->format || get_property_reply->type || get_property_reply->length) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
120 result.insert(tree_children[i]); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
121 if (depth >= CUTOFF) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
122 return true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
123 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
124 success |= true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
125 continue; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
126 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
127 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
128 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
129 if (WalkWindows(connection, depth + 1, Atom_WM_STATE, tree_children, tree_children_len, result)) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
130 success |= true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
131 if (depth >= CUTOFF) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
132 return true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
133 continue; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
134 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
135 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
136 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
137 return success; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
138 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
139 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
140 static bool GetAllTopLevelWindowsICCCM(xcb_connection_t* connection, const std::vector<xcb_window_t>& roots, |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
141 std::set<xcb_window_t>& result) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
142 bool success = false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
143 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
144 xcb_atom_t Atom_WM_STATE = [connection] { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
145 static constexpr std::string_view name = "WM_STATE"; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
146 xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
147 XcbPtr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
148 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
149 xcb_atom_t atom = reply->atom; |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
150 |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
151 return atom; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
152 }(); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
153 if (Atom_WM_STATE == XCB_ATOM_NONE) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
154 return success; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
155 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
156 std::vector<xcb_query_tree_cookie_t> cookies; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
157 cookies.reserve(roots.size()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
158 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
159 for (const auto& root : roots) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
160 cookies.push_back(::xcb_query_tree(connection, root)); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
161 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
162 for (const auto& cookie : cookies) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
163 success |= WalkWindows(connection, 0, Atom_WM_STATE, roots.data(), roots.size(), result); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
164 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
165 return success; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
166 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
167 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
168 bool EnumerateWindows(window_proc_t window_proc) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
169 if (!window_proc) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
170 return false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
171 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
172 xcb_connection_t* connection = ::xcb_connect(NULL, NULL); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
173 if (xcb_connection_has_error(connection)) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
174 return false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
175 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
176 std::set<xcb_window_t> windows; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
177 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
178 std::vector<xcb_window_t> roots; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
179 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
180 xcb_screen_iterator_t iter = ::xcb_setup_roots_iterator(::xcb_get_setup(connection)); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
181 for (; iter.rem; ::xcb_screen_next(&iter)) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
182 roots.push_back(iter.data->root); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
183 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
184 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
185 if (!GetAllTopLevelWindowsEWMH(connection, roots, windows)) |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
186 GetAllTopLevelWindowsICCCM(connection, roots, windows); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
187 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
188 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
189 struct WindowCookies { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
190 xcb_window_t window; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
191 xcb_get_property_cookie_t class_property_cookie; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
192 xcb_get_property_cookie_t name_property_cookie; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
193 xcb_res_query_client_ids_cookie_t pid_property_cookie; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
194 }; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
195 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
196 std::vector<WindowCookies> window_cookies; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
197 window_cookies.reserve(windows.size()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
198 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
199 for (const auto& window : windows) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
200 xcb_res_client_id_spec_t spec = {.client = window, .mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID}; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
201 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
202 WindowCookies window_cookie = { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
203 window, ::xcb_get_property(connection, 0, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0L, 2048L), |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
204 ::xcb_get_property(connection, 0, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0L, UINT_MAX), |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
205 ::xcb_res_query_client_ids(connection, 1, &spec)}; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
206 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
207 window_cookies.push_back(window_cookie); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
208 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
209 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
210 for (const auto& window_cookie : window_cookies) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
211 Window win = {0}; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
212 win.id = window_cookie.window; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
213 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
214 /* Class name */ |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
215 XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, window_cookie.class_property_cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
216 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
217 if (reply && reply->format == 8) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
218 const char* data = reinterpret_cast<const char*>(::xcb_get_property_value(reply.get())); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
219 const int data_len = ::xcb_get_property_value_length(reply.get()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
220 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
221 int instance_len = str_nlen(data, data_len); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
222 const char* class_name = data + instance_len + 1; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
223 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
224 win.class_name = std::string(class_name, str_nlen(class_name, data_len - (instance_len + 1))); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
225 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
226 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
227 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
228 /* Title text */ |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
229 XcbPtr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, window_cookie.name_property_cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
230 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
231 if (reply) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
232 const char* data = reinterpret_cast<const char*>(::xcb_get_property_value(reply.get())); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
233 int len = ::xcb_get_property_value_length(reply.get()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
234 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
235 win.text = std::string(data, len); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
236 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
237 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
238 Process proc = {0}; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
239 { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
240 /* PID */ |
336
d260549151d6
dep/animone: fix undefined behavior, get correct length value
Paper <paper@paper.us.eu.org>
parents:
310
diff
changeset
|
241 XcbPtr<xcb_res_query_client_ids_reply_t> reply(::xcb_res_query_client_ids_reply(connection, window_cookie.pid_property_cookie, NULL)); |
301
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
242 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
243 if (reply) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
244 xcb_res_client_id_value_iterator_t it = ::xcb_res_query_client_ids_ids_iterator(reply.get()); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
245 for (; it.rem; ::xcb_res_client_id_value_next(&it)) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
246 if (it.data->spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
247 proc.pid = *::xcb_res_client_id_value_value(it.data); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
248 GetProcessName(proc.pid, proc.name); /* fill this in if we can */ |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
249 break; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
250 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
251 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
252 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
253 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
254 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
255 if (!window_proc(proc, win)) { |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
256 ::xcb_disconnect(connection); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
257 return false; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
258 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
259 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
260 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
261 ::xcb_disconnect(connection); |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
262 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
263 return true; |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
264 } |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
265 |
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
266 } // namespace animone::internal::x11 |