注意:这是对“什么进程创建了这个 X11 窗口?”的回答的延续。来自 unix.stackexchange。该答案提到了XResQueryClientIdsX -Resource v1.2 扩展。我想知道如何使用它。
如何使用python 的 xcfib 模块查找与提供的 PID 关联的所有 X11 窗口 ID(假设没有竞争条件;窗口或进程没有被创建或销毁)。
我对 X11 不太了解,XCB API 文档似乎不完整,自动生成的 xcfib python 绑定也没有文档记录。根据我收集的信息,我需要:
\n\n\n假设没有竞争条件;窗口或进程没有被创建或销毁
\n
如果你知道假设不成立,那么假设就是不好的。幸运的是,您不需要这个假设。只需使用xcb_grab_server和xcb_ungrab_server,这就不会成为问题。
现在,至于XResQueryClientIds,您实际上只需输入 即可man xcb_res_query_client_ids。XCB 只是提供了这个,不需要实际查询扩展。这是一个示例程序。编译它gcc -lxcb -lxcb-res main.c,然后通过传递窗口 ID 作为唯一参数来执行它(例如,./a.out 0x2c00004)来执行它。
#include <stdio.h>\n#include <stdlib.h>\n#include <xcb/xcb.h>\n#include <xcb/res.h>\n\nint main(int argc, char *argv[]) {\n int screen;\n xcb_connection_t *conn = xcb_connect(NULL, &screen);\n\n xcb_res_client_id_spec_t spec = {0};\n spec.client = strtol(argv[1], NULL, 0);\n spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;\n\n xcb_generic_error_t *err = NULL;\n xcb_res_query_client_ids_cookie_t cookie = xcb_res_query_client_ids(conn, 1, &spec);\n xcb_res_query_client_ids_reply_t *reply = xcb_res_query_client_ids_reply(conn, cookie, &err);\n\n if (reply == NULL) {\n fprintf(stderr, "Uh-Oh! :(\\n");\n return -1;\n }\n\n uint32_t *pid = NULL;\n xcb_res_client_id_value_iterator_t it = xcb_res_query_client_ids_ids_iterator(reply);\n for (; it.rem; xcb_res_client_id_value_next(&it)) {\n spec = it.data->spec;\n if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {\n pid = xcb_res_client_id_value_value(it.data);\n break;\n }\n }\n\n free(reply);\n xcb_disconnect(conn);\n\n fprintf(stderr, "PID: %d\\n", *pid);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n为了给出正确的归属,我自己也不知道这些,我只是用谷歌搜索 XCB 函数名称并发现了这个. 要了解各个部分,我建议阅读它的 Xlib 文档。正如您所注意到的,XCB 通常是\xe2\x80\xa6 “记录不足”,但它实际上与 Xlib 相同,但大多数情况下名称略有不同。
\n