Xlib的:关闭窗口总是导致致命IO错误? [英] Xlib: Closing window always causes fatal IO error?

查看:813
本文介绍了Xlib的:关闭窗口总是导致致命IO错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么会这样,但我创建C ++使用Xlib的任何窗口可以输出一个错误的终端,当我尝试使用的X按钮来关闭。我可以没有错误编程关闭它,它只是在X按钮做的。

该错误是:

X服务器上的致命IO错误11(资源暂时不可用):

  XIO0
经过483请求(483已知处理)跟0个事件剩余。

请求的数量每次都是不同的,但总有剩余0的事件。为什么会这样?其原因似乎并没有成为我的code,因为它这样做无论什么和不发送关闭事件队列。我试图拦截了Atom WM_WINDOW_DELETE,它不超预期的code运行时,我关闭该窗口。

编辑:新增的事件循环code

 而(XPending(显示)){
    XNextEvent例行(显示器,功放及;事件);    调用pthread_mutex_unlock(安培;互斥);    如果(event.type ==暴露){
        XWindowAttributes getWindowAttributes;        调用pthread_mutex_lock(安培;互斥);        XGetWindowAttributes(显示屏,窗口,&安培; getWindowAttributes);        如果(state.currentState == STATE_NORMAL){
            state.normX = getWindowAttributes.x;
            state.normY = getWindowAttributes.y;
            state.normWidth = getWindowAttributes.width;
            state.normHeight = getWindowAttributes.height;
        }        调用pthread_mutex_unlock(安培;互斥);        glViewport(0,0,getWindowAttributes.width,getWindowAttributes.height);
    }否则如果(event.type ==重点preSS){
        返回false;
    }否则如果(event.type == ClientMessage){
        性病::法院LT&;<X按钮pressed<<的std :: ENDL; //的X ING窗口时从不运行
        如果(event.xclient.message_type == XInternAtom(显示,WM_DELETE_WINDOW,真)){
            返回false;
        }
    }否则如果(event.type ==按钮preSS){
        如果(state.currentState!= STATE_FULLSCREEN){
            全屏();
        }其他{
            正常化();
        }
    }否则如果(!的handleEvent(事件)){
        返回false;
    }    调用pthread_mutex_lock(安培;互斥);
}


解决方案

在除了 WM_WINDOW_DELETE 你需要侦听和处理 ClientMessage 事件。

修改从罗塞塔code 中的例子来说明:

 的#include< X11 / Xlib.h>
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;诠释主要(无效){
    显示* D;
    窗W;
    XEventê;
    为const char *味精=你好,世界!
    int类型;    D = XOpenDisplay(NULL);
    如果(D == NULL){
        fprintf中(标准错误,无法打开显示屏\\ n);
        出口(1);
    }    S = DefaultScreen(四);
    W = XCreateSimpleWindow(D,RootWindow(D,S),10,10,100,100,1,BlackPixel(D,S),WhitePixel(D,S));
    XSelectInput(D,W,ExposureMask |重点pressMask);
    XMapWindow(D,w)的;    //我支持WM_DELETE_WINDOW协议
    原子WM_DELETE_WINDOW = XInternAtom(DWM_DELETE_WINDOW,FALSE);
    XSetWMProtocols(D,W,&放大器; WM_DELETE_WINDOW,1);    而(1){
        XNextEvent例行(D,急症室);
        如果(e.type ==暴露){
            XFillRectangle(D,W,DefaultGC(D,S),20,20,10,10);
            XDrawString(D,W,DefaultGC(D,S),10,50,味精,strlen的(MSG));
        }
        否则,如果(e.type ==重点preSS)
            打破;
        否则,如果(e.type == ClientMessage)
            // TODO应检查这里其他客户端的消息类型 -​​
            然而//如上注册的唯一协议是WM_DELETE_WINDOW
            //这是这个小例子是安全的。
            打破;
    }    XCloseDisplay(四);
    返回0;
}

I'm not sure why this happens, but any window I create using Xlib in C++ gives outputs an error to the terminal when I try to close is using the X button. I can close it programmatically with no errors, it's just the X button that does it.

The error is the following:

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0"
after 483 requests (483 known processed) with 0 events remaining.

The number of requests is different every time, but there's always 0 events remaining. Why does this happen? The cause doesn't seem to be my code, since it does this no matter what and sends no close events to the queue. I've tried intercepting the Atom WM_WINDOW_DELETE, and it doesn't run over the expected code when I close the window.

Edit: Added event loop code.

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);
}

解决方案

In addition to WM_WINDOW_DELETE you need to listen for and handle the ClientMessage event.

Modifying the example from Rosetta Code to illustrate:

#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;
}

这篇关于Xlib的:关闭窗口总是导致致命IO错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆