annotate src/win/x11.cc @ 20:7174ff20498d

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