我想在所有其他窗口之上绘制某种窗口。例如,显示一些调试信息(如conky)或类似计时器的事情。
主要的是我希望能够在使用时继续使用其他窗口(事件透明地进行)。
我已尝试使用pygtk
,pyqt
和其他人进行此操作,但无法找到一种方法使其成为真正的叠加层而不会捕获事件。
是否有一些低级x11解决方案?
答案 0 :(得分:2)
我认为复合扩展方法在合成管理器运行时不起作用(因此已经使用了Composite的叠加窗口)。
由于您明确提及"没有事件捕获":
SHAPE extension允许为窗口设置一些不同的形状。此扩展的1.1版添加了"输入"形状。只需将其设置为空白区域,就可以完全按照自己的意愿进行操作。
我认为你要求的一些具体例子可以在Conky的源代码中找到:http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
编辑:既然你说你在Gtk中找不到任何东西(好吧,PyGtk),这就是你在Gtk中需要的功能:https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
答案 1 :(得分:1)
您可能需要Composite extension + GetOverlayWindow请求:
协议版本0.3添加了复合叠加窗口,其中 为合成管理者提供一个无需绘制的表面 干扰。此窗口始终高于正常窗口 屏幕保护程序窗口下方。它是一个InputOutput窗口,其宽度 和高度是屏幕尺寸。它的视觉是根视觉 它的边界宽度为零。试图使用。重定向它 复合扩展被忽略。此窗口不会出现在 QueryTree请求的回复。它也是一个覆盖重定向 窗口。最后两个功能使窗口管理器不可见 和其他X11客户端。访问此窗口的XID的唯一方法 是通过CompositeGetOverlayWindow请求。最初,复合材料 覆盖窗口未映射。
CompositeGetOverlayWindow返回Composite Overlay的XID 窗口。如果窗口尚未映射,则由此映射 请求。调用此请求的所有客户端都已终止 他们的X11连接窗口未映射。
复合管理器可以直接渲染到复合叠加层 窗户,或者他们可能重新将其他窗户重新成为这个孩子 窗口并渲染到这些。多个客户端可能会呈现给 复合叠加窗口,创建它的子窗口,重塑它,和 重新定义其输入区域,但遵循特定的仲裁规则 本规范未定义这些客户端;这些政策 应该由客户自己定义。
答案 2 :(得分:1)
PyGTK解决方案:
我认为Composite和shape X扩展已经足够普遍了,在此应假定它们在您的系统上是活动的。这是此的PyGtk代码:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
基本上,这是告诉Gtk,从事件传播的角度来看,整个窗口my_window
除了像素(0,0)之外,不应被视为其一部分。按照我目前的理解,这反过来意味着,当指针移动并单击时,事件将进入指针位置下方的基础窗口,就像my_window
不在那里一样。
注意事项:
这确实使您的叠加窗口成为焦点窗口(由于用户请求的窗口切换,或者仅因为它在应用程序启动时弹出并获得焦点)。这意味着,例如,键盘事件仍然会不合要求地进行下去,直到用户单击它以使其失去焦点而转向光标下方的任何窗口为止。我可能会使用here中描述的方法来解决此问题。
如果有一种使屏幕的一部分“显示内容但不接收事件”的正确方法,却又没有在上方构建奇异球窗口的话,我很乐意学习。
我假定在某些情况下,取决于版本和配置,一个人的特定桌面环境(Linux上的gnome,Unity等)可能会干扰此解决方案。