angelspie — управление окнами в X11, глобальные и не только горячии клавиши

от автора

Название — отсылка к devilspie, похожей утилитой. Она примечательна тем, что конфиг пишется на диалекте лисп, несмотря на это у неё весьма ограниченные возможности. Тем более у утилит типа wmctl и т.п.

С помощью библиотеки wnck можно делать куда больше, а ещё больше если задействовать gdk.

Для глобальный горячих клавиш я использовал libkeybinder, раньше я делал такое на «голой» xlib, но так удобней(и переносимей). Впрочем xlib/xtest тоже используется — чтобы эмулировать нажание кнопок. Но эти функции опциональны.

В качестве формата конфига я выбрал yaml. Более старые версии использовали конфиг на питоне, но я решил что yaml удобней конечным пользователям. Тем более в него можно встраивать код на python и sh.

В детали реализации я вдаваться не буду. Там много магии и метапрограммирования, часть кода сгенерирована.

Лучше покажу пример конфига, который использует часть возможностей. Кстати, новые правила можно генерировать из командной строки, оно возьмет name и class_group активного окна.

click_with_F1:   if:     key: F1   then:     click: 3 

Самый простой пример. При нажатии F1 будет эмулировать нажатие правой кнопки мыши.

save_image:   if:     key: F2     class_group: Google-chrome   then:     - click: 3     - sleep: 0.1     - press: v     - enable: autosave

При нажатии F2 нажмет правую кнопку, v(save as) и активирует правило autosave

# Would type "filename" and press alt+s to save when Save file dialog of chrome appears. But only after we pressed F2. autosave:   if:     name: Save File     class_group: Google-chrome     enabled: false   then:     - press: f i l e n a m e Alt+S # Disable autosaving every 2 secs. timer_test:   if:     event: timer 2   then:     disable: autosave

При появлении окна Save File запонит имя файла и сохранит. Через 2 секунды это правило отключается. Имя файла будет автоматически заполняться только при нажатии F2, а не у любых окон.

print_debug:   if:       event: never   then:     debug:      win_changed:   if:     event: active_window_changed   then:     echo: "window changed {name} {class_group}" switched_to_xterm:   if:     name:       contains: mc     class_group: XTerm   then:     - maximize:     - disable: win_changed     - trigger: print_debug not_in_mc:   if:     or:       class_group:         ne: xterm       name:         contains_not: mc   then:     - sh: date     - py: from datetime import datetime;print(datetime.now()) 

print_debug можно вызвать только вручную с помощью trigger, остальное думаю очевидно. это просто пример. доступны все манипуляции с окнами из wnck и gdk. список методов есть в командной строке или доках по wnck. возможных условий в if тоже куча, включая вызов кода на питоне или sh.

Важно — если горячая клавиша прописана только для определенного окна или условий. она будет мапиться только при переключении на это окно. При потере фокуса, хоткей отключается и кнопка работает как обычно. Это то чего нехватает многим гломальным менеджерам горячих кравиш.

Например у меня есть скрипт, который обрезает видео на текущем моменте, если активное окно — mpv. В других окнах такая функция была бы бесполезно, а кнока бы не работала.

Кстати. хоть в коде и много магии, я думаю, там неплохая архитектура. Хотелось бы услышать критику. Но тут важен баланс между понятностью кода и его универсальностью / компакностью. Упор сделан на последнее.

Код доступен на github https://github.com/pawnhearts/angelspie и pypi. Кстати. где бы ещё разместить программу? Хочется донести её для десктопных юзеров. Возможно, придется добавить gui, но там слишком много функций. Удобней просто редактировать конфиг.

ссылка на оригинал статьи https://habr.com/ru/post/562304/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *