[英]Xlib test window names
我正在嘗試使用Xlib來控制Xterm。 為此,我制作了一個帶有奇怪標題的Xterm。 在我列出所有窗口並檢查它們的名稱之后。 但是有一些錯誤,我的Xterm的名字在列出時沒有出現。 這是列出所有窗口的代碼:
void CMD::getWindowTerminal()
{
Atom a = XInternAtom(m_display, "_NET_CLIENT_LIST", true);
Atom actualType;
int format;
unsigned long numItems, bytesAfter;
unsigned char *data = 0;
int status = XGetWindowProperty(m_display, m_root_win, a, 0L, (~0L), false,
AnyPropertyType, &actualType, &format, &numItems,
&bytesAfter, &data);
if (status >= Success && numItems)
{
long *array = (long*) data;
for (unsigned long k = 0; k < numItems; k++)
{
// get window Id:
Window w = (Window) array[k];
char* name = '\0';
status = XFetchName(m_display, w, &name);
if (status >= Success)
{
std::cout << w << " " << name << std::endl;
if (name == NULL)
{
m_window_terminal = w;
std::cout << "TERMINAL FOUND" << std::endl;
}
}
XFree(name);
}
XFree(data);
}
}
我無法重現該錯誤; 您的代碼找到了我的xterm窗口。 您是否在查詢剛剛生成的xterm的窗口? 如果是這樣,您可能會遇到競爭狀況,因為您嘗試在xterm有機會創建窗口之前先找到它。 在這種情況下,糟糕的解決方案是稍等片刻,然后重試幾次。
如果不是這種情況,我只能推測(更多)原因(我的推測涉及行為異常的窗口管理器或非常老的軟件),但也許我可以建議一個解決方案:如果xterm沒有出現在根窗口的_NET_CLIENT_LIST
,讓我們直接深入到窗口樹中,看看是否可以在其中找到它。 這段C代碼(移植到C ++應該不難,並且無論如何都可以嘗試)使用XQueryTree
遞歸遍歷窗口樹,因此它查詢所有窗口:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
Window window_from_name_search(Display *display, Window current, char const *needle) {
Window retval, root, parent, *children;
unsigned children_count;
char *name = NULL;
/* Check if this window has the name we seek */
if(XFetchName(display, current, &name) > 0) {
int r = strcmp(needle, name);
XFree(name);
if(r == 0) {
return current;
}
}
retval = 0;
/* If it does not: check all subwindows recursively. */
if(0 != XQueryTree(display, current, &root, &parent, &children, &children_count)) {
unsigned i;
for(i = 0; i < children_count; ++i) {
Window win = window_from_name_search(display, children[i], needle);
if(win != 0) {
retval = win;
break;
}
}
XFree(children);
}
return retval;
}
// frontend function: open display connection, start searching from the root window.
Window window_from_name(char const *name) {
Display *display = XOpenDisplay(NULL);
Window w = window_from_name_search(display, XDefaultRootWindow(display), name);
XCloseDisplay(display);
return w;
}
由於它可以處理所有窗口,因此xterm窗口必須在其中。 如果不是,請返回開頭(有關可能的競爭條件的內容)。 如果不是那樣,那么很奇怪。
搜索后,如果我不添加提示功能將不起作用,為什么? 我在這里添加了一個提示:
if(XFetchName(display, current, &name) > 0) {
int r = strcmp(needle, name);
std::cout << current << " : " << name << std::endl;
XFree(name);
if(r == 0) {
return current;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.