开发者

X11/Xlib: Create "GlassPane"-Window

I've tried to create a fully transparent window using C++ & X11. It should not consume any events and simply forwards them to the windows below. Some kind of GlassPane as it's known for Java-Windows, but full screen. Then I'd like to draw on this window.

Is this somehow possible with X11?

My first attempt was ignoring all events, simply copy the image from the root window using XGetImage()... But first of all, this is quite slow as the window would need to be full screen. XShmGetImage unfortunately isn't an option here.

For sure, this window wouldn't need any decoration, but that isn't a big problem.

How to do this using X11 / Xlib only? If it's not possible, what else do I need?

Any help is appreciated!

PS: Xi开发者_StackOverflownerama is activated as well as Compiz, if that brings problems I could live deactivating them.


You can create an output-only window by setting its input shape to empty.

The API is XFixesSetWindowShapeRegion() and you can set ShapeInput separately from ShapeBounding. XFixesCreateRegion() is used to get a region to pass in.

Then you need an RGBA (with-alpha-channel) visual so you can draw transparent pixels into most of the window.

A compositing window manager will be required in order for the transparency to work.


You need overlay visual support for this in you X Server, or else performance will be absolutely abysmal, since you'd have to map / unmap your window continuously and/or do the get/putimage dance all the time.

You have to have the main/root plane non-overlay and create an overlay visual on top of that. Everything that's clear in the overlay plane will pass the "main screen" through.

Documentation on how to do this in "plain X" is very sparse, the simpler way would be via OpenGL / GLX, http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml - simply try:

int query[] = { /* GLX_RGBA, */ GLX_LEVEL, 1, 0 };
overlayVisual = glXChooseVisual(mydisplay, DefaultScreen(mydisplay), query);
myWindow = XCreateWindow(..., overlayVisual, ...);

Then You should be able to clear the window to make the "main root" visible, and draw into it to cover it. In "olden times" the overlay often was required to be a non-RGB (color indexed / palettized) visual and chroma keying was used for the transparent parts. OpenGL RGBA should support transparency / blending via the alpha channel, though ...

I haven't tried, my current framebuffer doesn't support overlays. Nvidia mentions them in the documentation for their X11 drivers / their config files hence I assume they're still around, and still usable in this fashion.


Xlib/X11 has an atom that performs this perfectly: "_NET_WM_WINDOW_OPACITY"

void ApplyAlpha (Display* display, Window window, byte Alpha)
  {
    int Alpha_;
    //
    Alpha_ = Alpha | Alpha << 8 | Alpha << 16 | Alpha << 24;
    if (Alpha == 0xFF)
      XDeleteProperty (display, window, XInternAtom (display, "_NET_WM_WINDOW_OPACITY", 0));
    else
      XChangeProperty (display, window, XInternAtom (display, "_NET_WM_WINDOW_OPACITY", 0),
                       XA_CARDINAL, 32, PropModeReplace, (byte *) &Alpha_, 1);
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜