【问题标题】:Many XSetInputFocus's and XSync Causes Error许多 XSetInputFocus 和 XSync 导致错误
【发布时间】:2013-05-23 18:08:30
【问题描述】:

在将输入焦点切换到具有匹配进程 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

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

【问题讨论】:

    标签: c++ linux ubuntu x11 xlib


    【解决方案1】:

    从文档中,它说明了以下内容:

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

    • 如果 revert_to 为 RevertToParent,则焦点将返回到父级(或最近的可见祖先),并且新的 revert_to 值被视为 RevertToNone。

    • 如果 revert_to 为 RevertToPointerRoot 或 RevertToNone,则焦点将分别恢复为 PointerRoot 或 None。当焦点恢复时,X server 会产生 FocusIn 和 FocusOut 事件,但不影响 last-focus-change 时间。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 2017-12-08
      • 2017-08-11
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      相关资源
      最近更新 更多