1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-29 01:58:26 +00:00

Fix bad query_x11_windows early returns (#1864)

* Fix bad early returns
* Prevent fallback tree traversal from propagation code

Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
This commit is contained in:
Tin Švagelj 2024-04-26 00:09:20 +00:00 committed by GitHub
parent 0821c25533
commit 71c4e6ea52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 32 deletions

View File

@ -1429,39 +1429,47 @@ std::vector<Window> x11_atom_window_list(Display *display, Window window,
return std::vector<Window>{};
}
std::vector<Window> query_x11_windows(Display *display) {
std::vector<Window> query_x11_windows(Display *display, bool eager) {
Window root = DefaultRootWindow(display);
Atom clients_atom = ATOM(_NET_CLIENT_LIST_STACKING);
std::vector<Window> result =
x11_atom_window_list(display, root, clients_atom);
if (result.empty()) { return result; }
std::vector<Window> result;
clients_atom = ATOM(_NET_CLIENT_LIST);
result = x11_atom_window_list(display, root, clients_atom);
if (result.empty()) { return result; }
Atom clients_atom = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", True);
if (clients_atom != 0) {
result = x11_atom_window_list(display, root, clients_atom);
if (!result.empty()) { return result; }
}
clients_atom = XInternAtom(display, "_NET_CLIENT_LIST", True);
if (clients_atom != 0) {
result = x11_atom_window_list(display, root, clients_atom);
if (!result.empty()) { return result; }
}
// slowest method
std::vector<Window> queue = {DefaultVRootWindow(display)};
if (eager) {
std::vector<Window> queue = {DefaultVRootWindow(display)};
Window _ignored, *children;
std::uint32_t count;
Window _ignored, *children;
std::uint32_t count;
const auto has_wm_hints = [&](Window window) {
auto hints = XGetWMHints(display, window);
bool result = hints != NULL;
if (result) XFree(hints);
return result;
};
const auto has_wm_hints = [&](Window window) {
auto hints = XGetWMHints(display, window);
bool result = hints != NULL;
if (result) XFree(hints);
return result;
};
while (!queue.empty()) {
Window current = queue.back();
queue.pop_back();
if (XQueryTree(display, current, &_ignored, &_ignored, &children, &count)) {
for (size_t i = 0; i < count; i++) queue.push_back(children[i]);
if (has_wm_hints(current)) result.push_back(current);
if (count > 0) XFree(children);
while (!queue.empty()) {
Window current = queue.back();
queue.pop_back();
if (XQueryTree(display, current, &_ignored, &_ignored, &children,
&count)) {
for (size_t i = 0; i < count; i++) queue.push_back(children[i]);
if (has_wm_hints(current)) result.push_back(current);
if (count > 0) XFree(children);
}
}
}
@ -1486,13 +1494,13 @@ Window query_x11_window_at_pos(Display *display, int x, int y) {
std::vector<Window> query_x11_windows_at_pos(
Display *display, int x, int y,
std::function<bool(XWindowAttributes &)> predicate) {
std::function<bool(XWindowAttributes &)> predicate, bool eager) {
std::vector<Window> result;
Window root = DefaultVRootWindow(display);
XWindowAttributes attr;
for (Window current : query_x11_windows(display)) {
for (Window current : query_x11_windows(display, eager)) {
int pos_x, pos_y;
Window _ignore;
// Doesn't account for decorations. There's no sane way to do that.

View File

@ -132,12 +132,13 @@ std::vector<Window> x11_atom_window_list(Display *display, Window window,
///
/// If neither of the atoms are provided, this function tries traversing the
/// window graph in order to collect windows. In this case, map state of windows
/// is ignored. This also produces a lot of noise for some WM/DEs due to
/// inserted window decorations.
/// is ignored.
///
/// @param display which display to query for windows @return a (likely) ordered
/// list of windows
std::vector<Window> query_x11_windows(Display *display);
/// @param display which display to query for windows
/// @param eager fallback to very slow tree traversal to ensure a list of
/// windows is returned even if window list atoms aren't defined
/// @return a (likely) ordered list of windows
std::vector<Window> query_x11_windows(Display *display, bool eager = false);
/// @brief Finds the last ascendant of a window (trunk) before root.
///
@ -171,7 +172,8 @@ Window query_x11_window_at_pos(Display *display, int x, int y);
std::vector<Window> query_x11_windows_at_pos(
Display *display, int x, int y,
std::function<bool(XWindowAttributes &)> predicate =
[](XWindowAttributes &a) { return true; });
[](XWindowAttributes &a) { return true; },
bool eager = false);
#ifdef BUILD_XDBE
void xdbe_swap_buffers(void);