为什么在xlib中MapNotify发送得太早

问题描述 投票:0回答:1

我第一次在 C 中使用 xlib,而不是 C++。我想在屏幕上绘制一个测试框,但我必须等待 xorg 创建窗口。我有一个 MapNotify 回调,它被提前调用。我添加了 3 秒的延迟,3 秒后盒子就画好了。这个解决方案显然只是为了测试,但是我无法让回调正常工作。

代码(注意我的延迟被注释了,注释时函数停止工作)

#include <time.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define white 0xFFFFFF
#define black 0

#define red 0xFF0000
#define green 0xFF00
#define blue 0xFF

void delay(unsigned int millis) {
    clock_t start = clock();
    while(clock() < start + millis);
}

int main(int argc, char** argv) {
    Display* dpy = XOpenDisplay(NULL); // Get default display
    if(dpy == NULL) {
        fprintf(stderr, "Cannot open display\n");
        return 1;
    }

    Window win = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy), 0, 0, 800, 800, 0, 0, black); // Make a """simple""" window

    XMapWindow(dpy, win);
    XSelectInput(dpy, win, StructureNotifyMask); // Get MapNotify events

    GC gc = XCreateGC(dpy, win, 0, 0);
    if(gc == NULL) {
        fprintf(stderr, "Failed to make a GC\n");
        return 1;
    }

    XSetBackground(dpy, gc, white);
    XSetForeground(dpy, gc, white);
    XSync(dpy, true);

    while(true) { // Await for screen, TODO this is called too early for some reason
        XEvent e;
        XNextEvent(dpy, &e);
        printf("Got event: %d\n", e.type);
        if(e.type == MapNotify)
            break;
    }
    //delay(3000);

    XFillRectangle(dpy, win, gc, 5, 5, 100, 100);
    XFlush(dpy);

    while(true) { // Await for window close, this doesn't actually work but I don't care for now
        XEvent e;
        XNextEvent(dpy, &e);
        if(e.type == UnmapNotify)
            return 0;
    }
}

c x11 xlib xorg
1个回答
0
投票

根据您上面的后续评论,我认为以下声明(来自XMapWindow)确实最好地回答了这个问题:

如果窗口是一个InputOutput窗口,XMapWindow()会在它导致显示的每个InputOutput窗口上生成Expose事件。

如果客户端映射并绘制窗口并且客户端开始处理事件,则窗口将被绘制两次。为了避免这种情况,首先请求 Expose 事件,然后映射窗口,以便客户端照常处理输入事件。

事件列表将包括屏幕上出现的每个窗口的“Expose”。 客户端对 Expose 事件的正常响应应该是重新绘制窗口。这种方法通常会导致程序更简单并与窗口管理器进行正确的交互。

© www.soinside.com 2019 - 2024. All rights reserved.