18 янв. 2009 г.

Об окнах и оконных менеджерах: тонкости организации и управления

Идея упорядочивания рабочего пространства в том или ином виде присуща всем графическим интерфейсам. Однако, окончательную настройку всегда делает сам пользователь и тут он ограничен несколькими факторами. Во-первых, своими пристрастиями. Кто-то любит, чтобы окна всех приложений располагались скопом на одном визуальном пространстве, кто-то предпочитает выделение каждому приложению конкретно своей зоны работы. Во-вторых, возможностями используемого графического окружения. В некоторых пользователь сразу получает все возможности тонкой настройки, в других приходится прибегать к сторонним средствам.

Предисловие.
По первому фактору лично я для себя выбрал второе - мне удобнее группировать окна по некому признаку и выделять группе окон свое рабочее пространство. Так легче ориентироваться, приходится меньше заниматься "увлекательной" операцией point-and-click, когда нужное окно сначала необходимо найти на панели/доке, а потом активировать мышью. Меня, как правило, сильно напрягает, когда на одном десктопе открыто больше 2-3 окон.

В случае использования таких оконных менеджеров, как fluxbox, dwm, awesome и т.п. в распоряжении пользователя сразу находится необходимый функционал. В общем случае достаточно прописать в файле настроек куда каким окнам рисоваться. Однако, при использовании xfwm, metacity и т.п. мы в выборе весьма ограничены. Да, есть виртуальные десктопы, но средств по управлению окнами предлагается крайне ограниченный набор. В xfwm, скажем, нельзя указать, чтобы окно браузера рисовалось на первом десктопе, без декораций, посередине и с указанными размерами. В таких случаях, пользователю очень сильно поможет программа devil's pie.

Немного об архитектуре WM.
Вывод окон приложений на экран осуществляется в общем случае с помощью двух технических средств - графического сервера (X Server) и оконного менеджера (Window Manager). Технически это представляет собой взаимодействие этих двух процессов. При запросе приложения показать окно верхнего уровня, х-сервер генерирует событие, которое перехватывается оконным менеджером, который в свою очередь создает так называемое frame window. Окно, содержащее в качестве своих составляющих такие компоненты, как главное окно приложения и декорации (название окна, кнопки управления). А также в некоторых случаях позволяет выполнить над окном ряд операций - манипуляции с прозрачностью, прорисовка на определенном десктопе, изменение размеров и т.п. Если менеджер окон не предоставляет функционала для расширенного управления окнами (xfwm, metacity), приходится прибегать к утилитам еще более высокого уровня. Так, devil's pie, представляет из себя демона, который взаимодействует с оконным менеджером - после того, как окно создалось, этот демон может выполнить с ним какие-либо заранее заданные действия. Таким образом, архитектурно это более излишне усложненное решение и лишний уровень абстракции. Однако, во многих случаях выбирать не приходится.
WM architecture

К практике!
Итак, в первую очередь программу нужно установить. Она довольно популярна и входит в состав репозиториев множества популярных дистрибутивов:

apt-get install devilspie
pacman -S devilspie

Для работы программа использует набор правил для ряда приложений, создаваемых пользователем. Правила должны располагаться в ~/.devilspie и представлять из себя простые текстовые файлы с расширением *.ds. Как пример приведу мое правило ~/.devilspie/Firefox.ds для браузера Firefox:
( if
( and
( is ( application_name ) "Firefox" )
)
( begin
( set_workspace 1 )
( println "match" )
)
)

Как можно легко понять, первые три строчки здесь представляют из себя условие, необходимое для срабатывания правила. В данном случае это появление окна с именем приложения "Firefox". Далее идет секция действий, которые следует предпринять с данным окном. В моем примере - переместить его на первый десктоп. Команда println "match" служит для отладочных целей настройки - она выводит в терминал с запущенным devil's pie "match", при срабатывании правила.
В качестве условий может выступать множество значений: window_class, window_role, window_name; также, как и в качестве действий: maximize, fullscreen, stick, center, geometry. Все эти значения можно посмотреть в руководстве man devilspie.
Приведу более сложный пример:
( if
( and
( is ( window_role ) "mainWindow" )
( contains ( window_class ) "Sonata" )
)
( begin
( wintype "utility" )
( set_workspace 5 )
( geometry "912x898+142+23" )
( println "match" )
)
)

Данное правило будет ждать появления окна с ролью "mainWindow" и класс которого содержит слово "Sonata". А затем присвоит окну тип "utility" (это позволит не становиться ему прозрачным, к примеру), перенесет на пятый десктоп и установит размеры и положение "912x898+142+23" (ширина, длина, позиция по оси X, позиция по оси Y).

Замечание: в xfce оконный менеджер по умолчанию перебрасывает окно, требующее фокус, на текущий десктоп. В частности, это приводит к тому, что не все ваши правила в devil's pie будут работать корректно и что при нажатии на ссылку, скажем, в почтовом клиенте на втором десктопе, браузер переброситься с первого десктопа на второй с почтовым агентом. Это не баг, а просто нет единого мнения у разработчиков по этому поводу. Однако, такое поведение можно отключить, добавив в файл ~/.config/xfce4/mcs_settings/wmtweaks.xml следующую строчку:
< option name="Xfwm/ActivateAction" type="string" value="none"/ >


Расширенный контроль сложных окон на примере GIMP.
Графический редактор GIMP сам по себе довольно нетривиально работает со своими окнами. Нельзя просто сказать всем окнам класса "Gimp" появляться на заданном десктопе - это не сработает. Однако, я провел небольшое изучение этого вопроса и просто приведу правила для Гимпа, а любой желающий сможет их прочесть и разобраться.
Итак, я создал три правила: два для стандартных боковых фреймов с инструментами и одно для, собственно, окна редактирования изображений.

Окно Toolbox с кистями, инструментами и т.п.:
( if
( and
( is ( window_role ) "gimp-toolbox" )
( contains ( window_class ) "Gimp" )
)
( begin
( undecorate )
( set_workspace 5 )
( geometry "136x925+0+25" )
( println "match" )
)
)

Окно со слоями и т.п.:
( if
( and
( is ( window_role ) "gimp-dock" )
( contains ( window_class ) "Gimp" )
)
( begin
( undecorate )
( set_workspace 5 )
( geometry "217x925+1062+25" )
( println "match" )
)
)

Окно редактирования изображений:
( if
( and
( is ( window_role ) "gimp-image-window" )
( contains ( window_class ) "Gimp" )
)
( begin
( wintype "utility" )
( set_workspace 5 )
( geometry "912x898+142+23" )
( println "match" )
)
)

Как видно из правил, все окна Гимпа перебрасываются на пятый десктоп и изменяют каждое свои размеры (меня очень раздражало, что Гимп автоматически позиционирует каждое окно с изображением). Окна-доки с инструментами и слоями также лишаются декораций (мне они ни к чему и только занимают место и визуальное пространство). А окно редактирования меняет тип на "utility", что не позволяет ему становится прозрачным (у меня включен композитинг и прозрачность активных/неактивных окон разная, т.о. вы можете себе представить в какое "удовольствие" превращается работа с изображением, когда приходится переключаться между окном редактирования и окнами инструментов).
Результат, как говориться, налицо:
GIMP with devil's pie
Дополнительные средства.
Не всегда удобно вручную возиться с правилами и помнить все десятки условий и возможных действий, которые поддерживает devil's pie. В этом случае я рекомендую воспользоваться утилитой gdevilspie - графический настройщик на pyGTK. Он позволяет очень просто парой кликов задавать правила и получать список параметров текущих окон.
По поводу определения параметров окон стоит сказать отдельно. Существует много средств для получения названий, классов, положения и ролей окон. Во-первых, это вывод самого devil's pie - достаточно запустить его из терминала, как мы увидим список присутствующих сейчас окон. Во-вторых, это программа xprop, которая позволяет указать нужное окно мышью и выведет большой массив данных. Отфильтровать их можно например так:
xprop | grep -i role

Что выведет только строку с ролью указанного мышью окна. В-третьих, программа wmctrl, которая вообще незаменима при работе с оконными менеджерами и окнами. Подробнее о ней можно узнать в руководстве man.

Заключение.
На этом, пожалуй, и закончу. Как видите, не все оконные менеджеры сразу предоставляют широкий функционал и, как правило, реагируют на одни и те же действия весьма по-разному. Однако, средства есть, хоть и сторонние. При всех недостатках метода контроля окон уровнем выше wm, это работает и весьма надежно. Так что ничто не мешает вам наслаждаться прелестями разграниченного рабочего пространства в таких окружениях, как Gnome, KDE и XFCE. Хотя для пользователей, которые хотят всё и сразу из коробки, я бы посоветовал взглянуть на Fluxbox, Openbox и другие. Как правило, при своих малых размерах, они уже прекрасно умеют всё то, что я здесь рассказывал без всяких дополнительных средств.

Ссылки:.
1. Window Managers for X: Introduction
2. Wikipedia: Re-parenting window manager
3. Devil's Pie: Syntax & Examples

4 комментария:

fuss комментирует...

Сам пользовался devilspie для простого раскидывания окон приложений по разным рабочим столам (для инета - 1 стол и т.д.). Но в последнее время в Гноме очень сильно начало напрягать что окна как-то странно располагаются на рабочем столе (то прилипают вверху слева, то внизу справа). Хотелось бы в идеале, чтоб окно открывалось там где расположен курсор (вроде в опенбоксе так?). Попробую реализовать это с помощью devilspie. Кстати, оно должно нормально работать и с compiz (хотя сам не проверял).
И еще есть GUI - http://code.google.com/p/gdevilspie/

Alsvartr комментирует...

Про гуй я упомянул. Правда он не всегда корректно определяет открытые окна.

Alsvartr комментирует...

А насчет расположения окон - в devil's pie же можно указать geometry. А вот там, где курсор расположен - право не знаю, можно ли реализовать. Средствами devil's pie вроде нельзя.

Анонимный комментирует...

Добрый день.
Использовал ваши правила для gimp. спасибо.

но, столкнулся с особенностью. открываю гимп на первом рабочем столе.при этом image-window открывается на 3 рабочем столе как прописано у меня в .ds. При этом панель инструментов и окно со слоями открывается на активном столе(при этом в .ds прописано открывать их на 3 столе). переключаюсь на третий стол, там все три окна. переключаюсь обратно на первый - панелей нет.
gnome 2.26
в чем может быть проблема?