У меня довольно простое сообщение «Hello World» в X11 в конце вопроса. Но когда он закрывается, я получаю следующие сообщения об ошибках времени выполнения:
$ ./xtest
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 9 requests (7 known processed) with 0 events remaining.
Итак, я попытался обработать wmDeleteMessage
сам, и мне удалось остановить закрытие окна, поэтому я знаю, что получаю событие правильно. . Затем я добавил XDestroyWindow ()
в обработку событий и получаю новые ошибки.
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 4 (X_DestroyWindow)
Resource id in failed request: 0x130
Serial number of failed request: 12
Current serial number in output stream: 12
Похоже, я пытаюсь уничтожить уже разрушенное окно, но если я вытащу XDestroyWindow ()
, он останется живым на моем экране.
Ниже мой код с попыткой уничтожить обработчик окна.Как мне выйти без ошибок?
#include
#include
int main()
{
Display *display;
if(!(display=XOpenDisplay(NULL)))
{
std::cerr << "ERROR: could not open display\n";
return 1;
}
int screen = DefaultScreen(display);
Window rootwind = RootWindow(display, screen);
Colormap cmap = DefaultColormap(display, screen);
Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
int blackColor = BlackPixel(display, screen);
int whiteColor = WhitePixel(display, screen);
Window w = XCreateSimpleWindow(display, rootwind, 0, 0, 200, 100, 0, blackColor, blackColor);
XMapWindow(display, w);
XSetWMProtocols(display, w, &wmDeleteMessage, 1);
bool running = true;
while(running)
{
XEvent e;
XNextEvent(display, &e);
switch (e.type)
{
case ClientMessage:
if(e.xclient.data.l[0] == wmDeleteMessage)
{
std::cout << "Shutting down now!!!" << std::endl;
XDestroyWindow(display,e.xdestroywindow.window);
running=false;
break;
}
break;
}
}
XCloseDisplay(display);
return 0;
}
Обновление
Строка изменена на:
std::cout << "Shutting down now!!!" << std::endl;
XDestroyWindow(display,w);
Что мне не нравится, потому что я планирую иметь больше окна, но сейчас я вернулся к первое сообщение об ошибке, которое у меня было:
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 9 requests (7 known processed) with 0 events remaining.
Update
Пытался изменить многие вещи, например, запустить цикл из XPending (). Решил запустить чужой hello world , и я получил та же проблема с их кодом. Должно быть что-то не так с моей настройкой.
Обновление Похоже, у многих есть эта проблема. У Google ftk была эта проблема, и они исправили ее в своем журнале изменений . Они вызывают FTK_QUIT (), что, как я предполагаю, похоже на Exit (). Итак, я поместил свой возврат прямо в цикл, и это решило проблему. Не уверен, почему, но это произошло. фиксированный код:
case ClientMessage:
if(e.xclient.data.l[0] == wmDeleteMessage)
{
XDestroyWindow(display,e.xclient.window);
XCloseDisplay(display);
return 0;
}
По-прежнему будет давать правильный ответ тому, кто может объяснить, почему и, если возможно, переместите оператор return (вместе с XCloseDisplay
) за пределы цикла.
Для правильного выхода цикл событий должен выглядеть следующим образом:
XEvent e;
do
{
XNextEvent(display, &e);
if(e.type == ClientMessage && e.xclient.data.l[0] == wmDeleteMessage)
{
XDestroyWindow(display,e.xclient.window);
break;
}
//...
}while (XPending(display) > 0)
XCloseDisplay(display);
return 0;
При выполнении в операторе switch
код не работает. Даже если он выходит из цикла без вызова другой функции X. Вышеуказанный оператор if
перед оператором switch
устраняет проблему без возврата из программы внутри цикла.