Site Mascot
 

Не удивляйтесь, сайт переехал: был http://smacker.fatal.ru, стал http://smacker.heliohost.org.

Рационализация монтирования с помощью DCOP

20.03.2007 13:47

Сегодня я расскажу о моей скромной идее по оптимизации работы со сменными носителями с применением DCOP.

 
С моей точки зрения, работа со сменными носителями (CD, DVD, Flash) обладает одним неприятным свойством — носитель в большинстве случаев надо не только подмонтировать, но и открыть в файловом менеджере. И вот тут-то возникает вопрос о появлении новых окон на рабочем столе и о том, как это периодически бесит (по крайней мере /me).
На десктопе монтирование проводит отслеживающий события HAL ivman, правила для которого составлены с учётом того, что при запущенном k3b монтировать диски не надо, так как обычные будут, скорее всего, копироваться, а RW перезаписываться. Но вот с открытием новых окон при монтировании во всех прочих ситуациях совсем беда — неудобно. Не спасат даже разные профили для разных носителей, открывающие окно с набором нужных вкладок и/или удобным разделением окна. На ноутбуке я пользуюсь удобным xfce4-mount-plugin, который при монтировании носителя запускает и выбранную команду.
Итак, вдохновившись статьёй из LXF, я решил применить DCOP для того, чтобы открывать носители во вкладке konqueror (да, даже сидя в XFCE4 я пользуюсь именно им). Для тех, кто не вполне знаком с понятием DCOP объясню, что Desktop Communicaton Protocol позволяет удалённо (вернее, извне приложения) управлять его функциями. Единственная загвоздка состоит в том, что для каждого приложения набор доступных параметров и функций будет разным. Для того, чтобы посмотреть, что умеет то или иное приложение, можно использовать программу kdcop. Отмечу, что в мои планы не входит писать здесь что-то вроде «введения в DCOP», тем более что для этого я не обладаю достаточной квалификацией, поэтому честно отошлю интересующихся к каким либо более компетентным источникам. В крайнем случае мне кажется, что поиск указанных параметров и функций в kdcop поможет понять логику похожих построений.

 

Задача сводится к нахождению запущенных процессов konqueror, определению активного или (если такого нет) последнего (потому что я так захотел) запущенного (больший PID) и открытию в нём вкладки с нужным адресом. В противном случае надо запустить новый процесс konqueror.
Синтаксис вызова dcop примерно таков:
 dcop процесс группа_функций имя_функции_или_параметра
В данном случае нас будут интересовать функции NewTab, reload и параметры isActiveWindow и currentURL групы konqueror-mainwindow#1.
Для каждого окна konqueror запускается свой процесс, поэтому в иерархии DCOP такие процессы будут проходить как отдельные записи вида konqueror-PID, например, сейчас у меня открыто два окна (обратите внимание на использование dcop для поиска процессов и астериска для шаблона):
 [smacker@desktop ~]$ dcop konqueror-*
 konqueror-11220
 konqueror-17487
Поэтому необходимо также решить вопрос о поиске и переборе всех запущенных процессов, это не какой-нибудь amarok, который бывает запущен только в единственном экземпляре.

 

Итак, логика работы скрипта такова:
Сначала перебираются все найденные dcop-ом процессы konqueror, среди которых ищется активный, а заодно определяется больший PID (для вычленения которого используется gawk). Далее, если есть активный процесс, ему передаётся команда newTab с аргументом, переданным собственно скрипту. Иначе newTab отправляется процессу с наибольшим PID-ом. Если нет и такого, открывается новое окно. В первых двух случаях из значения параметра currentURL gawk вырезает file://, после чего адрес сравнивается с аргументом скрипта — и если они совпадают, то новая вкладка не открывается, а обновляется текущая. По-моему, это вполне разумно. К сожалению, я так и не нашёл способа получить список всех открытых адресов во вкладках или возможность перебрать все вкладки по отдельности, чтобы определить, открыт ли данный адрес в какой-либо из них. Единственное, что я могу придумать — это проверять каждую вкладку, а потом закрывать её, чтобы активной стала другая, а затем «открыть как было» — но это неудобный и абсолютно неприемлемый способ... Так что в итоге проверка есть только для активной вкладки, но не для всех остальных. We call it beta 'cos it's beta than nothin'.

 

 #!/bin/bash
 
 MAX_NUM=0
 
 for IFACE in $(dcop konqueror-*)
 do
 
 if [ $(echo $IFACE | gawk -F - '{print $2}') > $MAX_NUM ]
 then
 MAX_NUM=$(echo $IFACE | gawk -F - '{print $2}')
 LAST=${IFACE}
 fi
 
 if [[ $(dcop ${IFACE} konqueror-mainwindow#1 isActiveWindow) == "true" ]]
 then
 ACTIVE=${IFACE}
 break
 fi
 
 done
 
 if [[ ${ACTIVE} ]]
 then 
 # open in active window
 
 ADR=$(dcop $ACTIVE konqueror-mainwindow#1 currentURL | gawk -F "://" '{print $2}')
 
 if [[ ${ADR} != $1 ]] 
 then
 dcop $ACTIVE konqueror-mainwindow#1 newTab $1
 exit
 else 
 dcop $ACTIVE konqueror-mainwindow#1 reload
 exit
 fi
 
 fi
 
 if [[ ${LAST} ]]
 then
 # open in last window
 
 ADR=$(dcop $LAST konqueror-mainwindow#1 currentURL | gawk -F "://" '{print $2}')
 
 if [[ ${ADR} != $1 ]] 
 then
 dcop $LAST konqueror-mainwindow#1 newTab $1
 exit
 else 
 dcop $LAST konqueror-mainwindow#1 reload
 exit
 fi
 
 fi
 
 # open in new window
 exec konqueror $1 &
 exit
 

 

Я назвал этот скрипт open_in_konqueror_tab (chmod 750) и бросил в ~/bin. Теперь в правилах ivman и настройках плагина xfce4 вместо команды konqueror используется именно этот скрипт. Единственное, что меня пока смущает — что периодически возникают проблемы для аргументов типа ./wallpapers, которые при целевом использовании скрипта, впрочем, исключены.
  1. Bircoph

    ***
    > Иначе newTab отправляется процессу с наибольшим PID-ом.

    Это не верно. Представь, что комп не выключается сутками (я со своим так и делаю), число PID'ов по умолчанию ограничено до 32768 (max_PID = 32767). Тогда рано или поздно возникнет процесс с меньшим пидом, поэтому проверку нужно выполнять не по pid, а по времени запуска:
    ps -o lstart -C konqueror
    тебе в помощь.

    З.Ы. Я немного удивлён, что ты на bash написал, как же извечное "perl -- наше всё"?

    [ Запись от 06.05.2007, отправлена в 9:37 ]
  2. Я буду рад, если вы оставите свой отзыв об этой заметке:

    Никнейм

    Email

    URL

    Заголовок комментария

    Проверка на человечность
    - Введите буквы:
    The CAPTCHA image