C++ 许多XSetInputFocus';s和XSync导致错误

C++ 许多XSetInputFocus';s和XSync导致错误,c++,linux,ubuntu,x11,xlib,C++,Linux,Ubuntu,X11,Xlib,在使用匹配的进程id将输入焦点切换到每个窗口后,关闭显示器(或同步显示器)时,我收到一个错误。下面是我收到的错误以及产生该错误的源代码 源代码: #include <X11/Xlib.h> #include <X11/Xatom.h> #include <iostream> #include <list> using namespace std; class WindowsMatchingPid{ public: WindowsMatc

在使用匹配的进程id将输入焦点切换到每个窗口后,关闭显示器(或同步显示器)时,我收到一个错误。下面是我收到的错误以及产生该错误的源代码

源代码:

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>
#include <list>

using namespace std;

class WindowsMatchingPid{
public:
    WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
        : _display(display)
        , _pid(pid)
    {
    // Get the PID property atom.
        _atomPID = XInternAtom(display, "_NET_WM_PID", True);
        if(_atomPID == None)
        {
            cout << "No such atom" << endl;
            return;
        }

        search(wRoot);
    }

    const list<Window> &result() const { return _result; }

private:
    unsigned long  _pid;
    Atom           _atomPID;
    Display       *_display;
    list<Window>   _result;

    void search(Window w)
    {
    // Get the PID for the current Window.
        Atom           type;
        int            format;
        unsigned long  nItems;
        unsigned long  bytesAfter;
        unsigned char *propPID = 0;
        if(Success == XGetWindowProperty(_display, w, _atomPID, 0, 1, False, XA_CARDINAL,
                                         &type, &format, &nItems, &bytesAfter, &propPID))
        {
            if(propPID != 0)
            {
            // If the PID matches, add this window to the result set.
                if(_pid == *((unsigned long *)propPID))
                    _result.push_back(w);

                XFree(propPID);
            }
        }

    // Recurse into child windows.
        Window    wRoot;
        Window    wParent;
        Window   *wChild;
        unsigned  nChildren;
        if(0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
        {
            for(unsigned i = 0; i < nChildren; i++)
                search(wChild[i]);
        }
    }
};

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);

    WindowsMatchingPid wmp(display,winRoot,4344);
    list<Window> lw = wmp.result();

    for(list<Window>::iterator it=lw.begin(); it != lw.end(); it++ ){
        XSetInputFocus(display,*it,RevertToParent,CurrentTime);
    }
    //XSync(display,false);
    XCloseDisplay(display);
    return 0;
}
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  42 (X_SetInputFocus)
  Serial number of failed request:  495
  Current serial number in output stream:  506

当到达
XSync
XCloseDisplay
时,它会产生错误。当我删除这两个调用时,它不会产生这些错误。我不确定我在这里做错了什么,导致
XSync
XCloseDisplay
投诉。

从文档中可以看出:

指定的焦点窗口必须在调用XSetInputFocus时可见,否则会导致错误匹配。如果随后焦点窗口变得不可见,X服务器将对revert_to参数求值,以确定新的焦点窗口,如下所示:

  • 如果revert_to为RevertToParent,则焦点将还原到父级(或最近的可视祖先级),并且新的revert_to值将被视为RevertToOne

  • 如果revert_to是RevertToPointerRoot或RevertToNone,则焦点将分别恢复为PointErrorot或None。当焦点恢复时,X服务器生成FocusIn和FocusOut事件,但上次焦点更改时间不受影响

XSetInputFocus可以生成BadMatch、BadValue和BadWindow错误

因此,我错过了一个确定窗口是否可见的检查。以下更改将修复此问题:

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);

    WindowsMatchingPid wmp(display,winRoot,4344);
    list<Window> lw = wmp.result();

    for(list<Window>::iterator it=lw.begin(); it != lw.end(); it++ ){
        XWindowAttributes attribute; // <-- Added
        XGetWindowAttributes(display,*it,&attribute); // <-- Added
        if(attribute.map_state == IsViewable ){ // <-- Added
            XSetInputFocus(display,*it,RevertToParent,CurrentTime);
        } // <-- Added
    }
    XCloseDisplay(display);
    return 0;
}
main()
{
//获取X11显示。
Display*Display=XOpenDisplay(0);
如果(显示==NULL)
返回-1;
//获取当前显示的根窗口。
窗口winRoot=XDefaultRootWindow(显示);
WindowsMatchingPid wmp(显示,winRoot,4344);
list lw=wmp.result();
对于(list::iterator it=lw.begin();it!=lw.end();it++){

XWindowAttributes属性;//从文档中可以看出:

指定的焦点窗口必须在调用XSetInputFocus时可查看,否则将导致错误匹配。如果焦点窗口以后变得不可查看,X服务器将评估revert_to参数以确定新的焦点窗口,如下所示:

  • 如果revert_to为RevertToParent,则焦点将还原到父级(或最近的可视祖先级),并且新的revert_to值将被视为RevertToOne

  • 如果revert_to为RevertToPointerRoot或RevertToNone,则焦点将分别恢复为PointerRoot或None。当焦点恢复时,X服务器将生成FocusIn和FocusOut事件,但上次焦点更改时间不受影响

XSetInputFocus可以生成BadMatch、BadValue和BadWindow错误

因此,我错过了确定窗口是否可见的检查。以下更改将修复此问题:

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);

    WindowsMatchingPid wmp(display,winRoot,4344);
    list<Window> lw = wmp.result();

    for(list<Window>::iterator it=lw.begin(); it != lw.end(); it++ ){
        XWindowAttributes attribute; // <-- Added
        XGetWindowAttributes(display,*it,&attribute); // <-- Added
        if(attribute.map_state == IsViewable ){ // <-- Added
            XSetInputFocus(display,*it,RevertToParent,CurrentTime);
        } // <-- Added
    }
    XCloseDisplay(display);
    return 0;
}
main()
{
//获取X11显示。
Display*Display=XOpenDisplay(0);
如果(显示==NULL)
返回-1;
//获取当前显示的根窗口。
窗口winRoot=XDefaultRootWindow(显示);
WindowsMatchingPid wmp(显示,winRoot,4344);
list lw=wmp.result();
对于(list::iterator it=lw.begin();it!=lw.end();it++){
XWindowAttributes属性//