背景:我正在开发一款名为ActivityWatch的软件,用于记录您在计算机上执行的操作。基本上是尝试解决一些问题:RescueTime,selfspy,arbtt等。
我们做的核心事情之一是有关活动窗口(类和标题)的日志信息。在过去,这已经在Linux上使用xprop和现在的python-xlib而没有问题。
但现在我们遇到了一个问题: Wayland正在崛起,据我所知,Wayland没有活跃窗口的概念。因此,我担心我们必须为Wayland可用的每个桌面环境实施支持(假设它们将提供获取有关活动窗口的信息的能力)。
希望他们最终能够融合并拥有一些共同的界面来完成这项任务,但我并没有屏住呼吸......
我一直anticipating this issue。但是今天我们得到了一个真正的Wayland用户first user request for Wayland support。由于较大的发行版采用Wayland作为默认的显示服务器协议(Fedora 25已经在使用它,Ubuntu将在17.10中切换即将推出),随着时间的推移情况将变得更加重要。
ActivityWatch的相关问题:
还有其他应用程序,如ActivityWatch需要相同的功能(RescueTime,arbtt,selfspy等),它们现在似乎不支持Wayland,我找不到有关它们的任何细节计划这样做
我现在有兴趣实施支持Gnome开始,并随着路径变得更加清晰而跟进其他人。
有关韦斯顿的类似问题在这里被问到:get the list of active windows in wayland weston
编辑:我在Freenode的#wayland问道,得到了以下回复:
15:20:44 ErikBjare Hello everybody. I'm working on a piece of self-tracking software called ActivityWatch (https://github.com/ActivityWatch/activitywatch). I know this isn't exactly the right place to ask, but I was wondering if anyone knew anything about getting the active window in any Wayland-using DE.
15:20:57 ErikBjare Created a question on SO: https://stackoverflow.com/questions/45465016/how-do-i-get-the-active-window-on-gnome-wayland
15:21:25 ErikBjare Here's the issue in my repo for it: https://github.com/ActivityWatch/activitywatch/issues/92
15:22:54 ErikBjare There are a bunch of other applications that depend on it (RescueTime, selfspy, arbtt, ulogme, etc.) so they'd need it as well
15:24:23 blocage ErikBjare, in the core protocol you cannot know which windnow has the keyboard or cursor focus
15:24:39 blocage ErikBjare, in the wayland core protocol *
15:25:10 blocage ErikBjare, you can just know if your window has the focus or not, it a design choise
15:25:23 blocage avoid client spying each other
15:25:25 ErikBjare blocage: I'm aware, that's my reason for concern. I'm not saying it should be included or anything, but as it looks now every DE would need to implement it themselves if these kind of applications are to be supported
15:25:46 ErikBjare So wondering if anyone knew the teams working with Wayland on Gnome for example
15:26:11 ErikBjare But thanks for confirming
15:26:29 blocage ErikBjare, DE should create a custom extension, or use D-bus or other IPC
15:27:31 blocage ErikBjare, I guess some compositor are around here, but I do not know myself if there is such extension already
15:27:44 blocage compositor developers *
15:28:36 ErikBjare I don't think there is (I've done quite a bit of searching), so I guess I need to catch the attention of some DE developers
15:29:16 ErikBjare Thanks a lot though
15:29:42 ErikBjare blocage: Would you mind if I shared logs of our conversation in the issue?
15:30:05 blocage just use it :) it's public
15:30:19 ErikBjare ty :)
编辑2 提起enhancement issue in the Gnome bugtracker。
tl; dr:如何在使用Wayland时获取Gnome上的活动窗口?
答案 0 :(得分:2)
之前的两个答案已经过时,这是在(Gnome)Wayland中查询应用名称和窗口标题的当前状态。
特定于Gnome的API可能会在Gnome版本之间中断,但它可以工作。它在很大程度上依赖于Gnome内部API的工作,因此没有机会成为标准API。有a PR on aw-watcher-window to add this,但如果可能,它需要一些清理和afk支持。
wlr-foreign-toplevel-management协议(在撰写本文时)由Sway,Mir,Phosh和Wayfire合成器实现。与{way3合成器已广泛实现的idle.xml协议)一起,在aw-watcher-window-wayland中有一个完整的带有ActivityWatch的afk-detection的实现。我一直在与sway / rootston开发人员讨论过Wayland应用程序名称和X11 wm_class是否可互换,并且Sway和Phosh现在都可以互换使用,因此API中Wayland和XWayland窗口之间不再存在任何可区别的区别。 >
我还没有研究过KWin是否具有类似于Gnome Shell的API来获取应用程序名称和标题,但至少没有实现wlr-foreign-toplevel-management。
答案 1 :(得分:1)
在我看来,你所拥有的最佳选择不是Wayland或任何可用的图书馆(没有一个)。实际上谁知道在gnome-wayland中关于活动窗口的是Mutter,所以你需要找到一种方法来向Mutter询问活动窗口。 Gnome可以开发API以在内部要求改变活动窗口并恢复功能。但实际上,你没有地方可以要求它。 Mutter不会开发一个API来访问他的内部表示,因为这只是Mutter的特定而不是所有Wayland的Windows管理器。所以这需要添加到一个外部库中,这个库可以与当前的窗口管理器进行通信,它正在使用它来以一般方式解析您的请求。
另一个可能性是添加Wayland插件,其中所有窗口管理器将有一种方式来共享当前活动窗口,并以某种方式与库直接对话以恢复功能。
所以,你的应用程序存在很大问题。你可以做的最多是在mutter上请求这个(知道活动窗口的地方),但在我看来,它无法在Mutter中解决。
我希望这会对你有所帮助,你可以找到一种方法。好的loock。
答案 2 :(得分:-2)
我有一个名为preguiça.py
的脚本,它正是您正在做的事情,尽管它可能更简单,我还没有发布它。
对于我的脚本,我使用PyGObject的 Window Navigator Construction Kit (Wnck)获取了窗口标题。
以下是它的简化版本,以及基本部分:
from gi.repository import Wnck
from gi.repository import GObject
def changed (screen, window, data):
print ("Changed!")
# window = screen.get_active_window()
if window:
print ("Title: %s" % window.get_name())
screen = Wnck.Screen.get_default ()
screen.connect ("active-window-changed", changed, None)
mainLoop = GObject.MainLoop ()
try:
mainLoop.run ()
except KeyboardInterrupt:
print ("Hey")
mainLoop.unref ()
您所询问的实际代码实际上已在上面的示例中被注释掉(我不需要捕获窗口,因为回调已经接收到它),但您可能需要它,具体取决于您的实现。< / p>
我是为X编写的,当我切换到Wayland时它并没有抱怨,所以它可能适合你。
请注意,它并没有像你提到的那样从Wayland 获取信息,但它实际上可能更好,因为它将与X / Wayland无关。它从我打开的xterm获得了标题,所以它应该是与工具箱无关的。
不要问我有关实施细节的问题。代码至少有四年了:)