我不知道为什么会发生这种情况,但是我在C ++中使用Xlib创build的任何窗口在尝试closures时都会向terminal输出一个错误,并使用Xbutton。 我可以没有错误地以编程方式closures它,它只是Xbutton。
错误如下:
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0" after 483 requests (483 known processed) with 0 events remaining.
请求数量每次都是不同的,但总是有0个事件。 为什么会这样呢? 原因似乎并不是我的代码,因为它不pipe是什么,也不向队列发送closures事件。 我试过拦截Atom WM_WINDOW_DELETE,并且在closures窗口时,它不会运行在期望的代码上。
编辑:添加事件循环代码。
while(XPending(display)) { XNextEvent(display, &event); pthread_mutex_unlock(&mutex); if(event.type == Expose) { XWindowAttributes getWindowAttributes; pthread_mutex_lock(&mutex); XGetWindowAttributes(display, window, &getWindowAttributes); if(state.currentState == STATE_NORMAL) { state.normX = getWindowAttributes.x; state.normY = getWindowAttributes.y; state.normWidth = getWindowAttributes.width; state.normHeight = getWindowAttributes.height; } pthread_mutex_unlock(&mutex); glViewport(0, 0, getWindowAttributes.width, getWindowAttributes.height); } else if(event.type == KeyPress) { return false; } else if(event.type == ClientMessage) { std::cout<<"X Button pressed"<<std::endl; //Never run when X-ing window if(event.xclient.message_type == XInternAtom(display, "WM_DELETE_WINDOW", True)) { return false; } } else if(event.type == ButtonPress) { if(state.currentState != STATE_FULLSCREEN) { fullscreen(); } else { normalize(); } } else if(!handleEvent(event)){ return false; } pthread_mutex_lock(&mutex); }
除了WM_WINDOW_DELETE
之外,您还需要侦听并处理ClientMessage
事件。
修改从Rosetta代码的例子来说明:
#include <X11/Xlib.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { Display *d; Window w; XEvent e; const char *msg = "Hello, World!"; int s; d = XOpenDisplay(NULL); if (d == NULL) { fprintf(stderr, "Cannot open display\n"); exit(1); } s = DefaultScreen(d); w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1, BlackPixel(d, s), WhitePixel(d, s)); XSelectInput(d, w, ExposureMask | KeyPressMask); XMapWindow(d, w); // I support the WM_DELETE_WINDOW protocol Atom WM_DELETE_WINDOW = XInternAtom(d, "WM_DELETE_WINDOW", False); XSetWMProtocols(d, w, &WM_DELETE_WINDOW, 1); while (1) { XNextEvent(d, &e); if (e.type == Expose) { XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg)); } else if (e.type == KeyPress) break; else if (e.type == ClientMessage) // TODO Should check here for other client message types - // however as the only protocol registered above is WM_DELETE_WINDOW // it is safe for this small example. break; } XCloseDisplay(d); return 0; }