Как выйти из программы X11 без ошибки

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

17
задан Kev 19 November 2011 в 02:23
поделиться