backgroundopacityxlib

how to change window background opacity with xlib?


How to change window background opacity with xlib ? But dont change window foreground. Compositor have run and XServer support 32 depth and TrueColor.

I have tried this:

unsigned long opacity = (unsigned long)(0x8ffffffful);
Atom NET_WM_WINDOW_OPACITY = XInternAtom(display, "_NET_WM_WINDOW_OPACITY", False);
XChangeProperty(display, win, NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1L);

But it will change both background and foreground. I have also tried this:

unsigned long opacity = (unsigned long)(0x8ffffffful);
XSetWindowAttributes attr;
attr.colormap = new_colormap;
attr.background_pixel = opacity;
XChangeWindowAtrributes(display, win, CWColormap | CWBackPixel, &attr);

But it report BadMatch error. I think it have different Visual.

So how to change window background opacity with xlib ?


Solution

  • If you have a composite manager, then setting the color value of the background pixel should be sufficient. You have to make sure to have a TrueColor, 32-bit visual.

    The window manager hint NET_WM_WINDOW_OPACITY sets the overall transparency of the window (that would include everything within the window), so basically after all rendering has been done, every pixel gets multiplied by the opacity value.

    The following example looks for a 32-bit visual and creates a semi transparent window (by only setting the background pixel).

    e.g.

    #include <X11/X.h>
    #include <X11/Xlib.h>
    #include <X11/Xutil.h>
    
    #include <stdlib.h>
    
    int main()
    {
        Display *dpy = XOpenDisplay(NULL);    //default display
        Window root = DefaultRootWindow(dpy); //default root window
    
        //visual info
    
        XVisualInfo vinfo;
        XMatchVisualInfo(
            dpy,                //display
            DefaultScreen(dpy), //default screen
            32,                 //32-bit depth
            TrueColor,          //class
            &vinfo              //a valid visual on success
        ); //don't forget to check the result!
        
        //window attributes
    
        XSetWindowAttributes xattr;
        xattr.background_pixel  = 0x7f7f7f7f; //normally you'd have to use 
                                              //the color shift masks of the visual
                                              //for our simple example, 
                                              //we set all values to 0.5
        xattr.background_pixmap = None;
        xattr.border_pixel      = 0;
        xattr.colormap          = XCreateColormap(dpy, root, vinfo.visual, AllocNone);
    
        long xattr_mask = (
            CWBackPixmap  |
            CWBackPixel   |
            CWBorderPixel |
            CWColormap
        );
    
        //window
    
        Window win = XCreateWindow(
            dpy,               //display
            root,              //root window
            0, 0,              //pos
            640, 480,          //size
            0,                 //border
            32,                //depth
            InputOutput,       //class
            vinfo.visual,      //visual
            xattr_mask, &xattr //attributes
        );
        XMapWindow(dpy, win);
    
        while (1) {
            XEvent evt;
            XNextEvent(dpy, &evt);
        }
    
        //cleanup
    
        XDestroyWindow(dpy, win);
        XCloseDisplay(dpy);
    
        return 0;
    }