代码之家  ›  专栏  ›  技术社区  ›  jsr

如何在XLib中创建半透明白色窗口

  •  9
  • jsr  · 技术社区  · 8 年前

    我想在XLib中创建一个半透明的白色窗口,但该窗口不是半透明的,它保持完全不透明。我使用康普顿合成器,系统中有透明窗口,因此问题在于代码:

    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
        Display* display = XOpenDisplay(NULL);
    
        XVisualInfo vinfo;
    
        XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo);
    
        XSetWindowAttributes attr;
        attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
        attr.border_pixel = 0;
        attr.background_pixel = 0x80ffffff;
    
        Window win = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 200, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr);
        XSelectInput(display, win, StructureNotifyMask);
        GC gc = XCreateGC(display, win, 0, 0);
    
        Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
        XSetWMProtocols(display, win, &wm_delete_window, 1);
    
        XMapWindow(display, win);
    
        int keep_running = 1;
        XEvent event;
    
        while (keep_running) {
            XNextEvent(display, &event);
    
            switch(event.type) {
                case ClientMessage:
                    if (event.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", 1) && (Atom)event.xclient.data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", 1))
                        keep_running = 0;
    
                    break;
    
                default:
                    break;
            }
        }
    
        XDestroyWindow(display, win);
        XCloseDisplay(display);
        return 0;
    }
    
    2 回复  |  直到 8 年前
        1
  •  14
  •   n. m. could be an AI    8 年前

    X11期望 预乘 here 当所有东西都被预乘时,计算量会减少。

    因此,您需要将每个R、G和B通道乘以alpha值(0x80)并除以256。

    将背景设置为0x808080可获得所需结果:

    注意:结果与@patthoyts的建议不同:这里只有窗户本身是半透明的,WM装饰保持不透明;在那里,窗户本身和装饰都由WM透明(WM进行必要的颜色混合)。

        2
  •  2
  •   patthoyts    8 年前

    您需要设置_NET_WM_WINDOW_OPACITY。以下是在映射窗口之前要添加的代码片段:

    double alpha = 0.8;
    unsigned long opacity = (unsigned long)(0xFFFFFFFFul * alpha);
    Atom XA_NET_WM_WINDOW_OPACITY = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False);
    XChangeProperty(display, win, XA_NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
                    PropModeReplace, (unsigned char *)&opacity, 1L);
    

    注意:您应该添加 #include <X11/Xatom.h> 以获得XA_ CARDINAL的声明。

    我不完全确定这个接口有多稳定 Extended Window Manager Hints 规范,但据我所见,还没有最终修订。我知道这是怎么回事 Tk implements transparency support 但在unix上。

    结果如下:

    transparent X11 window over editor