46

背景:我正在开发一款名为ActivityWatch的软件,它可以记录您在计算机上所做的事情。基本上是尝试解决以下问题:RescueTime、selfspy、arbtt 等。

我们所做的核心工作之一是记录有关活动窗口(类和标题)的信息。过去,这是在 Linux 上使用 xprop 完成的,现在 python-xlib 没有问题。

但是现在我们遇到了一个问题: Wayland 正在兴起,据我所知,Wayland 没有活动窗口的概念。所以我担心的是,我们将不得不为 Wayland 可用的每个桌面环境实现支持(假设它们将提供获取有关活动窗口的信息的能力)。

希望他们最终会融合并有一些共同的界面来完成这项工作,但我并没有屏住呼吸......

我一直在期待这个问题。但是今天我们收到了第一个来自 Wayland实际用户的对 Wayland 支持的用户请求。随着较大的发行版采用 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:在 Gnome bugtracker 中提交了一个增强问题

tl;dr:使用 Wayland 时如何在 Gnome 上获得活动窗口?

4

3 回答 3

5

之前的两个答案已经过时了,这是在(Gnome)Wayland中查询窗口的应用名称和标题的当前状态。

  1. 可以通过 DBus 访问的 Gnome 特定的 JavaScript API
  2. wlr-foreign-toplevel-management Wayland 协议(遗憾的是 Gnome 没有实现)

Gnome 特定的 API 可能会在 Gnome 版本之间中断,但它可以工作。它严重依赖 Gnome 内部 API 才能工作,因此它不可能成为标准 API。aw-watcher-window 上有一个 PR 可以添加 this ,但如果可能的话,它需要一些清理和 afk 支持。

wlr-foreign-toplevel-management协议(在撰写本文时)由 Sway、Mir、Phosh 和 Wayfire 合成器实现。连同被 Wayland 合成器广泛实现的 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。

于 2020-09-23T14:31:50.000 回答
3

在我看来,您拥有的最佳选择不是 Wayland 或任何可用的库(没有一个)。实际上,在 gnome-wayland 中知道活动窗口的人是 Mutter,因此您需要找到一种方法来要求 Mutter 活动窗口。Gnome 可以开发一个 API 来在内部请求静音活动窗口并恢复功能。但实际上,你没有地方要求它。Mutter 不会开发 API 来访问他的内部表示,因为这将非常特定于 Mutter,而不是所有 Wayland 窗口管理器。所以这需要添加到一个外部库中,这个库可能会与当前的窗口管理器对话,它正在以一般方式解决您的请求。

另一种可能性是添加一个 Wayland 插件,其中所有窗口管理器都可以共享当前活动窗口,并以某种方式与库直接对话以恢复功能。

因此,您的应用程序存在很大问题。大多数你可以做的是在mutter上请求这个(知道活动窗口的地方),但在我看来它不能在Mutter中解决。

我希望这会对您有所帮助,并且您可以找到方法。祝你好运。

于 2017-10-04T04:59:48.033 回答
-4

我有一个名为 的脚本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 ()

您所要求的实际代码实际上已在上面的示例中注释掉(我不需要捕获窗口,因为回调已经收到它),但您可能需要它,具体取决于您的实现。

我是为 X 写的,当我切换到 Wayland 时它没有抱怨,所以它应该对你有用。

请注意,它不会像您问的那样从 Wayland获取信息,但实际上它可能更好,因为它将与 X/Wayland 无关。它的标题来自我打开的一个 xterm,因此它也应该与工具包无关。

不过,不要问我实施的细节。该代码至少有四年的历史:)

于 2017-08-18T14:04:31.947 回答