У меня довольно простой "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<X11/Xlib.h>
#include <iostream>
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.
Обновление
Попытался изменить многие вещи, как если бы цикл был запущен XPending(). Решил запустить кого-то еще привет мир, и я получаю ту же проблему с их кодом. Должно быть что-то не так с моей настройкой.
Обновление По-видимому, у многих людей есть эта проблема. Эта проблема возникла у 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) за пределы цикла.
Цикл Event должен выглядеть так, чтобы он был правильно выполнен:
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 код не работает. Даже если он выходит из цикла без вызова другой функции Х. Вышеуказанный оператор if, поставленный перед оператором switch, исправляет проблему, не возвращаясь из программы внутри цикла.