Операционные системы Linux обладают очень большими возможностями для автоматизации рутинных действий. В предыдущих публикациях мы уже показали большое количество различных и странных примеров, включая возможность управления системой с помощью календаря Google. Но мы никогда не затрагивали автоматизацию и скриптование программ с графическим интерфейсом. А ведь как правило им тоже можно управлять из консоли и скриптов.
Управление программами с помощью Wmctrl
Скрестить мощь скриптов и красоту графики поможет wmctrl. С его помощью можно изменять размер и расположение окон на экране, автоматизировать смену рабочих столов или использовать информацию об открытых окнах в других скриптах.
Основное преимущество wmctrl — полная независимость от какого-либо оконного менеджера. Он взаимодействует с окнами посредством протокола EWMH/NetWM, который поддерживают большинство оконных менеджеров.
Не буду утомлять вас рассказами о возможностях утилиты и ее флагах, а сразу покажу пример. Все знают о существовании Konsole и Tilda, специальных эмуляторах терминала, которые можно разворачивать и сворачивать нажатием клавиши. С помощью wmctrl вы сможете наделить такими возможностями любой другой эмулятор терминала (например, Konsole из KDE).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#! /bin/bash if [ `wmctrl -xl | grep -c Konsole` != 0 ]; then if [ -f /tmp/.Konsole.add ]; then wmctrl -r Konsole -b add,below rm /tmp/.Konsole.add else wmctrl -r Konsole -b add,above touch /tmp/.Konsole.add fi else konsole fi |
Просто повесь его на клавиатурную комбинацию. Первое нажатие запустит терминал, а все последующие будут сворачивать/разворачивать его.
Эмулятор терминала не единственное применение wmctrl в рамках представленного выше скрипта. На самом деле вместо Konsole можно подставить любую программу. А можно пойти дальше и задействовать в сценарии два окна, например браузер и мессенджер, таким образом, чтобы в определенный момент работы в интернете нажатием клавиш можно было заставить браузер подвинуться и освободить место под мессенджер и кинуть взгляд на сообщения в чате.
Чтобы этого добиться, сначала нужно определить размеры окон обоих приложений в каждом из двух требующихся состояний. Делается это с помощью команды wmctrl -lG (перед этим растяните/сожмите окна до нужных размеров):
1 2 3 4 5 6 7 |
$ wmctrl -lG 0x0500001b 0 0 55 1280 726 N/A Проект OpenNet - QupZilla 0x03000005 0 900 55 380 693 N/A Telegram (6) $ wmctrl -lG 0x0500001b 0 0 55 900 693 N/A Проект OpenNet - QupZilla 0x03000005 0 900 55 380 693 N/A Telegram (6) |
Опция -G добавляет четыре дополнительных столбца в середине вывода команды. В них отражены данные о смещении окон по осям X и Y, а также их ширина и высота соответственно. В моем случае я сначала использовал данные в точности, как их вывела команда. Но при подстановке в сценарий расположение окна QupZilla по оси Y по какой-то причине отличалось от расчетного, поэтому его пришлось немного подкорректировать вручную.
1 2 3 4 5 6 7 8 9 10 11 |
#!/bin/sh if [ -f /tmp/.telega.half ]; then wmctrl -r Telegram -e '0,900,55,380,693' -b add,below wmctrl -r QupZilla -e '0,0,26,1280,726' rm /tmp/.telega.half else wmctrl -r QupZilla -e '0,0,26,900,693' wmctrl -r Telegram -e '0,900,55,380,693' -b remove,below touch /tmp/.telega.half fi |
При первом запуске этот скрипт сожмет окно браузера с правой стороны и покажет в освободившемся пространстве окно мессенджера. Второй запуск закроет мессенджер и вернет окно браузера в прежнее состояние.

Управление программами с помощью Xdotool
Telegram, который мы использовали в примере с браузером и мессенджером, сам по себе неплохо управляется сочетаниями клавиш. И все-таки одного шортката мне не хватает. Того, который восстанавливал бы окно из лотка. Wmctrl не всегда способен решить эту задачу. И пока встроенные возможности мессенджера не могут нас порадовать подобной функциональностью, поможет утилита xdotool. Она позволяет эмулировать действия мышью, а значит, и повесить их на сочетания клавиш.
Поскольку рабочее окружение у меня Plasma, я создал еще один виджет системного лотка, отключив в его настройках все пункты, кроме «Состояния приложений», а всем элементам приложений, кроме Telegram, указал пожизненную невидимость («Всегда скрывать»). Сам же Telegram должен быть всегда виден.

Осталось только определить координаты значка «Телеграма» при заблокированных виджетах, установив на него курсор мыши и выполнив в терминале такую команду:
1 |
$ xdotool getmouselocation |
Из всего многообразия полученных данных берем координаты X, Y (в моем случае — 1238 и 776) и подставляем в команду, перемещающую курсор мыши в заданное положение из любой области экрана и эмулирующую одно нажатие левой кнопки.
1 2 3 |
#!/bin/sh xdotool mousemove 1238 776 click 1 mousemove 640 400 |
Далее скрипт можно привязать к комбинации клавиш (или, как у меня, к одной — Menu), чтобы при их нажатии появлялось окно программы. Повторное нажатие того же сочетания клавиш вновь свернет окно Telegram в трей. Для удобства навигации в скрипт добавлен возврат курсора мыши в центр экрана.
Управление программами с помощью Xwininfo
Утилита xwininfo показывает на экране большое количество характеристик выбранного окна: ID, название, размеры, отступы от краев экрана, толщину границ, цветовую палитру и многое другое. Утилита wmctrl, содержащая в строке параметров опцию :SELECT:, позволяет применить указанные параметры к окну, наведя на него курсор и щелкнув мышью:
1 |
$ wmctrl -r :SELECT: -T <название> |
Управление программами с помощью Xprop
Часто используемая в различных сценариях утилита xprop предназначена для отображения свойств окон и шрифтов. В некоторых моментах функциональность xprop пересекается с функциональностью других утилит. Например, чтобы определить активное окно, можно выполнить одну из следующих команд:
1 2 3 4 5 |
$ xdotool getwindowname $(xdotool getactivewindow) $ xwininfo -int -id $(xdotool getactivewindow) | awk -F\" '/xwininfo:/ { print $2; exit }' $ xwininfo -id $(xprop -root | awk '/NET_ACTIVE_WINDOW/ { print $5; exit }') | awk -F\" '/xwininfo:/ { print $2; exit }' |
Кроме того, xprop можно использовать, когда нужно изменить свойства окон или шрифтов. В одной из прошлых статей я рассказывал про трюк с эффектом размытия для полупрозрачного окна Yakuake. Тот же прием для Konsole будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 |
#!/bin/bash if [ `echo $DISPLAY` ]; then konsolex=$(qdbus | grep konsole | cut -f 2 -d\ ) if [ -n konsolex ]; then for konsole in $konsolex; do xprop -f _KDE_NET_WM_BLUR_BEHIND_REGION 32c -set _KDE_NET_WM_BLUR_BEHIND_REGION 0 -id `qdbus $konsole /konsole/MainWindow_1 winId`; done fi fi |
Управление программами с помощью D-Bus
Практически любой современный десктопный дистрибутив Linux поставляется с системой межпроцессного взаимодействия D-Bus. Многие приложения используют D-Bus для общения между собой, ее же использует среда KDE с версии 4. Для нас же важно то, что D-Bus можно применить в качестве посредника между пользователем и машиной, то есть для управления графическими приложениями и их скриптования.
Как пример использования D-Bus приведу скрипт, который мониторит уведомления от Telegram и при наличии в сообщении определенного триггера — имени контакта или ключевой фразы — автоматически открывает приложение для просмотра сообщения. Чтобы реализовать этот замысел, можно присовокупить к D-Bus уже известный нам xdotool:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/bash contact="Николай" dbus-monitor "interface='org.freedesktop.Notifications'" |\ grep --line-buffered "string" |\ grep --line-buffered $contact |\ grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\ grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\ grep --line-buffered -v '^\s*$' |\ xargs -I '{}' echo {} |\ sed -u -n 's/'$contact'/xdotool mousemove 1096 66 sleep 1 click 1/p' |\ sh |
В качестве триггера здесь использовано имя контакта, как оно указано в списке контактов. Фильтруя и редактируя новые сообщения в рамках мониторинга D-Bus, на выходе получаем имя контакта в момент, когда от него приходит сообщение, и подменяем его на модифицированную команду из предыдущих примеров.
По заранее вычисленным координатам скрипт перемещает курсор мыши в ту область, где появляется окно нотификации, и секунду спустя эмулирует клик левой кнопки, тем самым заставляя «Телеграм» открываться с фокусом на отправителе этого сообщения и самом сообщении.
Выводы
Несмотря на то что графический софт обычно предполагает управление мышью и зачастую весьма ограниченный набор комбинаций клавиш, широкие возможности Linux позволяют создавать сценарии даже в этом случае.
В статье перечислены далеко не все возможности консольных приложений по управлению программами с графическим интерфейсом. Тут предпринята всего лишь попытка обозначить наиболее общие моменты, с помощью которых каждый мог бы настроить собственный инструментарий для выполнения своих уникальных задач.