Alt+Tab no more
"Write programs that do one thing and do it well."
Простейший вариант запуска приложений — это запуск мышью по ярлыку с, возможно, предварительной фильтрацией по подстроке. Достаточно эффективный метод, но я лично использую grun. Ланчеры подобного рода позволяют полностью избежать мыши для запуска приложений. Grun в этом плане не очень продвинут, он представляет из себя лишь поле ввода названия программы с автодополнением по истории и, возможно, по locate
(?), но зато быстро запускается, не вися при этом в фоне. Есть некоторые недостатки, но в целом удовлетворительно. Однако это, конечно, не предел удобства, о чём ниже.
После того, как мы запустили наши любимые программы, нам, как адептам UNIX, нередко приходится много переключаться между ними. Простейший вариант навигации между приложениями — это мышь или alt+tab. Более продвинутый вариант — совмещение данного способа с несколькими рабочими столами. В этой статье мы рассмотрим альтернативу всему этому — назначение горячих клавиш всем часто используемым приложениям.
Прототип
Индивидуальные хоткеи не только устраняют необходимость в привлечении мыши для задач переключения, но также позволяют совместить в одном хоткее как запуск, так и переключение на окно приложения.
Для реализации подобного поведения достаточно следующего кода:
if wmctrl -l | grep GIMP; then wmctrl -a GIMP; else gimp; fi
(Для работы данной команды необходимо, чтобы в системе была установлена тулза wmctrl
.)
В данном примере, как легко видеть, мы либо активируем окно GIMP, если он запущен, либо запускаем его.
Продакшн
Теперь, на основе этой команды можно набашить скрипт, чтобы уменьшить копипастность конфига, если вы, конечно, настраиваете хоткеи с помощью конфига, как тру хакеры. Заодно можно сделать так, чтобы скрипт переключаться на следующее окно заданного приложения, если некоторое его окно в данный момент уже активно. Возможно, непонятно о чём я, но это полезно.
#!/bin/bash
# $1 - app title, $2 - exe path
if list=`wmctrl -l | grep "$1"`; then
activeid=`xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | sed -e 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //'`
activeid=`printf %d $activeid`
if test=`xprop -id $activeid | grep TITLE | grep "$1"`; then
n=`wmctrl -l | grep "$1" | wc -l`
# select next window in list
m=0
id1=$(printf "%d" "`echo "$list" | head -n 1 | tail -n 1 | sed -e 's/\s.*//'`")
id2=$(printf "%d" "`echo "$list" | head -n 2 | tail -n 1 | sed -e 's/\s.*//'`")
id3=$(printf "%d" "`echo "$list" | head -n 3 | tail -n 1 | sed -e 's/\s.*//'`")
id4=$(printf "%d" "`echo "$list" | head -n 4 | tail -n 1 | sed -e 's/\s.*//'`")
id5=$(printf "%d" "`echo "$list" | head -n 5 | tail -n 1 | sed -e 's/\s.*//'`")
id6=$(printf "%d" "`echo "$list" | head -n 6 | tail -n 1 | sed -e 's/\s.*//'`")
id7=$(printf "%d" "`echo "$list" | head -n 7 | tail -n 1 | sed -e 's/\s.*//'`")
id8=$(printf "%d" "`echo "$list" | head -n 8 | tail -n 1 | sed -e 's/\s.*//'`")
id9=$(printf "%d" "`echo "$list" | head -n 9 | tail -n 1 | sed -e 's/\s.*//'`")
if [ "$activeid" == "$id1" ]; then m=1; fi
if [ "$activeid" == "$id2" ]; then m=2; fi
if [ "$activeid" == "$id3" ]; then m=3; fi
if [ "$activeid" == "$id4" ]; then m=4; fi
if [ "$activeid" == "$id5" ]; then m=5; fi
if [ "$activeid" == "$id6" ]; then m=6; fi
if [ "$activeid" == "$id7" ]; then m=7; fi
if [ "$activeid" == "$id8" ]; then m=8; fi
if [ "$activeid" == "$id9" ]; then m=9; fi
if (( $m >= $n )); then m=1; else m=`echo "$m+1"|bc`; fi
idm=$(printf "%d" "`echo "$list" | head -n $m | tail -n 1 | sed -e 's/\s.*//'`")
idm=$(printf "0x%x" "$idm")
wmctrl -ia $idm
else
wmctrl -a "$1"
fi
else
$2 &
fi
Скрипт превосходно кривой, как и положено bash-скриптам, но он работает! Он переключает нас на окно приложения, заданного первым параметром $1 по титлу, и, если не находит его, тогда запускает приложение в соответствии со вторым параметром $2. Также реализована выше упомянутая фича по циклированию по нескольким (до 10) окнам одного приложения. Для работы скрипта, кроме тулзы wmctrl
, также нужна xprop
— обе могут отсутствовать в вашей системе по дефолту.
Недостаток данного скрипта в том, что он не запоминает то окно из группы нескольких окон одного приложения, которое было активировано последний раз, так что если нужно постоянно переключаться, скажем, на третье окно некоторого приложения, то хоткей необходимо будет нажимать три раза.
Использование
Примеры использования для некоторых приложений:
$ wmexec " GIMP" gimp
$ wmexec ' - gedit' gedit
$ wmexec "gnome-terminal" gnome-terminal
Пример интеграции в конфиг оболочки openbox:
<keybind key="A-F1">
<action name="Execute">
<command>~/bin/wmexec " GIMP" gimp</command>
</action>
</keybind>
<keybind key="W-e">
<action name="Execute">
<command>~/bin/wmexec ' - gedit' gedit</command>
</action>
</keybind>
<keybind key="W-i">
<action name="Execute">
<command>~/bin/wmexec "gnome-terminal" gnome-terminal</command>
</action>
</keybind>
Теперь можно, например, запускать сразу несколько приложений за несколько нажатий на клавиатуре. Или же мгновенно переключаться между несколькими приложениями, не прибегая ни к мыши, ни к Alt+Tab.
Ссылка на скрипт wmexec.
Всем плодотворной кастомизации своего десктопа
shitpoet@gmail.com