Mercurial > minori
comparison dep/animia/src/win/x11.cc @ 158:80d6b28eb29f
dep/animia: fix most X11 stuff
it looks like _NET_WM_PID isn't supported by MOST clients, or my code is wrong...
core/filesystem: fix Linux config path handling on *nix
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Fri, 17 Nov 2023 02:07:33 -0500 |
parents | 18c8eb5d1edc |
children | 54c5d80a737e |
comparison
equal
deleted
inserted
replaced
157:18c8eb5d1edc | 158:80d6b28eb29f |
---|---|
3 #include "animia.h" | 3 #include "animia.h" |
4 | 4 |
5 #include <X11/Xlib.h> | 5 #include <X11/Xlib.h> |
6 #include <X11/Xutil.h> | 6 #include <X11/Xutil.h> |
7 #include <X11/Xatom.h> // XA_* | 7 #include <X11/Xatom.h> // XA_* |
8 | |
8 #include <cstdint> | 9 #include <cstdint> |
9 #include <string> | 10 #include <string> |
11 #include <memory> | |
12 #include <set> | |
10 | 13 |
11 /* The code for this is very fugly because X11 uses lots of generic type names | 14 /* The code for this is very fugly because X11 uses lots of generic type names |
12 (i.e., Window, Display), so I have to use :: when defining vars to distinguish | 15 (i.e., Window, Display), so I have to use :: when defining vars to distinguish |
13 between Animia's types and X11's types */ | 16 between Animia's types and X11's types */ |
14 | 17 |
15 namespace animia::internal::x11 { | 18 namespace animia::internal::x11 { |
16 | 19 |
17 /* should return UTF8_STRING or STRING */ | 20 /* should return UTF8_STRING or STRING */ |
18 static bool GetWindowPropertyAsString(::Display* display, ::Window window, const char* atom, std::string& result, ::Atom reqtype = AnyPropertyType) { | 21 static bool GetWindowPropertyAsString(::Display* display, ::Window window, ::Atom atom, std::string& result, ::Atom reqtype = AnyPropertyType) { |
19 int format; | 22 int format; |
20 unsigned long leftover_bytes, num_of_items; | 23 unsigned long leftover_bytes, num_of_items; |
21 ::Atom type; | 24 ::Atom type; |
22 unsigned char* data; | 25 unsigned char* data; |
23 | 26 if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, |
24 if (!::XGetWindowProperty(display, window, ::XInternAtom(display, atom, False), 0L, (~0L), False, reqtype, | 27 &type, &format, &num_of_items, &leftover_bytes, &data)) |
25 &type, &format, &num_of_items, &leftover_bytes, &data)) | |
26 return false; | 28 return false; |
27 | 29 |
28 result = std::string((char*)data, num_of_items); | 30 result = std::string((char*)data, num_of_items); |
29 | |
30 ::XFree(data); | |
31 | 31 |
32 return true; | 32 return true; |
33 } | 33 } |
34 | 34 |
35 /* this should return CARDINAL, a 32-bit integer */ | 35 /* this should return CARDINAL, a 32-bit integer */ |
36 static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { | 36 static bool GetWindowPID(::Display* display, ::Window window, pid_t& result) { |
37 int format; | 37 int format; |
38 unsigned long leftover_bytes, num_of_items; | 38 unsigned long leftover_bytes, num_of_items; |
39 ::Atom reqtype = XA_CARDINAL, atom = ::XInternAtom(display, "_NET_WM_PID", False), type; | 39 ::Atom atom = ::XInternAtom(display, "_NET_WM_PID", False), type; |
40 unsigned char* data; | 40 unsigned char* data; |
41 | 41 |
42 /* TODO: check the type for this */ | 42 if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, XA_CARDINAL, |
43 if (!::XGetWindowProperty(display, window, atom, 0L, (~0L), False, reqtype, | 43 &type, &format, &num_of_items, &leftover_bytes, &data)) |
44 &type, &format, &num_of_items, &leftover_bytes, &data)) | |
45 return false; | 44 return false; |
46 | 45 |
47 result = static_cast<pid_t>(*(uint32_t*)data); | 46 result = static_cast<pid_t>(*(uint32_t*)data); |
48 | |
49 ::XFree(data); | |
50 | 47 |
51 return true; | 48 return true; |
52 } | 49 } |
53 | 50 |
54 static bool FetchName(::Display* display, ::Window window, std::string& result) { | 51 static bool FetchName(::Display* display, ::Window window, std::string& result) { |
55 /* TODO: Check if XInternAtom created None or not... */ | 52 /* TODO: Check if XInternAtom created None or not... */ |
56 if (GetWindowPropertyAsString(display, window, "_NET_WM_NAME", result, ::XInternAtom(display, "UTF8_STRING", false))) | 53 if (GetWindowPropertyAsString(display, window, ::XInternAtom(display, "_NET_WM_NAME", False), |
54 result, ::XInternAtom(display, "UTF8_STRING", False))) | |
57 return true; | 55 return true; |
58 | 56 |
59 /* Fallback to XGetWMName() */ | 57 /* Fallback to XGetWMName() */ |
60 XTextProperty text; | 58 XTextProperty text; |
61 | 59 |
83 | 81 |
84 return true; | 82 return true; |
85 } | 83 } |
86 | 84 |
87 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) { | 85 bool X11WinTools::EnumerateWindows(window_proc_t window_proc) { |
88 auto get_window_property = [&](::Display* display, ::Window window, ::Atom atom, unsigned long& num_of_items, unsigned char** data) -> int { | 86 if (!window_proc) |
89 int format; | 87 return false; |
90 unsigned long leftover_bytes; | |
91 ::Atom realtype; | |
92 | |
93 return ::XGetWindowProperty(display, window, atom, 0L, (~0L), false, AnyPropertyType, | |
94 &realtype, &format, &num_of_items, &leftover_bytes, data); | |
95 }; | |
96 | 88 |
97 ::Display* display = ::XOpenDisplay(nullptr); | 89 ::Display* display = ::XOpenDisplay(nullptr); |
98 ::Window root = DefaultRootWindow(display); | 90 ::Window root = DefaultRootWindow(display); |
99 | 91 |
100 unsigned long num_windows; | 92 unsigned int num_windows = 0; |
101 ::Window* windows = nullptr; | 93 ::Window* windows = nullptr; |
102 | 94 |
103 int status = get_window_property(display, root, ::XInternAtom(display, "_NET_CLIENT_LIST", true), num_windows, (unsigned char**)&windows); | 95 { |
96 ::Window root_return; | |
97 ::Window parent_return; | |
104 | 98 |
105 if (status < Success) | 99 int status = ::XQueryTree(display, root, &root_return, &parent_return, &windows, &num_windows); |
106 return false; | 100 if (status < Success) |
101 return false; | |
102 } | |
107 | 103 |
108 for (long k = 0; k < num_windows; k++) { | 104 for (long k = 0; k < num_windows; k++) { |
109 const ::Window window = windows[k]; | 105 const ::Window window = windows[k]; |
110 | 106 |
111 Window win; | 107 Window win; |
112 win.id = (long)windows[k]; | 108 win.id = window; |
113 { | 109 { |
114 ::XClassHint* hint = ::XAllocClassHint(); | 110 ::XClassHint* hint = ::XAllocClassHint(); |
115 if (::XGetClassHint(display, window, hint)) { | 111 if (::XGetClassHint(display, window, hint)) { |
116 win.class_name = hint->res_class; | 112 win.class_name = hint->res_class; |
117 ::XFree(hint); | 113 ::XFree(hint); |
124 | 120 |
125 if (!window_proc(proc, win)) | 121 if (!window_proc(proc, win)) |
126 return false; | 122 return false; |
127 } | 123 } |
128 | 124 |
125 ::XFree(windows); | |
126 | |
129 return true; | 127 return true; |
130 } | 128 } |
131 | 129 |
132 } | 130 } |