Подтвердить что ты не робот

Как получить активное окно на Gnome Wayland?

Фон: Я работаю над программным обеспечением под названием 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, чтобы начать с и следить за другими, поскольку путь становится более понятным.

Аналогичный вопрос, касающийся Уэстона, был задан здесь: получить список активных окон в wayland weston

Изменить: Я спросил в #wayland на Freenode, получил следующий ответ:

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/info/45465016/how-do-i-get-the-active-window-on-gnome-wayland
15:21:25  ErikBjare    Here 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 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 public                                                                                               
15:30:19  ErikBjare    ty :)

Редактировать 2: Подано проблема с улучшением в Bugtracker Gnome.

tl; dr: Как получить активное окно в Gnome при использовании Wayland?

4b9b3361

Ответ 1

По моему мнению, лучший выбор у вас - это не Wayland или любая доступная библиотека (их нет). Фактически, кто знает в gnome-wayland о активных окнах, это Mutter, поэтому вам нужно найти способ спросить Mutter о активных окнах. Gnome может разработать API, чтобы внутренне просить замять активное окно и восстановить функциональность. Но на самом деле у вас нет места, чтобы просить об этом. Mutter не будет разрабатывать API для доступа к его внутреннему представлению, потому что это будет довольно специфично только для Mutter, а не для всех менеджеров окон Wayland. Поэтому это необходимо добавить во внешнюю библиотеку, где эта библиотека может, вероятно, поговорить с текущим менеджером окон, что она используется для разрешения вашего запроса в общем виде.

Еще одна возможность - добавить плагин Wayland, в котором все диспетчер окон будет иметь доступ к текущим активным окнам и в некотором роде библиотека, чтобы напрямую поговорить с wayland, чтобы восстановить функциональность.

Итак, ваше приложение находится в большой проблеме. Большинство, что вы можете сделать, это запросить это на mutter (где знают активные окна), но, на мой взгляд, это невозможно решить в Mutter.

Я надеюсь, что это поможет вам, и вы сможете найти способ. Хороший фиксатор.

Ответ 2

У меня есть script, называемый preguiça.py, который делает именно то, что вы делаете, хотя это, вероятно, намного проще, и я его не выпустил.

Для моего script я приобрел заголовок окна, используя 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 ()

Фактический код для того, что вы просите, фактически прокомментирован в приведенном выше примере (мне не нужно было записывать это окно, поскольку callback уже его получает), но вам может понадобиться его в зависимости от вашей реализации.

Я написал это для X, и он не жаловался, когда я переключился на Wayland, так что, вероятно, это сработает для вас.

Обратите внимание, что он не получает информацию от Wayland, как вы просили, но это, вероятно, на самом деле лучше, так как это будет X/Wayland-agnostic. Он получил название из xterm, который я открыл, поэтому он также должен быть инструментарием-агностиком.

Не спрашивайте меня о деталях реализации. Код не менее четырех лет:)