Mercurial > minori
diff dep/animia/src/win/x11.cc @ 199:9f3534f6b8c4
dep/animia: initial Wayland support, drop non-working kvm fd plugin
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Tue, 02 Jan 2024 02:34:27 -0500 |
parents | bc1ae1810855 |
children | 58e81b42a0d6 |
line wrap: on
line diff
--- a/dep/animia/src/win/x11.cc Sun Dec 24 02:59:42 2023 -0500 +++ b/dep/animia/src/win/x11.cc Tue Jan 02 02:34:27 2024 -0500 @@ -5,6 +5,9 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> // XA_* +#ifdef HAVE_XRES +#include <X11/extensions/XRes.h> +#endif #include <cstdint> #include <string> @@ -16,11 +19,16 @@ namespace animia::internal::x11 { +/* specify that these are X types. */ +typedef ::Window XWindow; +typedef ::Display XDisplay; +typedef ::Atom XAtom; + /* should return UTF8_STRING or STRING */ -static bool GetWindowPropertyAsString(::Display* display, ::Window window, ::Atom atom, std::string& result, ::Atom reqtype = AnyPropertyType) { +static bool GetWindowPropertyAsString(XDisplay* display, XWindow window, XAtom atom, std::string& result, XAtom reqtype = AnyPropertyType) { int format; unsigned long leftover_bytes, num_of_items; - ::Atom type; + XAtom type; unsigned char* data; int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, @@ -36,10 +44,35 @@ } /* this should return CARDINAL, a 32-bit integer */ -static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { +static bool GetWindowPID(XDisplay* display, XWindow window, pid_t& result) { +#ifdef HAVE_XRES + { + long num_ids; + XResClientIdValue *client_ids; + XResClientIdSpec spec = { + .client = window, + .mask = XRES_CLIENT_ID_PID_MASK + }; + + ::XResQueryClientIds(display, 1, &spec, &num_ids, &client_ids); + + for (long i = 0; i < num_ids; i++) { + if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) { + result = ::XResGetClientPid(&client_ids[i]); + ::XResClientIdsDestroy(num_ids, client_ids); + return true; + } + } + + ::XResClientIdsDestroy(num_ids, client_ids); + + return false; + } +#endif + int format; unsigned long leftover_bytes, num_of_items; - ::Atom atom = ::XInternAtom(display, "_NET_WM_PID", False), type; + XAtom atom = ::XInternAtom(display, "_NET_WM_PID", False), type; unsigned char* data; int status = ::XGetWindowProperty(display, window, atom, 0L, (~0L), False, XA_CARDINAL, @@ -47,14 +80,14 @@ if (status != Success || type != XA_CARDINAL || num_of_items < 1) return false; - result = static_cast<pid_t>(*(uint32_t*)data); + result = static_cast<pid_t>(*reinterpret_cast<uint32_t*>(data)); ::XFree(data); return true; } -static bool FetchName(::Display* display, ::Window window, std::string& result) { +static bool FetchName(XDisplay* display, XWindow window, std::string& result) { /* TODO: Check if XInternAtom created None or not... */ if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", False), result, ::XInternAtom(display, "UTF8_STRING", False))) @@ -92,19 +125,17 @@ return true; } -static bool WalkWindows(::Display* display, std::set<::Window>& children, const std::set<::Window>& windows) { - /* This sucks. It takes waaaay too long to finish. - * TODO: Look at the code for xwininfo to see what they do. - */ +static bool WalkWindows(XDisplay* display, std::set<XWindow>& children, const std::set<XWindow>& windows) { + /* This can take a VERY long time if many windows are open. */ if (windows.empty()) return false; - for (const ::Window& window : windows) { + for (const XWindow& window : windows) { unsigned int num_children = 0; - ::Window* children_arr = nullptr; + XWindow* children_arr = nullptr; - ::Window root_return; - ::Window parent_return; + XWindow root_return; + XWindow parent_return; int status = ::XQueryTree(display, window, &root_return, &parent_return, &children_arr, &num_children); if (!status || !children_arr) @@ -121,7 +152,7 @@ ::XFree(children_arr); - std::set<::Window> children_children; + std::set<XWindow> children_children; if (WalkWindows(display, children_children, children)) children.insert(children_children.begin(), children_children.end()); @@ -134,13 +165,13 @@ if (!window_proc) return false; - ::Display* display = ::XOpenDisplay(nullptr); + XDisplay* display = ::XOpenDisplay(nullptr); if (!display) return false; - ::Window root = DefaultRootWindow(display); + XWindow root = ::XDefaultRootWindow(display); - std::set<::Window> windows; + std::set<XWindow> windows; WalkWindows(display, windows, {root}); for (const auto& window : windows) {