9

我想在屏幕上所有窗口的顶部绘制一些图元。我在 C 中找到了一些代码并尝试将其移植到使用 python 的 xlib:

from Xlib.display import Display
from Xlib import X
from Xlib import protocol

display = Display(':0')
root = display.screen().root
gc = root.create_gc()
root.fill_rectangle(gc, 100, 100, 500, 500)

但是屏幕上什么也没有出现(但是,分配了根窗口:在它工作后抓取键盘)。如何正确执行此操作?

4

1 回答 1

6

您可以在根窗口上绘图 - 您的代码可能有效,但根窗口可能会被某种桌面窗口(nautilus、kde 桌面等)遮挡。尝试在不运行任何程序的情况下启动 X 会话,您将看到更新(您可以使用 Xephyr 或 Xnest)

另一种方法是创建透明窗口,使其位于最顶部并在其表面上绘制。您需要手动将鼠标事件传播到底层窗口。

要在所有窗口上实际绘制,您需要创建简单的复合管理器,或者如果已经有 CM 正在运行,请使用它的覆盖窗口。

复合协议规范

该协议的 0.3 版添加了 Composite Overlay Window,它为合成管理器提供了一个可以在不受干扰的情况下在其上绘制的表面。此窗口始终位于普通窗口之上,并且始终位于屏幕保护程序窗口之下。它是一个 InputOutput 窗口,其宽度和高度是屏幕尺寸。它的视觉是根视觉,其边框宽度为零。尝试使用复合扩展对其进行重定向将被忽略。此窗口不会出现在 QueryTree 请求的回复中。它也是一个覆盖重定向窗口。最后两个特性使它对窗口管理器和其他 X11 客户端不可见。访问此窗口的 XID 的唯一方法是通过 CompositeGetOverlayWindow 请求。最初,复合叠加窗口未映射。

CompositeGetOverlayWindow 返回复合叠加窗口的 XID。如果窗口还没有被映射,它被这个请求映射。当所有调用此请求的客户端都终止了它们的 X11 连接时,该窗口将被取消映射。

复合管理器可以直接渲染到复合覆盖窗口,或者它们可以将其他窗口重新设置为该窗口的子窗口并渲染到这些窗口。多个客户端可以渲染到复合覆盖窗口,创建它的子窗口,重塑它,重新定义它的输入区域,但是这些客户端遵循的具体仲裁规则在本规范中没有定义;这些策略应由客户自己定义。

于 2013-01-11T00:46:40.840 回答