Xlib:关闭窗口总是导致致命的IO错误? 我不知道为什么会发生这种情况,但是我在C++中使用XLIB创建的任何窗口都会给输出端一个错误,当我尝试关闭时,使用X按钮。我可以以编程方式关闭它,没有错误,只是X按钮完成了它

Xlib:关闭窗口总是导致致命的IO错误? 我不知道为什么会发生这种情况,但是我在C++中使用XLIB创建的任何窗口都会给输出端一个错误,当我尝试关闭时,使用X按钮。我可以以编程方式关闭它,没有错误,只是X按钮完成了它,c++,c,linux,xlib,C++,C,Linux,Xlib,错误如下: XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":0" after 483 requests (483 known processed) with 0 events remaining. 每次请求的数量都不同,但总有0个事件剩余。为什么会发生这种情况?原因似乎不是我的代码,因为不管发生什么,它都会这样做,并且不会向队列发送关闭事件。我曾尝试拦截Atom WM_WINDOW_DELETE,

错误如下:

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 483 requests (483 known processed) with 0 events remaining.
每次请求的数量都不同,但总有0个事件剩余。为什么会发生这种情况?原因似乎不是我的代码,因为不管发生什么,它都会这样做,并且不会向队列发送关闭事件。我曾尝试拦截Atom WM_WINDOW_DELETE,但当我关闭窗口时,它没有超出预期的代码

编辑:添加事件循环代码

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);
}
while(xpend(显示)){
XNextEvent(显示和事件);
pthread_mutex_unlock(&mutex);
if(event.type==Expose){
XWindowAttributes getWindowAttributes;
pthread_mutex_lock(&mutex);
XGetWindowAttributes(显示、窗口和getWindowAttributes);
如果(state.currentState==状态_正常){
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){
返回false;
}else if(event.type==ClientMessage){

std::cout除了
WM\u WINDOW\u DELETE
之外,您还需要监听并处理
ClientMessage
事件

从中修改示例以说明:

#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;
}
#包括
#包括
#包括
#包括
内部主(空){
显示*d;
窗口w;
XEvent e;
const char*msg=“你好,世界!”;
int-s;
d=XOpenDisplay(空);
如果(d==NULL){
fprintf(stderr,“无法打开显示\n”);
出口(1);
}
s=默认屏幕(d);
w=XCreateSimpleWindow(d,根窗口(d,s),10,10,100,100,1,黑色像素(d,s),白色像素(d,s));
X选择输入(d、w、曝光掩模|按键掩模);
XMapWindow(d,w);
//我支持WM_DELETE_窗口协议
原子WM_DELETE_WINDOW=XInternAtom(d,“WM_DELETE_WINDOW”,False);
XSetWMProtocols(d、w和WM_删除_窗口,1);
而(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==按键)
打破
else if(e.type==ClientMessage)
//TODO应在此处检查其他客户端消息类型-
//但是,由于上面注册的唯一协议是WM_DELETE_WINDOW
//这个小例子是安全的。
打破
}
XCloseDisplay(d);
返回0;
}

任何窗口,甚至弹出窗口或瞬变?除了
WM\u window\u DELETE
之外,您还需要监听并处理
ClientMessage
事件。显示您的代码。WM\u window\u DELETE
。添加了事件循环代码-我已经在寻找ClientMessage。关闭窗口的动作关闭了错误,因此没有消息被删除我只使用了普通的XWindows,所以可能没有弹出窗口或瞬态。我在代码中添加了SetWMProtocols,这似乎就是我所缺少的。为什么默认情况下你必须这样做?奇怪的是……我还注意到std::cout的行为和我预期的不一样。有时它工作正常,有时它只是等待程序运行到c无法输出到终端或等待随机时间段。这与Xlib有关吗?
SetWMProtocols
是必需的,因为没有明确的通知,窗口管理器无法对任何特定客户端的功能进行假设。仅请求
Atom
实际上没有任何作用原子本身就是一个资源的句柄。
std::cout
是一个缓冲流。
std::cerr
充当一个无缓冲流。当你想刷新输出流时,你也可以继续使用
std::cout
并调用
std::flush
。@MyTagel:只是一个简单的问题:什么是
atom