Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XRender Create Offscreen Picture

Tags:

c++

x11

xlib

I'm trying to create a compositing window manager. So far it works, but when a window overlays another, it flickers like crazy. I found that it was because I was creating a Picture, and then painting to it, which caused it to paint to the screen.

My desired behaviour would be to have an offscreen Picture that I can draw to, and then use XComposite to draw that to an onscreen window. Is there any way to have an offscreen Picture that is the same size as the root window?

So far (this code runs in an infinite loop thingy):

Window root, parent, *children;
uint children_count;
XQueryTree(disp, DefaultRootWindow(disp), &root, &parent, &children, &children_count);

// I'd like the following picture to be offscreen.
// I suspect that I have to put else something where rootPicture is
// Currently, when I draw to this picture, X11 renders it to the screen immediately, which is what I don't want.
Picture pictureBuf = XRenderCreatePicture(disp, /* rootPicture */, XRenderFindVisualFormat(disp, DefaultVisual(disp, DefaultScreen(disp))), CPSubwindowMode, &RootAttributes);

for (uint i = 0; i < children_count; i++) {
    // collapsed some stuff that doesn't matter
    Picture picture = XRenderCreatePicture(disp, children[i], pictureFormat, CPSubwindowMode, &pictureAttributes);

    // The following line should composite to an offscreen picture
    XRenderComposite(disp, hasAlpha ? PictOpOver : PictOpSrc, picture, None, pictureBuf, 0, 0, 0, 0, windowRect.x(), windowRect.y(), windowRect.width(), windowRect.height());
    // collapsed some stuff that doesn't matter
}

// The following line should composite from the offscreen picture to an onscreen picture
XRenderComposite(disp, PictOpSrc, pictureBuf, None, rootPicture, 0, 0, 0, 0, RootAttr.x, RootAttr.y, RootAttr.width, RootAttr.height);
like image 910
Victor Tran Avatar asked Nov 09 '22 03:11

Victor Tran


1 Answers

I was recently looking into something similar and figured I'd reply. The below fragment of code shows how you would create new pixmap from an existing window without drawing directly to that window. Hopefully this helps.

Pixmap new_pixmap;
new_pixmap = XCompositeNameWindowPixmap( display, src_window);
Drawable draw = new_pixmap;
if (!draw) draw = src_window;
Picture origin;
origin = XRenderCreatePicture( display, draw, format, CPSubWindowMode, &attributes);
like image 172
AcidTonic Avatar answered Dec 16 '22 11:12

AcidTonic