- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想在 C 中使用 Xlib 获取所有打开的窗口标题的列表。我正在运行 Ubuntu 12.04。我正在使用以下代码来完成此操作:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, &len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
现在我遇到的问题是,这会通过大多数窗口,然后给我一个 BadWindow 错误:
0: DNDCollectionWindow
1: launcher
2: Desktop
3: panel
4: Dash
5: Hud
6: Switcher
7: Update Manager
8: Terminal
9: Ask a Question - Stack Overflow - Mozilla Firefox
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 20 (X_GetProperty)
Resource id in failed request: 0x41
Serial number of failed request: 22
Current serial number in output stream: 22
所以我想知道是否有人知道造成这种情况的原因/如何解决它?
据我所知,列表函数正在返回一些我无法检索其名称的窗口,但我不确定。
提前致谢!
最佳答案
根据我的评论,由于问题中列出了代码,我收到了编译器警告:
In function ‘list’: 14:29: warning: passing argument 10 of ‘XGetWindowProperty’ from incompatible pointer type [enabled by default]
&type, &form, &len, &remain, &list);
^In file included ...: /usr/include/X11/Xlib.h:2688:12: note: expected ‘long unsigned int ’ but argument is of type ‘long unsigned int *’
通过从第 10 个参数中删除地址运算符,将 &len
更改为 len
来解决这个问题,因为它被传递给 list()
作为 unsigned long *len
。
注意:在 name()
函数中,因为它被声明为 unsigned long len
,address-of 运算符是必需的。
因此,我从以下编译没有警告的代码开始:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
最初我没有收到 BadWindow
错误,所以我在第 38 行插入了一个 sleep( 3 )
,就在 for 循环之前给我足够的时间关闭窗口以尝试复制该行为。
果然,这重现了错误:BadWindow(无效的 Window 参数)
。
扫描代码,最初看起来 if( wlist[i]==0 )
应该踢出无效的窗口句柄,但实际上并非如此。此外,将 if( !window )
测试插入到 name()
函数本身同样是徒劳的。
然而,函数XSetErrorHandler可能会有一些用处,我已经包含了您的代码,经过修改以显示用法:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
int catcher( Display *disp, XErrorEvent *xe )
{
printf( "Something had happened, bruh.\n" );
return 0;
}
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
sleep( 3 ); // <-- inserted to give me time to close an open window
XSetErrorHandler( catcher ); // <-- inserted to set error handler
int i;
for(i = 0; i < (int)len; i++){
// if(wlist[i] != 0){ // <-- apparently futile?
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
// }
}
XSetErrorHandler( NULL ); // <-- restore the default error handler
return 0;
}
我只是创建了一个小函数 int catcher( Display*, XErrorEvent * )
来捕获错误,避免运行时终止。
如果您需要编写更多代码,我已经包含了对 XErrorHandler()
的第二次调用,传递 NULL
以恢复默认处理程序。
一些其他注意事项,首先通过终止我创建的最后一个窗口来测试此代码,但这还不足以确定它是否会在收到错误后继续。因此,我进行了第二次测试,其中我杀死了列表末尾之前的窗口,并验证了成功。
一些最后的说明:
显然,错误处理程序被过度简化了。捕获到错误时,会显示消息,程序会继续运行。然而,窗口项目仍然被打印,但被反射(reflect)为 (null)
...
例如:
7: neo – Dolphin
8: neo – Dolphin
Something had happened, bruh.
9: (null)
10: neo – Dolphin
希望这可以帮助您开始……我将留下有趣的部分,例如检测“已发生”的错误,以及调整列表的编号/显示由您决定; )
关于C - Xlib - 使用 XGetWindowProperty 作为窗口标题的 BadWindow 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25349163/
我正在使用以下代码从根窗口读取 _NET_ACTIVE_WINDOW 原子: Atom actualType; int actualFormat; unsigned long nItems, byte
我在阅读某些 XWindow ICCCM 属性时遇到问题。 问题实际上是当我尝试读取 _NET_WM_STATUS 属性时。 我正在使用的功能是: int get_property_value(Dis
我正在使用以下命令获取所有 X 窗口的名称: Atom nameAtom = XInternAtom(dpy,"_NET_WM_NAME",false); Atom type; int f
我想在 C 中使用 Xlib 获取所有打开的窗口标题的列表。我正在运行 Ubuntu 12.04。我正在使用以下代码来完成此操作: #include #include #include #inc
我是一名优秀的程序员,十分优秀!