Mercurial > minori
annotate dep/animone/src/win/x11.cc @ 327:b5d6c27c308f
anime: refactor Anime::SeriesSeason to Season class
ToLocalString has also been altered to take in both season
and year because lots of locales actually treat formatting
seasons differently! most notably is Russian which adds a
suffix at the end to notate seasons(??)
| author | Paper <paper@paper.us.eu.org> |
|---|---|
| date | Thu, 13 Jun 2024 01:49:18 -0400 |
| parents | a4257370de16 |
| children | d260549151d6 |
| 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> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
18 #include <set> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
19 #include <string> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
20 #include <memory> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
21 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
22 #include <chrono> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
23 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
24 #include <iostream> |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
25 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
26 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
|
27 size_t i = 0; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
28 for (; i < len && s[i]; i++) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
29 ; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
30 return i; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
31 } |
|
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 namespace animone::internal::x11 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
34 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
35 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
|
36 std::set<xcb_window_t>& result) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
37 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
|
38 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
|
39 xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
40 std::unique_ptr<xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(connection, cookie, NULL)); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
41 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
42 xcb_atom_t atom = reply->atom; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
43 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
44 return atom; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
45 }(); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
46 if (Atom__NET_CLIENT_LIST == XCB_ATOM_NONE) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
47 return false; // BTFO |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
48 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
49 bool success = false; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
50 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
51 std::vector<xcb_get_property_cookie_t> cookies; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
52 cookies.reserve(roots.size()); |
|
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 for (const auto& root : roots) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
55 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
|
56 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
57 for (const auto& cookie : cookies) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
58 std::unique_ptr<xcb_get_property_reply_t> reply(::xcb_get_property_reply(connection, cookie, NULL)); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
59 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
60 if (reply) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
61 xcb_window_t* value = reinterpret_cast<xcb_window_t*>(::xcb_get_property_value(reply.get())); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
62 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
|
63 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
64 for (size_t i = 0; i < len; i++) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
65 result.insert(value[i]); |
|
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 success |= true; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
68 } |
|
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 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
71 return success; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
72 } |
|
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 /* 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
|
75 * 1. Gets the tree of children |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
76 * 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
|
77 * 3. If that failed... return the original window |
|
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 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
|
80 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
|
81 /* The depth we should start returning at. */ |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
82 static constexpr int CUTOFF = 1; |
|
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 bool success = false; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
85 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
86 std::vector<xcb_query_tree_cookie_t> cookies; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
87 cookies.reserve(windows_len); |
|
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 for (int i = 0; i < windows_len; i++) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
90 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
|
91 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
92 for (const auto& cookie : cookies) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
93 std::unique_ptr<xcb_query_tree_reply_t> query_tree_reply(::xcb_query_tree_reply(connection, cookie, NULL)); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
94 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
95 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
|
96 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
|
97 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
98 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
|
99 state_property_cookies.reserve(tree_children_len); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
100 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
101 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
|
102 state_property_cookies.push_back( |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
103 ::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
|
104 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
105 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
|
106 std::unique_ptr<xcb_get_property_reply_t> get_property_reply( |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
107 ::xcb_get_property_reply(connection, state_property_cookies[i], NULL)); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
108 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
109 /* 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
|
110 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
|
111 result.insert(tree_children[i]); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
112 if (depth >= CUTOFF) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
113 return true; |
|
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 success |= true; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
116 continue; |
|
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 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
119 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
120 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
|
121 success |= true; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
122 if (depth >= CUTOFF) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
123 return true; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
124 continue; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
125 } |
|
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 return success; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
129 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
130 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
131 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
|
132 std::set<xcb_window_t>& result) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
133 bool success = false; |
|
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 xcb_atom_t Atom_WM_STATE = [connection] { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
136 static constexpr std::string_view name = "WM_STATE"; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
137 xcb_intern_atom_cookie_t cookie = ::xcb_intern_atom(connection, true, name.size(), name.data()); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
138 xcb_intern_atom_reply_t* reply = ::xcb_intern_atom_reply(connection, cookie, NULL); |
|
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 xcb_atom_t atom = reply->atom; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
141 free(reply); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
142 return atom; |
|
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 if (Atom_WM_STATE == XCB_ATOM_NONE) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
145 return success; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
146 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
147 std::vector<xcb_query_tree_cookie_t> cookies; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
148 cookies.reserve(roots.size()); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
149 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
150 for (const auto& root : roots) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
151 cookies.push_back(::xcb_query_tree(connection, root)); |
|
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 for (const auto& cookie : cookies) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
154 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
|
155 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
156 return success; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
157 } |
|
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 bool EnumerateWindows(window_proc_t window_proc) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
160 if (!window_proc) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
161 return false; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
162 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
163 xcb_connection_t* connection = ::xcb_connect(NULL, NULL); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
164 if (xcb_connection_has_error(connection)) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
165 return false; |
|
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 std::set<xcb_window_t> windows; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
168 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
169 std::vector<xcb_window_t> roots; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
170 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
171 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
|
172 for (; iter.rem; ::xcb_screen_next(&iter)) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
173 roots.push_back(iter.data->root); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
174 } |
|
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 if (!GetAllTopLevelWindowsEWMH(connection, roots, windows)) |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
177 GetAllTopLevelWindowsICCCM(connection, roots, windows); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
178 } |
|
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 struct WindowCookies { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
181 xcb_window_t window; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
182 xcb_get_property_cookie_t class_property_cookie; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
183 xcb_get_property_cookie_t name_property_cookie; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
184 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
|
185 }; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
186 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
187 std::vector<WindowCookies> window_cookies; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
188 window_cookies.reserve(windows.size()); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
189 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
190 for (const auto& window : windows) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
191 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
|
192 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
193 WindowCookies window_cookie = { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
194 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
|
195 ::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
|
196 ::xcb_res_query_client_ids(connection, 1, &spec)}; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
197 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
198 window_cookies.push_back(window_cookie); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
199 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
200 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
201 for (const auto& window_cookie : window_cookies) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
202 Window win = {0}; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
203 win.id = window_cookie.window; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
204 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
205 /* Class name */ |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
206 std::unique_ptr<xcb_get_property_reply_t> reply( |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
207 ::xcb_get_property_reply(connection, window_cookie.class_property_cookie, NULL)); |
|
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 if (reply && reply->format == 8) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
210 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
|
211 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
|
212 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
213 int instance_len = str_nlen(data, data_len); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
214 const char* class_name = data + instance_len + 1; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
215 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
216 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
|
217 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
218 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
219 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
220 /* Title text */ |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
221 std::unique_ptr<xcb_get_property_reply_t> reply( |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
222 ::xcb_get_property_reply(connection, window_cookie.name_property_cookie, NULL)); |
|
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 if (reply) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
225 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
|
226 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
|
227 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
228 win.text = std::string(data, len); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
229 } |
|
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 Process proc = {0}; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
232 { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
233 /* PID */ |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
234 std::unique_ptr<xcb_res_query_client_ids_reply_t> reply( |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
235 ::xcb_res_query_client_ids_reply(connection, window_cookie.pid_property_cookie, NULL)); |
|
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 if (reply) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
238 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
|
239 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
|
240 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
|
241 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
|
242 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
|
243 break; |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
244 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
245 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
246 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
247 } |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
248 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
249 if (!window_proc(proc, win)) { |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
250 ::xcb_disconnect(connection); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
251 return false; |
|
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 ::xcb_disconnect(connection); |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
256 |
|
b1f625b0227c
*: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents:
283
diff
changeset
|
257 return true; |
|
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 } // namespace animone::internal::x11 |
