5

我尝试使用 C++ 和 X11 创建一个完全透明的窗口。它不应该消耗任何事件,而只是将它们转发到下面的窗口。某种以 Java-Windows 闻名的 GlassPane,但全屏显示。然后我想在这个窗口上画画。

这对 X11 有可能吗?

我的第一次尝试是忽略所有事件,只需使用...从根窗口复制图像XGetImage()。但首先,这很慢,因为窗口需要全屏显示。XShmGetImage不幸的是,这里不是一个选择。

当然,这扇窗户不需要任何装饰,但这不是什么大问题。

如何仅使用 X11 / Xlib 做到这一点?如果不可能,我还需要什么?

任何帮助表示赞赏!

PS:Xinerama也被激活了Compiz,如果这带来了问题,我可以将它们停用。

4

3 回答 3

5

您可以通过将其输入形状设置为空来创建仅输出窗口。

API 是XFixesSetWindowShapeRegion(),您可以ShapeInputShapeBounding. XFixesCreateRegion()用于获取要传入的区域。

然后,您需要一个 RGBA(带 alpha 通道)视觉效果,以便您可以将透明像素绘制到大部分窗口中。

为了使透明度起作用,需要一个合成窗口管理器。

于 2010-12-01T19:01:55.620 回答
4

您需要在 X 服务器中对此进行叠加视觉支持,否则性能将绝对糟糕透顶,因为您必须不断地映射/取消映射窗口和/或一直进行 get/putimage 舞蹈。

您必须使主/根平面不叠加,并在其上创建叠加视觉。覆盖平面中清晰的所有内容都将通过“主屏幕”。

关于如何在“plain 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 驱动程序/他们的配置文件的文档中提到了它们,因此我认为它们仍然存在,并且仍然可以以这种方式使用。

于 2010-12-01T17:13:38.943 回答
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);
  }
于 2021-09-16T01:47:03.860 回答