5

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);
Victor Tran
  • 516
  • 4
  • 16
  • Could you not draw in a buffer in memory and copy that? – user3853544 Jan 27 '17 at 19:30
  • @user3853544 That's sort of what I'm trying to do. I don't know how I'd go about doing it though. :) – Victor Tran Jan 29 '17 at 09:52
  • I've never used this library but usually its along the line of SomeBitmapType img(width, height); Then copy that into your image. – user3853544 Jan 30 '17 at 10:37
  • @user3853544 There doesn't seem to be any function in this library that can do that. A ```Picture``` is a typedef for an ```XID```, which itself is a typedef for an ```unsigned long```. – Victor Tran Feb 02 '17 at 10:33

1 Answers1

1

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);
AcidTonic
  • 171
  • 1
  • 7