Просто для удовольствия, так как вы находитесь на X
Используя python (или кучу других языков) Мы можем использовать сигналы от Wnck.Экран и Wnck.Window следить за созданием и/или изменением состояния окон. Это включает в себя максимизацию и минимизацию окон.
Это именно то, что делает приведенный ниже скрипт. Впоследствии он поддерживает файл журнала, который будет обновляться, если вы создаете, сворачиваете или разворачиваете окно определенного WM_CLASS (и, следовательно, приложения). Вы можете найти WMCLASS целевого приложения, открыв терминал, введите xprop WM_CLASS
+ Возвращаться, затем нажмите на тему окна («telegramdesktop» для телеграммы или что-то в этом роде).
Имейте в виду, что я заставил скрипт сбрасывать файл журнала после каждого сеанса (регистрации), иначе файл журнала со временем стал бы огромным.
Что в лог-файле?
Лог-файл (~/.windowlog.txt
) будет хранить записи о создании, закрытии и изменении состояния окон данного WM_Class. Каждый раз, когда окно разворачивается, счетчик добавляет единицу, поэтому в конце дня вы можете увидеть активность:
найдено окно: Telegram
состояние изменено: визуальное(1)
состояние изменено: свернуто
состояние изменено: визуальное(2)
состояние изменено: свернуто
состояние изменено: визуальное(3)
окно закрыто: Telegram
новое окно: Telegram
состояние изменено: визуальное(4)
состояние изменено: свернуто
состояние изменено: визуальное(5)
Запись что сценарий написан с расчетом на одно окно для приложения, как в вашем вопросе. Чтобы вести более подробную запись за окно, обработка данных потребует более сложного кодирования.
Сценарий
#!/usr/bin/env python3
импорт ги
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
из gi.repository импортировать Gtk, Wnck
импорт ОС
импорт системы
класс WatchWindow:
защита __init__(я, wmclass):
self.visual = Нет
self.count_visual = 0
self.wnck_scr = Wnck.Screen.get_default()
self.wmclass = wmкласс
self.logpath = os.environ["HOME"] + "/.windowlog.txt"
self.run_watching()
Gtk.main()
def write_to_log (я, новая строка):
с open(self.logpath, "a+") в качестве файла журнала:
logfile.write(новая строка + "\n")
def readable_state (самостоятельно, свернуто):
п = ""
если не свернуто:
self.count_visual = self.count_visual + 1
n = "(" + str(self.count_visual) + ")"
return ["свернутый", "визуальный"][[True, False].index(свернутый)] + n
def logstate (я, окно, * аргументы):
old_state = self.visual
новое_состояние = окно.is_minimized()
# регистрируем только в том случае, если свернутое состояние действительно изменилось
если старое_состояние != новое_состояние:
self.visual = новое_состояние
message = "состояние изменено: " + self.readable_state(self.visual) # журнал
распечатать (сообщение)
self.write_to_log(сообщение)
def log_new (я, экран, окно):
если window.get_class_group_name().lower() == self.wmclass:
message = "новое окно:" + window.get_name() # запись нового
распечатать (сообщение)
self.write_to_log(сообщение)
self.watch_window (окно)
self.logstate(окно)
def log_closed (я, экран, окно):
если window.get_class_group_name().lower() == self.wmclass:
имя = окно.get_name()
self.visual = Нет
print("окно закрыто:", name) # журнал закрыт
def watch_window(self, window, firstcall=False):
если window.get_class_group_name().lower() == self.wmclass:
если первый вызов:
message = "найдено окно:" + window.get_name()
print(message) # зарегистрируйте пожалуйста
self.write_to_log("Найдено окно: " + window.get_name())
self.logstate(окно)
window.connect("state_changed", self.logstate)
определение run_watching (я):
пытаться:
os.remove(self.logpath)
кроме FileNotFoundError:
проходят
self.wnck_scr.force_update()
для w в self.wnck_scr.get_windows():
self.watch_window(w, Истина)
self.wnck_scr.connect("окно открыто", self.log_new)
self.wnck_scr.connect("окно закрыто", self.log_closed)
аргументы = sys.argv[1:]
если не аргументы:
print("Недостаточно аргументов! Нам нужен wm_class для наблюдения...")
еще:
Окно наблюдения (аргументы [0])
Настраивать
Скопируйте скрипт в пустой файл, сохраните его как виндоггер.py
и сделать его исполняемым
Тест-запустите его в окне терминала, запустите его с WM_CLASS в качестве аргумента (я полагаю телеграмдесктоп
), так:
/путь/к/windowlogger telegramdesktop
Посмотрите, в порядке ли вывод в терминале, см. Внутри лог-файла ~/.windowlog.txt
если все работает как надо.
Добавьте его в свои приложения для запуска, если хотите.
NB
Возможно, вам нужно добавить одну или несколько библиотек, проверьте вывод терминала.
Окно регистрации активно?
Из комментария я понимаю, что вы считаете окно «используемым» (только), если это активное окно.
В этом случае мы можем значительно упростить сценарий, так как мы Только нужно посмотреть на active_window_changed
сигнал. Если мы также регистрируем использование времени (за использование / общее время использования), вы можете получить четкое представление о том, сколько времени вы потратили, глядя на (любое) окно телеграммы. Затем файл журнала выглядит так:
start_time: woensdag, 06 октября 2021, 11:32:53
окно активировано (1)
окно скрыто или закрыто, было активно: 0:00:04 всего: 0:00:04
окно активировано (2)
окно скрыто или закрыто, было активно: 0:00:06 всего: 0:00:10
окно активировано (3)
окно скрыто или закрыто, было активно: 0:00:12 всего: 0:00:22
окно активировано (4)
окно скрыто или закрыто, было активно: 0:00:07 всего: 0:00:29
Скрипт в таком случае:
#!/usr/bin/env python3
импорт ги
gi.require_version("Gtk", "3.0")
gi.require_version("Wnck", "3.0")
из gi.repository импортировать Gtk, Wnck
импорт ОС
импорт системы
время импорта
импорт даты и времени
класс WatchWindow:
def __init__(я, wmclass):
self.visual = Ложь
self.count_visual = 1
self.wnck_scr = Wnck.Screen.get_default()
self.wmclass = wmкласс
self.logpath = os.environ["HOME"] + "/.windowlog.txt"
self.total_time = 0
self.last_time = время.время ()
self.run_watching()
Gtk.main()
def write_to_log (я, новая строка):
с open(self.logpath, "a+") в качестве файла журнала:
logfile.write(новая строка + "\n")
def get_readable_time (самостоятельно, истекло):
вернуть строку (datetime.timedelta (секунды = прошедшее))
def log_active (я, * аргументы):
пытаться:
# active_class может быть None, например. при запуске
active_class = self.wnck_scr.get_active_window().get_class_group_name()
кроме AttributeError:
актив_класс = ""
newvisual = active_class.lower() == self.wmclass.lower()
старый визуал = self.visual
текущее время = время.время()
если новое визуальное != старое визуальное:
если новый визуал:
self.last_time = текущее время
message = "окно активировано (" + str(self.count_visual) + ")"
self.count_visual = self.count_visual + 1
еще:
winactive_time = текущее время - self.last_time
self.last_time = текущее время
self.total_time = self.total_time + winactive_time
message = "окно скрыто или закрыто, было активно: " + \
self.get_readable_time (раунд (winactive_time)) +\
"\t" + "всего:" +\
self.get_readable_time (раунд (self.total_time))
self.write_to_log(сообщение)
self.visual = новый визуал
определение run_watching (я):
пытаться:
os.remove(self.logpath)
кроме FileNotFoundError:
проходят
time_stamp_message = "start_time: " + time.strftime(" %A, %B %d %Y, %H:%M:%S")
self.write_to_log (time_stamp_message)
self.wnck_scr.force_update()
self.wnck_scr.connect ("активное окно изменено", self.log_active)
self.log_active()
аргументы = sys.argv[1:]
если не аргументы:
print("Недостаточно аргументов! Нам нужен wm_class для наблюдения...")
еще:
Окно наблюдения (аргументы [0])
Настройка такая же.