【问题标题】:Draw on top of the screen using xlib使用 xlib 在屏幕顶部绘制
【发布时间】:2012-12-21 10:50:19
【问题描述】:

我想在屏幕上所有窗口的顶部绘制一些图元。我在 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)

但是屏幕上什么也没有出现(但是,根窗口被分配:在它工作后抓取键盘)。如何正确地做到这一点?

【问题讨论】:

  • 除非您正在编写窗口管理器,否则编写 X 根目录是一个非常糟糕的主意。从其他所有内容中窃取输入焦点是执行此操作的应用程序多么“粗鲁”的一个示例。我会在您使用的任何 GUI 工具包中寻找“模态对话框”。
  • @msw:我写的不是窗口管理器,而是另一个低级应用程序,所以真的有必要在所有窗口之上绘制。

标签: python unix drawing xlib xorg


【解决方案1】:

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

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

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

来自composite protocol spec:

0.3 版协议增加了复合覆盖窗口,它 为合成管理器提供一个无需在其上进行绘制的表面 干涉。这个窗口总是在普通窗口之上并且总是 屏幕保护程序窗口下方。它是一个 InputOutput 窗口,其宽度 和高度是屏幕尺寸。它的视觉是根视觉 并且它的边框宽度为零。尝试使用 复合扩展被忽略。此窗口不会出现在 QueryTree 请求的回复。它也是一个覆盖重定向 窗户。最后两个功能使其对窗口管理器不可见 和其他 X11 客户端。访问此窗口 XID 的唯一方法 是通过 CompositeGetOverlayWindow 请求。最初,复合 覆盖窗口未映射。

CompositeGetOverlayWindow 返回 Composite Overlay 的 XID 窗户。如果窗口还没有被映射,它被这个映射 要求。当所有调用此请求的客户端都已终止 他们的 X11 连接窗口未映射。

复合管理器可以直接渲染到复合叠加层 窗口,或者它们可能将其他窗口重新设置为该窗口的子级 窗口并渲染到这些。多个客户端可能会呈现给 Composite Overlay Window,创建它的子窗口,重塑它,并 重新定义其输入区域,但遵循特定的仲裁规则 本规范未定义这些客户端;这些政策 应该由客户自己定义。

【讨论】:

  • 不幸的是,xlib 文档很糟糕,虽然它似乎实现了复合扩展,但没有指导如何使用它。
  • 在覆盖窗口顶部绘图(即使用 cairo)需要在每次我们想要绘制某些东西时请求和释放覆盖。但是在叠加层上绘制图像后,它将在几毫秒内消失。似乎我们需要某种通知(“expose”事件?)用于复合覆盖窗口,以便知道何时允许我们在其上绘图。
猜你喜欢
  • 2019-10-03
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
相关资源
最近更新 更多