260 // writer->writeAttribute(&yRoot, typeid (yRoot)); |
261 // writer->writeAttribute(&yRoot, typeid (yRoot)); |
261 relationalWriterFlush(); |
262 relationalWriterFlush(); |
262 } |
263 } |
263 } |
264 } |
264 |
265 |
|
266 relpipe::common::type::StringX fetchWindowName(const Display& display, Window window) { |
|
267 relpipe::common::type::StringX name; |
|
268 // TODO: this does not work → use XGetWMName(), XmbTextPropertyToTextList(), XFreeStringList() instead of XFetchName() |
|
269 // char* rawName = nullptr; |
|
270 // if (XFetchName(display.display, window, &rawName) && rawName) |
|
271 // name = convertor.from_bytes(rawName); // bad encoding, std::range_error – wstring_convert::from_bytes |
|
272 // std::cout << "\n\n\n>>> " << rawName << " <<<\n\n\n"; // bad encoding, not UTF-8 |
|
273 //XFree(rawName); |
|
274 return name; |
|
275 } |
|
276 |
|
277 void listWindow(const Display& display, Window window, relpipe::common::type::Integer level, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) { |
|
278 Window rootWindow; |
|
279 Window parentWindow; |
|
280 unsigned int childrenCount; |
|
281 Window* childrenList; |
|
282 if (!XQueryTree(display.display, window, &rootWindow, &parentWindow, &childrenList, &childrenCount)) |
|
283 throw std::invalid_argument("Unable to query the tree for window: " + std::to_string(window)); |
|
284 |
|
285 XWindowAttributes windowAttributes; |
|
286 if (!XGetWindowAttributes(display.display, window, &windowAttributes)) |
|
287 throw std::invalid_argument("Unable to get attributes for window: " + std::to_string(window)); |
|
288 |
|
289 XClassHint classHint; |
|
290 relpipe::common::type::StringX resClass; |
|
291 relpipe::common::type::StringX resName; |
|
292 if (XGetClassHint(display.display, window, &classHint)) { |
|
293 if (classHint.res_class) resClass = convertor.from_bytes(classHint.res_class); |
|
294 if (classHint.res_name) resName = convertor.from_bytes(classHint.res_name); |
|
295 XFree(classHint.res_class); |
|
296 XFree(classHint.res_name); |
|
297 } |
|
298 |
|
299 writer->writeAttribute(std::to_wstring(window)); |
|
300 // writer->writeAttribute(std::to_wstring(screen?)); |
|
301 // writer->writeAttribute(std::to_wstring(root_win)); |
|
302 writer->writeAttribute(std::to_wstring(parentWindow)); |
|
303 writer->writeAttribute(&level, typeid (level)); |
|
304 writer->writeAttribute(fetchWindowName(display, window)); |
|
305 writer->writeAttribute(resClass); |
|
306 writer->writeAttribute(resName); |
|
307 writer->writeAttribute(std::to_wstring(windowAttributes.x)); |
|
308 writer->writeAttribute(std::to_wstring(windowAttributes.y)); |
|
309 writer->writeAttribute(std::to_wstring(windowAttributes.width)); |
|
310 writer->writeAttribute(std::to_wstring(windowAttributes.height)); |
|
311 |
|
312 for (unsigned int i = 0; i < childrenCount; i++) listWindow(display, childrenList[i], level + 1, configuration, writer, relationalWriterFlush); |
|
313 |
|
314 XFree(childrenList); |
|
315 } |
|
316 |
|
317 void listWindows(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) { |
|
318 writer->startRelation(L"x11_window",{ |
|
319 {L"id", relpipe::writer::TypeId::INTEGER}, |
|
320 // {L"screen", relpipe::writer::TypeId::INTEGER}, |
|
321 // {L"root", relpipe::writer::TypeId::INTEGER}, |
|
322 {L"parent", relpipe::writer::TypeId::INTEGER}, |
|
323 {L"level", relpipe::writer::TypeId::INTEGER}, |
|
324 {L"name", relpipe::writer::TypeId::STRING}, |
|
325 {L"res_class", relpipe::writer::TypeId::STRING}, |
|
326 {L"res_name", relpipe::writer::TypeId::STRING}, |
|
327 {L"x", relpipe::writer::TypeId::INTEGER}, |
|
328 {L"y", relpipe::writer::TypeId::INTEGER}, |
|
329 {L"width", relpipe::writer::TypeId::INTEGER}, |
|
330 {L"height", relpipe::writer::TypeId::INTEGER}, |
|
331 }, true); |
|
332 |
|
333 int screen = DefaultScreen(display.display); |
|
334 Window window = RootWindow(display.display, screen); |
|
335 |
|
336 listWindow(display, window, 0, configuration, writer, relationalWriterFlush); |
|
337 } |
|
338 |
265 static int handleXError(::Display* display, XErrorEvent* errorEvent) { |
339 static int handleXError(::Display* display, XErrorEvent* errorEvent) { |
266 std::wcerr << L"X11 error:" |
340 std::wcerr << L"X11 error:" |
267 << L" display=" << errorEvent->display |
341 << L" display=" << errorEvent->display |
268 << L" error_code=" << errorEvent->error_code |
342 << L" error_code=" << errorEvent->error_code |
269 << L" minor_code=" << errorEvent->minor_code |
343 << L" minor_code=" << errorEvent->minor_code |