我正在尝试在X11会话中获取所有顶级桌面窗口的列表.基本上,我想获得窗口管理器应用程序切换UI中显示的所有窗口的列表(通常在用户按下ALT + TAB时打开).
我之前从未做过任何X11编程,但到目前为止,我已经设法通过整个窗口列表进行枚举,代码看起来像这样:
void CSoftwareInfoLinux::enumerateWindows(Display *display, Window rootWindow)
{
Window parent;
Window *children;
Window *child;
quint32 nNumChildren;
XTextProperty wmName;
XTextProperty wmCommand;
int status = XGetWMName(display, rootWindow, &wmName);
if (status && wmName.value && wmName.nitems)
{
int i;
char **list;
status = XmbTextPropertyToTextList(display, &wmName, &list, &i);
if (status >= Success && i && *list)
{
qDebug() << "Found window with name:" << (char*) *list;
}
status = XGetCommand(display, rootWindow, &list, &i);
if (status >= Success && i && *list)
{
qDebug() …Run Code Online (Sandbox Code Playgroud) 到目前为止,我发现了两种方法:
对于每个根窗口(默认屏幕、特定屏幕、所有屏幕等),列出每个直接子窗口。递归地搜索每个直接子节点以查找具有该WM_STATE属性的窗口;该窗口成为直接子级的顶级应用程序窗口,所有递归都可以停止。如果直接子级的层次结构中没有窗口具有该WM_STATE属性,则假定直接子级本身就是顶级应用程序窗口。
使用xcb_get_property, and xcb_query_tree(尽管名称仅列出直系孩子)。
这就是xlsclients使用的,通过 XCB(与上面相同的算法,或多或少)。
要求:需要 ICCCM(窗口管理器)支持WM_STATE.
对于每个根窗口(默认屏幕、特定屏幕、所有屏幕等),获取“_NET_CLIENT_LIST”属性,该属性列出了窗口管理器管理的所有顶级应用程序窗口。
使用xcb_get_property.
这是wmctrl通过 Xlib 使用的。
需要窗口管理器来维护列表。一些窗口似乎逃脱了列表。
要求:EWMH(窗口管理器)支持_NET_CLIENT_LIST或_WIN_CLIENT_LIST(我不知道第二个是什么;我找不到任何文档)。
问题:
还有其他方法吗?是否有任何方法不依赖于外部机制,例如 ICCCM 或 EWMH?
哪种方法最有弹性?
_NET_CLIENT_LIST. 为什么是这样?WM_STATE级是顶级应用程序窗口,那么是否会匹配无窗口应用程序?更糟糕的是,它不会在虚拟根窗口下严重崩溃吗?例如,虚拟根窗口成为唯一的直接子窗口,递归将在第一个应用程序窗口上停止WM_STATE;只会匹配一个窗口。针对这种可能性,xlsclients不包括对虚拟根窗口的任何检查……那么为什么它可以与 GNOME(使用虚拟根窗口)一起使用?