1

一致するプロセス 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。これら 2 つの呼び出しを削除すると、これらのエラーは発生しなくなりました。ここで何が間違っているのか、両方が不平を言う原因になるのかわかりませXSyncXCloseDisplay

4

1 に答える 1

1

ドキュメントから、次のように述べられています。

指定されたフォーカス ウィンドウは、XSetInputFocus が呼び出された時点で表示可能である必要があります。そうでない場合、BadMatch エラーが発生します。後でフォーカス ウィンドウが表示できなくなった場合、X サーバーは revert_to 引数を評価して、次のように新しいフォーカス ウィンドウを決定します。

  • revert_to が RevertToParent の場合、フォーカスは親 (または表示可能な最も近い祖先) に戻り、新しい revert_to 値は RevertToNone と見なされます。

  • 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;
}
于 2013-05-23T19:27:24.137 に答える