Xlib、C++ - 获取 Window 句柄(SendEvent,...)
Xlib,C++ - Get Window Handle (SendEvent,...)
我目前正在使用 XLib 编写一个可以将鼠标和键盘事件发送到某个 window(不显示)的应用程序。
我能够使用 "XGetInputFocus()" 方法获得的 "window" 句柄将这些事件发送到 window。不幸的是,我需要获得另一个 window(不是重点对象)的 window-句柄,并将伪造的输入事件发送到那个 window。因此我写了一个方法"enumerateWindows"来获取这个句柄。
问题来了。我可以找到几个 windows,它们的名称相同。就像树中至少 3 "eclipse" windows 一样。这是为什么?
因为我不知道该选择哪个 "Window",所以我只是将它们全部与我从 "XGetInputFocus()" 方法中获得的 Window 进行了比较。没有匹配项(与对象 identity 进行比较时)。树上无处可去。这是为什么?我还能如何获得与 "XGetInputFocus()" 相同的 Window 引用?
这是我的代码和输出:
#define EMPTY_WINDOW NULL
/* rootWindow: Window that is being looked from
* toSearch : Window that I want to obtain
*/
Window* enumerateWindows(Display *display, Window rootWindow, Window toSearch)
{
Window parent;
Window *children;
unsigned int nNumChildren;
char *name;
// Compare Object identity !!
if(&rootWindow == &toSearch){
cout << "Found correct Window!!" << endl;
return &rootWindow;
}
// Descend tree..
int status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
if (status == 0)
{
cout << "Cant query further.." << endl;
return EMPTY_WINDOW;
}
if (nNumChildren == 0)
{
return EMPTY_WINDOW;
}
for (int i = 0; i < nNumChildren; i++)
{
Window *ret = enumerateWindows(display, children[i],toSearch);
if(ret != EMPTY_WINDOW ){
return ret;
}
}
XFree((char*) children);
return EMPTY_WINDOW;
}
int main()
{
// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if(display == NULL) return -1;
// Get the root window for the current display.
Window winRoot = XDefaultRootWindow(display);
// Find the window which has the current keyboard focus.
Window winFocus;
int revert;
// The important part: Obtain Current focus window!
XGetInputFocus(display, &winFocus, &revert);
// Try to obtain the same window from the QueryTree
Window *win = enumerateWindows(display, winRoot, winFocus);
if( win == &winFocus){
cout << "Object Identity same! Problem solved!" << endl;
}else{
cout << "Didn't find the correct object.." << endl;
}
XCloseDisplay(display);
return 0;
}
感谢您的帮助!提前致谢!
此致
好的,我找到了答案。此代码有效:
Window *getWindowList(Display *disp, unsigned long *len) {
Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type;
int form;
unsigned long remain;
unsigned char *list;
if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,33,
&type,&form,len,&remain,&list) != Success) { // XA_WINDOW
return 0;
}
return (Window*)list;
}
char *getWindowName(Display *disp, Window win) {
Atom prop = XInternAtom(disp,"WM_NAME",False), type;
int form;
unsigned long remain, len;
unsigned char *list;
if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType,
&type,&form,&len,&remain,&list) != Success) { // XA_STRING
return NULL;
}
return (char*)list;
}
int main(){
int i;
unsigned long len;
XKeyEvent esend;
Display *disp = XOpenDisplay(NULL);
Window *list;
char *name;
list = (Window*)getWindowList(disp,&len);
for (i=0;i<(int)len;i++) {
name = getWindowName(disp,list[i]);
cout << i << ": " << name << endl;
free(name);
}
}
XLib Window Name Problems
我目前正在使用 XLib 编写一个可以将鼠标和键盘事件发送到某个 window(不显示)的应用程序。
我能够使用 "XGetInputFocus()" 方法获得的 "window" 句柄将这些事件发送到 window。不幸的是,我需要获得另一个 window(不是重点对象)的 window-句柄,并将伪造的输入事件发送到那个 window。因此我写了一个方法"enumerateWindows"来获取这个句柄。
问题来了。我可以找到几个 windows,它们的名称相同。就像树中至少 3 "eclipse" windows 一样。这是为什么? 因为我不知道该选择哪个 "Window",所以我只是将它们全部与我从 "XGetInputFocus()" 方法中获得的 Window 进行了比较。没有匹配项(与对象 identity 进行比较时)。树上无处可去。这是为什么?我还能如何获得与 "XGetInputFocus()" 相同的 Window 引用?
这是我的代码和输出:
#define EMPTY_WINDOW NULL
/* rootWindow: Window that is being looked from
* toSearch : Window that I want to obtain
*/
Window* enumerateWindows(Display *display, Window rootWindow, Window toSearch)
{
Window parent;
Window *children;
unsigned int nNumChildren;
char *name;
// Compare Object identity !!
if(&rootWindow == &toSearch){
cout << "Found correct Window!!" << endl;
return &rootWindow;
}
// Descend tree..
int status = XQueryTree(display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
if (status == 0)
{
cout << "Cant query further.." << endl;
return EMPTY_WINDOW;
}
if (nNumChildren == 0)
{
return EMPTY_WINDOW;
}
for (int i = 0; i < nNumChildren; i++)
{
Window *ret = enumerateWindows(display, children[i],toSearch);
if(ret != EMPTY_WINDOW ){
return ret;
}
}
XFree((char*) children);
return EMPTY_WINDOW;
}
int main()
{
// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if(display == NULL) return -1;
// Get the root window for the current display.
Window winRoot = XDefaultRootWindow(display);
// Find the window which has the current keyboard focus.
Window winFocus;
int revert;
// The important part: Obtain Current focus window!
XGetInputFocus(display, &winFocus, &revert);
// Try to obtain the same window from the QueryTree
Window *win = enumerateWindows(display, winRoot, winFocus);
if( win == &winFocus){
cout << "Object Identity same! Problem solved!" << endl;
}else{
cout << "Didn't find the correct object.." << endl;
}
XCloseDisplay(display);
return 0;
}
感谢您的帮助!提前致谢!
此致
好的,我找到了答案。此代码有效:
Window *getWindowList(Display *disp, unsigned long *len) {
Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",False), type;
int form;
unsigned long remain;
unsigned char *list;
if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,33,
&type,&form,len,&remain,&list) != Success) { // XA_WINDOW
return 0;
}
return (Window*)list;
}
char *getWindowName(Display *disp, Window win) {
Atom prop = XInternAtom(disp,"WM_NAME",False), type;
int form;
unsigned long remain, len;
unsigned char *list;
if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType,
&type,&form,&len,&remain,&list) != Success) { // XA_STRING
return NULL;
}
return (char*)list;
}
int main(){
int i;
unsigned long len;
XKeyEvent esend;
Display *disp = XOpenDisplay(NULL);
Window *list;
char *name;
list = (Window*)getWindowList(disp,&len);
for (i=0;i<(int)len;i++) {
name = getWindowName(disp,list[i]);
cout << i << ": " << name << endl;
free(name);
}
}
XLib Window Name Problems