X11/Xlib:创建“GlassPane”-窗口

发布于 2024-10-05 01:57:46 字数 419 浏览 8 评论 0原文

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

这对于 X11 来说是可能的吗?

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

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

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

任何帮助表示赞赏!

PS:XineramaCompiz 都已激活,如果这带来问题,我可以停用它们。

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: Xinerama is activated as well as Compiz, if that brings problems I could live deactivating them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滴情不沾 2024-10-12 01:57:46

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

API 为 XFixesSetWindowShapeRegion(),您可以将 ShapeInputShapeBounding 分开设置。 XFixesCreateRegion() 用于获取要传入的区域。

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

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

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.

深爱成瘾 2024-10-12 01:57:46

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

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.

情话难免假 2024-10-12 01:57:46

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);
  }

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);
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文