Mercurial > minori
changeset 157:18c8eb5d1edc
x11: make it work
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Thu, 16 Nov 2023 16:51:34 -0500 |
parents | cdf79282d647 |
children | 80d6b28eb29f 900b5b530883 |
files | dep/animia/src/fd/xnu.cc dep/animia/src/win.cc dep/animia/src/win/x11.cc |
diffstat | 3 files changed, 42 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/dep/animia/src/fd/xnu.cc Wed Nov 15 18:04:04 2023 -0500 +++ b/dep/animia/src/fd/xnu.cc Thu Nov 16 16:51:34 2023 -0500 @@ -19,13 +19,10 @@ namespace animia::internal::xnu { static std::string GetProcessName(pid_t pid) { - struct proc_bsdinfo proc; + char name[2*MAXCOMLEN]; + proc_name(pid, name, sizeof(name)); - int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); - if (st != PROC_PIDTBSDINFO_SIZE) - return ""; - - return (proc.pbi_name[0]) ? proc.pbi_name : proc.pbi_comm; + return name; } bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { @@ -38,8 +35,7 @@ return false; } - for (int i = 0; i < size / sizeof(*pids); i++) { - const pid_t pid = pids[i].kp_proc.p_pid; + for (const auto& pid : pids) { if (!process_proc({pid, GetProcessName(pid)})) return false; }
--- a/dep/animia/src/win.cc Wed Nov 15 18:04:04 2023 -0500 +++ b/dep/animia/src/win.cc Thu Nov 16 16:51:34 2023 -0500 @@ -12,6 +12,8 @@ win32::Win32WinTools os_win; #elif MACOSX quartz::QuartzWinTools os_win; +#elif X11 +x11::X11WinTools os_win; #else BaseWinTools os_win; #endif
--- a/dep/animia/src/win/x11.cc Wed Nov 15 18:04:04 2023 -0500 +++ b/dep/animia/src/win/x11.cc Thu Nov 16 16:51:34 2023 -0500 @@ -1,4 +1,12 @@ +#include "animia/win/x11.h" +#include "animia/win.h" +#include "animia.h" + #include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> // XA_* +#include <cstdint> +#include <string> /* The code for this is very fugly because X11 uses lots of generic type names (i.e., Window, Display), so I have to use :: when defining vars to distinguish @@ -6,31 +14,34 @@ namespace animia::internal::x11 { +/* should return UTF8_STRING or STRING */ static bool GetWindowPropertyAsString(::Display* display, ::Window window, const char* atom, std::string& result, ::Atom reqtype = AnyPropertyType) { int format; unsigned long leftover_bytes, num_of_items; ::Atom type; - void* data; + unsigned char* data; - if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype, + if (!::XGetWindowProperty(display, window, ::XInternAtom(display, atom, False), 0L, (~0L), False, reqtype, &type, &format, &num_of_items, &leftover_bytes, &data)) return false; - result = std::string(data, num_of_items); + result = std::string((char*)data, num_of_items); ::XFree(data); return true; } +/* this should return CARDINAL, a 32-bit integer */ static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { int format; unsigned long leftover_bytes, num_of_items; - ::Atom type; - void* data; + ::Atom reqtype = XA_CARDINAL, atom = ::XInternAtom(display, "_NET_WM_PID", False), type; + unsigned char* data; - if (!::XGetWindowProperty(display, root, ::XInternAtom(display, atom, true), 0L, (~0L), false, reqtype, - &type, &format, &num_of_items, &leftover_bytes, &data)) + /* TODO: check the type for this */ + if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, + &type, &format, &num_of_items, &leftover_bytes, &data)) return false; result = static_cast<pid_t>(*(uint32_t*)data); @@ -50,17 +61,17 @@ { int status = ::XGetWMName(display, window, &text); - if (!status || !text_prop.value || !text_prop.nitems) + if (!status || !text.value || !text.nitems) return false; } char** list; { - int num; + int count; - int status = ::XmbTextPropertyToTextList(display, &text, &list, &num); - if (status < Success || !num || !*list) + int status = ::XmbTextPropertyToTextList(display, &text, &list, &count); + if (status < Success || !count || !*list) return false; } @@ -74,22 +85,22 @@ } bool X11WinTools::EnumerateWindows(window_proc_t window_proc) { - auto get_window_property = [&](Display* display, Window window, Atom atom, unsigned long& num_of_items, void*& data) -> int { + auto get_window_property = [&](::Display* display, ::Window window, ::Atom atom, unsigned long& num_of_items, unsigned char** data) -> int { int format; unsigned long leftover_bytes; ::Atom realtype; - return ::XGetWindowProperty(display, root, atom, 0L, (~0L), false, AnyPropertyType, - &realtype, &format, &num_of_items, &leftover_bytes, &data); - } + return ::XGetWindowProperty(display, window, atom, 0L, (~0L), false, AnyPropertyType, + &realtype, &format, &num_of_items, &leftover_bytes, data); + }; ::Display* display = ::XOpenDisplay(nullptr); - ::Window root = ::DefaultRootWindow(display); + ::Window root = DefaultRootWindow(display); unsigned long num_windows; ::Window* windows = nullptr; - int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (void*)windows); + int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (unsigned char**)&windows); if (status < Success) return false; @@ -99,8 +110,14 @@ Window win; win.id = (long)windows[k]; - GetWindowPropertyAsString(display, window, "_NET_ACTIVE_WINDOW", win.class_name, ::XInternAtom(display, "STRING", false)); - win.title = FetchName(display, windows[k]); + { + ::XClassHint* hint = ::XAllocClassHint(); + if (::XGetClassHint(display, window, hint)) { + win.class_name = hint->res_class; + ::XFree(hint); + } + } + FetchName(display, windows[k], win.text); Process proc; GetWindowPID(display, window, proc.pid);