透明Xlib窗口的点击穿透

14

我有一个透明的、水印式的应用程序,使用C语言中的XLib编写。目前,如果你在应用程序的任何地方单击,什么也不会发生,但我希望它可以将鼠标输入传递到下面的任何内容上。例如:如果你单击下面应用程序下的关闭窗口的“X”按钮,它应该关闭应用程序,而不是什么都不做。

5个回答

4

好的,这是我找到的内容

请注意,这个功能是在最近十年中添加的,所以如果你有一个旧版本的X11,这可能会起作用或者不起作用。

首先将以下内容包含到你的项目中,因为它们是必需的:

#include <X11/extensions/shape.h>
#include <X11/extensions/Xfixes.h>

如果要更改输入几何图形(也就是您可以与窗口交互的地方),在这种情况下,我们将其设置为0 x 0像素,这意味着没有任何交互。以下是一个示例:

XRectangle rect;
XserverRegion region = XFixesCreateRegion(display, &rect, 1);
XFixesSetWindowShapeRegion(display, window, ShapeInput, 0, 0, region);
XFixesDestroyRegion(display, region);

并将此添加到项目链接器中 -lXfixes


2
如果您不希望“水印”窗口接收任何输入,而是将输入发送到它下面的窗口,则可以考虑查看 gtk_widget_input_shape_combine_region 的实现。我之前使用其前身 gtk_widget_input_shape_combine_mask 以使弹出窗口的所有部分都不接收任何事件。
我有点跑题了,但是似乎 XShapeCombineRectangles 是相关的调用(链接的 do_shape_combine_region 在这种情况下使用 shape = ShapeInput)。

我尝试使用GDK窗口,但这并没有起作用。 - u_Ltd.
当我尝试在xlib窗口上运行它时,它可以正常工作(甚至满足了您可以单击“X”关闭底层窗口的要求)。 - u_Ltd.

1
我认为XQueryTree可能会有所帮助。将其执行到根窗口上,获取子窗口列表,找到它们的位置并将鼠标/键盘的XEvent传递给相应的窗口。
注意:您需要注意活动/非活动窗口、窗口的活动/非活动区域、另一个窗口的子窗口、其他窗口的大小和x/y位置。这段代码可能会很混乱。

那么我会使用 XQueryTree 获取窗口 ID,然后使用 XGetWindowAttributes 检查重叠情况。如果存在重叠,我会将鼠标事件发送到该窗口。还有一个问题,如何将鼠标事件发送或传递给该窗口? - Corey
1
请查看以下内容:'http://stackoverflow.com/questions/14656615/xlib-xsendevent-click-event-do-not-work-inside-of-some-windows-on-ubuntu-12-04?rq=1' 和 'http://www.semicomplete.com/blog/geekery/xsendevent-xdotool-and-ld_preload.html' - bikram990
我能够使用XQueryTree选择正确的窗口,但是我在向窗口发送适当的事件时遇到了麻烦。我想发送FocusChangeEvent和可能的ButtonPressEvent,但我还没有成功地完成任何一个。有人有好的XSendEvent示例吗? - Corey
请将此作为一个新问题提出。 - bikram990

0
  1. 你需要实现一个小窗口管理器,它将使用XSelectInput监听默认根窗口上的所有事件。

  2. 然后在fd = connectionNember(display)上进行轮询。

  3. 每当你收到事件时,请检查它是否是鼠标事件,它会给你x、y。你可以通过遍历窗口堆栈找到正确的窗口。

  4. 然后使用XGrabPinter将事件报告给底层窗口。


0

一些额外的注意事项:

  • 如果您想在 xcb 中执行此操作,请确保首先查询 xfixes 版本 5.0,否则您将收到一个模糊的 BadRequest 错误
  • 这里有一种替代方法(从 picom source 偷来的,他又从 compiz source 偷来了 ☺)
xcb_shape_mask(conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, window, 0, 0, 0);
xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, XCB_CLIP_ORDERING_UNSORTED, window, 0, 0, 0, NULL);

关于它是如何工作的,我一点头绪也没有。XShape 是出了名的没有文档说明。不过结果似乎是一样的。

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