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