X11/Xlib:创建“GlassPane”窗口

5
我尝试使用C++和X11创建一个完全透明的窗口。它不应该消耗任何事件,只是将它们转发到下面的窗口。就像Java-Windows中所称的GlassPane,但是全屏的。然后我想在这个窗口上绘图。
使用X11是否可能实现这一点?
我的第一次尝试是忽略所有事件,仅使用XGetImage()从根窗口复制图像...但首先,由于窗口需要全屏显示,这相当缓慢。 XShmGetImage在这里不是一个选项。
当然,这个窗口不需要任何装饰,但这不是一个大问题。
如何仅使用X11 / Xlib实现此操作?如果不可能,我还需要什么?
非常感谢您的帮助!
PS:Xinerama已激活,以及Compiz,如果这会带来问题,我可以禁用它们。
3个回答

5
你可以通过将其输入形状设置为空来创建一个仅输出窗口。
API为XFixesSetWindowShapeRegion(),你可以分别设置ShapeInputShapeBounding。使用XFixesCreateRegion()获取要传递的区域。
然后你需要一个RGBA(带alpha通道)视觉效果,这样你就可以在大多数窗口中绘制透明像素。
需要一个合成窗口管理器才能使透明度正常工作。

关于事件,使用带有空区域的XFixesSetWindowShapeRegion来设置形状输入是有效的。不错的点,谢谢! - Atmocreations
关于这个问题的另一个问题:我是否可以以任何方式拦截事件(得到通知),但不消耗它,也就是说,下面的窗口也接收到该事件?猜测使用XFixesSetWindowShapeRegion()进行ShapeInput,这可能行不通,对吧?谢谢! - Atmocreations
1
据我所知,目前没有办法“窥探”事件,很遗憾。 - Havoc P
好的。如果我需要事件,我会设置另一个区域...没问题。谢谢! - Atmocreations

4
你需要在你的X Server中使用覆盖可视化支持,否则性能将非常糟糕,因为你必须不断地映射/取消映射窗口和/或进行get/putimage操作。
你必须使主/根平面为非叠加,并在其上创建一个覆盖可视化。覆盖平面中清晰的所有内容都会透过“主屏幕”。
关于如何在“纯X”中执行此操作的文档非常稀少,更简单的方法是通过OpenGL/GLX http://www.opengl.org/sdk/docs/man/xhtml/glXChooseVisual.xml - 只需尝试:
int query[] = { /* GLX_RGBA, */ GLX_LEVEL, 1, 0 };
overlayVisual = glXChooseVisual(mydisplay, DefaultScreen(mydisplay), query);
myWindow = XCreateWindow(..., overlayVisual, ...);

然后,您应该能够清除窗口以使“主根”可见,并绘制到其中以覆盖它。在“古老的时代”,覆盖层通常需要是非RGB(颜色索引/调色板)视觉效果,并且透明部分使用色度键控。OpenGL RGBA应该通过alpha通道支持透明度/混合,但是... 我没有尝试过,我的当前帧缓冲区不支持覆盖层。 Nvidia在其X11驱动程序/配置文件文档中提到了它们,因此我认为它们仍然存在,并且仍然可以以这种方式使用。

0

Xlib/X11有一个完美执行此操作的原子: "_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);
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接