В статье говорится о том, как динамически изменять и считывать иконку окна Linux. Утилита xdotool_xseticon была создана для динамического изменения значка окна в Astra Linux. Затем функциональность утилиты была расширена для полного управления окнами и получения всей информации об окне Linux. Утилита xdotool_xseticon была протестирована в средах Wayland и X11 в Ubuntu 24.04 (KDE), X11 в Ubuntu 22.04 (KDE) и Astra Linux 1.8. Размер утилиты - 1000 строк.

Краткая предыстория

Краткая предыстория, в ходе работы с Astra Linux понадобилось сделать информационную систему из старой ВЕБ-системы с ограничениями для пользователя. В связи с этим понадобилась утилита, которая управляет независимыми окнами. Далее с помощью Bash был сделан фреймворк для Astra Linux. По техническому заданию в системе нельзя было использовать нелицензионный софт , поэтому был сделан фреймворк WebDesktopGL, в состав которого и входит эта утилита xdotool_xseticon.

Установка и сборка

Установку можно выполнить с помощью команды git clone, а сборку - с помощью скрипта Install_bash_Xdotool_xseticon.sh.

git clone https://github.com/PVE-Vladimir/xdotool_xseticon.git
# Использовать скрипт установки Install_bash_Xdotool_xseticon.sh
./xdotool_xseticon/Install_bash_Xdotool_xseticon.sh
cd ./xdotool_xseticon

Сборка происходит через gcc. Команда сборки

sudo apt install libx11-dev
gcc -o "$SCRIPT_DIR/xdotool_xseticon" "$SCRIPT_DIR/Xdotool_xseticon.c" -lX11

Результат сборки — утилита xdotool_xseticon.

Описание использования утилиты

Утилита была создана для управления иконкой окна Linux. Для этого она использует ARGB-значения цветов. RGB-значения цветов можно получить, применив скрипт make_window_icon_txt.sh, который создаст файл icon.txt (массив Bash в формате ARGB) из любого изображения формата gif, webp, mov, mp4 и png. Анимацию для иконки возможно получить из файлов форматов gif, webp, mov, mp4. В скрипте есть функция обработки изображения для добавления alpha канала.

Каждый запрос скрипта make_window_icon_txt.sh создаёт файл .txt текстовый bash массив ARGB пикселей. Если сделать запрос для одного изображения .png, скрипт вернёт массив с одним элементом со списком пикселей, записанным в .txt и содержащим:

declare -a arr_txt=([0]="2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010") 

Также этот список пикселей будет продублирован непосредственно в терминале.

Чтобы узнать идентификатор окна (0x6000001), используйте команду search:

./xdotool_xseticon search --pid $(pgrep zabbix_replay)
./xdotool_xseticon search --name zabbix_replay | head -n1

Получить иконку окна

Получить иконку окна возможно из уже запущенного окна

./xdotool_xseticon _NET_WM_ICON $(./xdotool_xseticon search --name zabbix_replay | head -n1)

Команда вернёт ARGB-значения цветов 2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010. Создать файл иконки возможно через команды

echo "declare -a arr_txt=([0]=\"$(./xdotool_xseticon _NET_WM_ICON \
$(./xdotool_xseticon search --name zabbix_replay | head -n1))\")" > icon.txt ;
./make_window_icon_txt.sh icon.txt # создать файл icon_txt.png

В итоге получится текстовый bash массив ARGB пикселей icon.txt и файл изображения icon_txt.png.

Извлечь из .png формата ARGB-значения цветов 2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010 возможно путём команды:

./make_window_icon_txt.sh alpha ./Images/tenor2/frame_00000014.png

Команда вернёт ARGB-значения цветов в frame_00000014.txt и выведет ARGB в терминале.

Поменять иконку окна через xseticon

xseticon это однократное изменение иконки окна на изображение в формате ARGB-значения цветов.

./xdotool_xseticon xseticon 0x6000001 2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010

0x6000001 — идентификатор окна.

2 2 — размер иконки (2x2 пикселя).

0xffff0000 и т.д. — ARGB-значения цветов.

Одиночную иконку можно установить сразу из .png используя xseticon без создания .txt файла

./xdotool_xseticon xseticon $(./xdotool_xseticon search \
--name zabbix_replay | head -n1) $(./make_window_icon_txt.sh \
txt_off ./Images/tenor2/frame_00000014.png)
Пример работы команды xseticon без alpha канал
Пример работы команды xseticon без alpha канал

Одиночную иконку можно установить сразу из .png изображения добавив alpha канал

./xdotool_xseticon xseticon $(./xdotool_xseticon search \
--name zabbix_replay | head -n1) $(./make_window_icon_txt.sh \
alpha txt_off ./Images/tenor2/frame_00000014.png)
Пример работы команды xseticon с alpha каналом
Пример работы команды xseticon с alpha каналом

Возможно использовать и более сложные конструкции через bash, к примеру, как в скрипте set_gif.sh, который устанавливает, через xseticon, анимированную иконку или одиночную иконку. Скрипт вызывается через команду:

./set_gif.sh zabbix_replay ./Images/Image.txt
Пример работы скрипта set_gif.sh
Пример работы скрипта set_gif.sh

Скрипт проверяет: нашлось ли окно по названию через pid, наличие дисплея, наличие второго изображения. Если массив .txt содержит один элемент, то количество элементов равно 1, поэтому он устанавливается только один раз. Если вы хотите постоянно обновлять изображение, используйте массив из двух одинаковых элементов. Частота кадров анимации задаётся через sleep 0.05. Скрипт не прерывается, а пишет echo "Error"; замените это на exit 0, чтобы скрипт завершался в случае ошибки.

Возможно не использовать массив и сразу указать 2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010 через переменную bash. Это удобно, если не хочется оставлять отдельный файл изображения, а все данные хранить в одном коде bash.

icon_txt="2 2 0xffff0000 0x0000ffff 0xcccc0b09 0x10101010"
./xdotool_xseticon xseticon $(./xdotool_xseticon search \
--name zabbix_replay | head -n1) $icon_txt

Анимировать или поменять иконку окна через xseticon_gif

xseticon_gif — это функция утилиты xdotool_xseticon, которая является аналогом скрипта set_gif.sh. Основное отличие xseticon_gif от скрипта set_gif.sh заключается в том, что это более оптимизированное решение на языке Си и что эта функция без изменения кода не ожидает в отдельном потоке после вызова ситуации, когда будет доступно выполнение команды. xseticon_gif отличается от xseticon тем, что она работает не с отдельными пикселями, а обрабатывает только массив .txt.

Пример команды

./xdotool_xseticon xseticon_gif $(./xdotool_xseticon search \
--name zabbix_replay | head -n1) ./Images/Image.txt 6

6 в конце это частота анимации кадров в секунду.

Пример xseticon_gif
Пример xseticon_gif

Функция также распознаёт одиночные массивы .txt и выполняется только один раз

./xdotool_xseticon xseticon_gif $(./xdotool_xseticon search \
--name zabbix_replay | head -n1) ./Images/tenor2/frame_00000014.txt

Функция xseticon_gif для установки анимации не является полностью оптимизированной для всех дистрибутивов Linux. Она нагружает процесс Xorg или его аналоги, к примеру /usr/bin/plasmashell. В целом нагрузка идёт на CPU и не очень высокая при частоте кадров 20. Таким образом, анимацию возможно использовать для одного окна без проблем для системы. Однако в разных версиях одного и того же дистрибутива Linux анимация может вести себя по-разному. К примеру, почему-то в Ubuntu 22.04 (KDE) анимация работает превосходно, а в Ubuntu 24.04 (KDE) установлено ограничение анимации на 6 кадров. Причина этого в том, что Ubuntu 24.04 (KDE) появилась после того, как начали применять ИИ для отладки кода. В результате нарушилась работа plasmashell. Сбой выглядит так, будто ИИ добавил асинхронную проверку иконки окна. Я не проверял изменения в коде, но вряд ли человек мог допустить такой баг. Пример ошибки для Ubuntu 24.04 (KDE) показан справа, слева - нормальная работа анимации.

Слева нормальная работа анимации, справа ошибка plasmashell
Слева нормальная работа анимации, справа ошибка plasmashell

Заключение

Новые версии KDE становятся хуже по сравнению со старыми из-за того, что кастомный функционал становится менее доступным. В других дистрибутивах Linux анимация работает более стабильно и производительно, чем в KDE, по результатам тестов. Анимация xdotool_xseticon xseticon_gif работает с Wayland в Ubuntu 24.04, что подтверждено результатами тестов. В системах с Wayland обычно запускается XWayland — сервер, эмулирующий протокол X11 поверх Wayland. Возможно, этого достаточно, чтобы xdotool_xseticon работал с Wayland. Изменение иконки окна у сторонних окон позволяет добиться новых сценариев использования Linux, тем самым существенно расширяя функционал различных сервисов и приложений.

Комментарии (0)