annotate dep/animone/src/win/x11.cc @ 277:a796e97cc86d

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