Xlib: 창을 매핑하고 매핑 해제하기 위해 디스플레이를 꺼야 하는 이유는 무엇입니까?

Xlib: 창을 매핑하고 매핑 해제하기 위해 디스플레이를 꺼야 하는 이유는 무엇입니까?
// ...
int main(int argc, char *argv[]) {
  int rev;
  Window win;
  Display *dis = XOpenDisplay(NULL);

  XGetInputFocus(dis, &win, &rev);

  XUnmapWindow(dis, win);
  XCloseDisplay(dis);

  // ...

  dis = XOpenDisplay(NULL);
  XMapWindow(dis, win);
  XCloseDisplay(dis);

  return 0;
}

참고로, 창 매핑을 해제하기 전에 디스플레이를 꺼야 하므로 매핑하기 전에 다시 초기화해야 프로그램이 제대로 작동합니다.
여기서 무슨 일이 일어나고 있는 걸까요?

해결책:

// ...
int main(int argc, char *argv[]) {
  int rev;
  Window win;
  Display *dis = XOpenDisplay(NULL);

  XGetInputFocus(dis, &win, &rev);

  XUnmapWindow(dis, win);
  XFlush(dis); // The fix

  //...

  XMapWindow(dis, win);
  XCloseDisplay(dis);

  return 0;
}

답변1

XUnmapWindow 후에 XCloseDisplay를 호출할 필요가 없습니다. 이것이 작동하지 않는다면, 프로그램에 일부 변수를 망칠 수 있는 다른 버그가 있는 것이 틀림없습니까?

다음은 제가 빠르게 시도한 예입니다. 창의 매핑을 해제하고 매핑하며 그 사이에 XCloseDisplay/XOpenDisplay가 필요하지 않습니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
 
int main (int argc, char *argv[])
{
    Display *display;
    Window window;
    XSetWindowAttributes attributes;
    XGCValues gr_values;
    XFontStruct *fontinfo;
    GC gr_context;
    Visual *visual;
    int depth;
    int screen;
    XEvent event;
    XColor color, dummy;

    display = XOpenDisplay (NULL);
    screen = DefaultScreen (display);
    visual = DefaultVisual (display,screen);
    depth  = DefaultDepth (display,screen);
    attributes.background_pixel = XWhitePixel (display,screen);
 
    window = XCreateWindow (display, XRootWindow (display, screen), 200, 200, 350, 200, 5, depth, InputOutput, visual, CWBackPixel, &attributes);
    XSelectInput (display, window, ExposureMask | KeyPressMask) ;
    fontinfo = XLoadQueryFont (display, "6x10");

    XAllocNamedColor (display, DefaultColormap (display, screen), "red", &color, &dummy);
 
    gr_values.font = fontinfo->fid;
    gr_values.foreground = color.pixel;
    gr_context = XCreateGC (display, window, GCFont + GCForeground, &gr_values);
    XFlush (display);
    XMapWindow (display, window);
    XFlush (display);

    int keypressed = 0;
    while (!keypressed) {
        XNextEvent (display, &event);

        switch (event.type) {
            case Expose:
                XDrawLine (display, window, gr_context, 0, 0, 100, 100);
                XDrawString (display, window, gr_context, 100, 100, "hello1", 6);
                break;
            case KeyPress: 
                keypressed = 1;
                XUnmapWindow (display, window);
                XFlush (display);
                break;
        }
    }

    sleep (1);
    XMapWindow (display, window);
    XFlush (display);

    while (1) {
        XNextEvent (display, &event);

        switch (event.type) {
            case Expose:
                XDrawLine (display, window, gr_context, 50, 50, 100, 100);
                XDrawString (display, window, gr_context, 50, 50, "hello2", 6);
                break;
            case KeyPress: 
                XCloseDisplay (display); 
                exit (0);
        }
    }
}

프로그램은 사용자가 키를 누를 때까지 기다립니다. 그런 다음 매핑을 해제하고 다시 매핑합니다. 다음에 키를 누르면 종료됩니다. 그것을 컴파일하다

gcc -o programname programname.c -lX11

여기에서 가져온 샘플:http://www-h.eng.cam.ac.uk/help/tpl/graphics/X/X11R5/node21.html

관련 정보