У меня довольно простой "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
, исправляет проблему, не возвращаясь из программы внутри цикла.