X11 - 如何使用 Python 引发另一个应用程序的窗口
I'd like to be able to raise another application's Window using Python.
I did see this, which I suppose I could try:
X11: raise an existing window via command line?
However, I'd prefer to do it in Python if at all possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
要激活另一个窗口,在 Xlib 协议层上正确的做法是发送 _NET_ACTIVE_WINDOW 消息,如 EWMH 规范中所述
http://standards.freedesktop.org/wm-spec/wm-spec -1.3.html
这可以通过 python-xlib (大概)或通过 pygtk 使用 GDK 在外国 GdkWindow 上使用 gdk_window_focus() 来完成
_NET_ACTIVE_WINDOW 优于 XRaiseWindow() 并且已经出现在许多重要的 WM 中年。
您应该避免 XSetInputFocus() ,这会导致问题(特别是如果您的时间戳错误)。问题是 WM 无法拦截 SetInputFocus(),因此会导致奇怪的竞争条件和 UI 不一致。
实际上只有 _NET_ACTIVE_WINDOW 可以正常工作,这就是它被发明的原因,因为以前的 hack 很糟糕。
有一个名为 libwnck 的库,可以让您激活窗口(除其他外),但不幸的是,它增加了相当多的开销,因为它总是跟踪任何应用程序中所有打开的窗口,即使您不需要这样做。但是,如果您想从其他应用程序跟踪窗口,无论如何,那么 libwnck 有一个函数可以激活那些执行正确操作的窗口,这将是一个不错的选择。
严格正确的方法是检查 EWMH _NET_ACTIVE_WINDOW 支持(EWMH 文档说明了如何执行此操作),如果 WM 没有 _NET_ACTIVE_WINDOW,则回退到 XRaiseWindow。然而,由于过去许多年积极开发的 WM 都具有 EWMH,因此许多人对传统 WM 的回退感到懒惰。
To activate another window, the right thing to do on the Xlib protocol layer is to send a _NET_ACTIVE_WINDOW message as described in the EWMH spec
http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html
This could be done with python-xlib (presumably) or with gdk_window_focus() on a foreign GdkWindow using GDK through pygtk
_NET_ACTIVE_WINDOW is superior to XRaiseWindow() and has been in all the important WMs for many many years.
You should avoid XSetInputFocus() which will cause problems (especially if you get the timestamp wrong). The issue is that the WM can't intercept the SetInputFocus() so it causes weird race conditions and UI inconsistencies.
Really only _NET_ACTIVE_WINDOW works properly, which is why it was invented, because the previous hacks were bad.
There is a library called libwnck that will let you activate windows (among other things) but unfortunately it adds quite a lot of overhead because it always tracks all open windows from any app, even if you don't need to do that. However if you want to track windows from other apps anyway, then libwnck has a function to activate those windows that does the right thing and would be a good choice.
The strictly correct approach is to check for EWMH _NET_ACTIVE_WINDOW support (EWMH documents how to do this) and fall back to XRaiseWindow if the WM doesn't have _NET_ACTIVE_WINDOW. However, since any WM that's been actively worked on in the last many years has EWMH, lots of people are lazy about the fallback for legacy WMs.
您可以查看python ewmh 包。 文档包含示例,但以下是实现您想要的效果的方法:
You can have a look at the python ewmh package. Documentation contains examples, but here is how you can achieve what you want:
您需要使用 python-xlib 并调用
.circulate(Xlib.X.RaiseLowest)< /code> 窗口对象(可以通过很多很多不同的方式来识别 - 无法从 Q 中有关它的零信息中猜测哪一个适合您;-)。有关使用
python-xlib
的绝佳示例,请查看 tinywm 窗口管理器-- 在 C 版本之后,作者给出了一个 Python 版本,该版本需要大约 30 个非空白、非注释行(对于一个可用的,虽然很小的窗口管理器...!-)。You need to use python-xlib and call
.circulate(Xlib.X.RaiseLowest)
on the window object (which can be identified in many, many different ways -- can't guess which one is appropriate for you from the zero amount of info about it in your Q;-). For a great example of usingpython-xlib
, check out the tinywm window manager -- after the C version, the author gives a Python version that takes about 30 non-blank, non-comment lines (for a usable, if tiny, window manager...!-).使用 python-xlib:
Using python-xlib: