Многие XSetInputFocus и XSync вызывают ошибки

Я получаю сообщение об ошибке при закрытии дисплея (или при его синхронизации) после переключения фокуса ввода на каждое окно с соответствующим идентификатором процесса. Ниже приведена ошибка, которую я получаю, и исходный код, который ее производит.

Исходный код:

#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 жаловаться.

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]