I have a fairly simple "Hello World" in X11 at end of question. But when it exits I get the run time error messages below:
$ ./xtest
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 9 requests (7 known processed) with 0 events remaining.
So I tried handling the wmDeleteMessage
myself, and I was able to stop the window from closing, so i know I am getting the event correctly. Than I added a XDestroyWindow()
to the event handling and I get new errors.
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
It sounds like i am trying to destroy a already destroyed Window, but if I take out the XDestroyWindow()
it stays alive on my screen.
Below is my code with an attempt at a destroy window handler. How do I exit without any errors?
#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;
}
Update
Changed line to :
std::cout << "Shutting down now!!!" << std::endl;
XDestroyWindow(display,w);
Which I don't like because I plan on having more than window, but for now I am back to the first error message I had :
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 9 requests (7 known processed) with 0 events remaining.
Update
Tried changing many things around like having the loop run off of XPending(). Decided to run someone else's hello world and I get the same problem with their code. Must be something wrong with my setup.
Update Apparently alot of people have this problem. Google ftk had this problem and they fixed it in their change log. They call FTK_QUIT() which i am guessing is like Exit(). So i put my return right there inside the loop and that solved the problem. Not sure why but it did. fixed code:
case ClientMessage:
if(e.xclient.data.l[0] == wmDeleteMessage)
{
XDestroyWindow(display,e.xclient.window);
XCloseDisplay(display);
return 0;
}
Will still give correct answer to someone who can explain why and if is possible move the return statement (along with the XCloseDisplay
) outside of the loop.
The Event loop should look like this to exit properly:
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;
When running in a switch
statement the code does not work. Even if it exits the loop without calling another X function. The if
statement above placed before your switch
statement fixes the issue without returning from the program inside the loop.