Название - отсылка к 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 и pypi. Кстати. где бы ещё разместить программу? Хочется донести её для десктопных юзеров. Возможно, придется добавить gui, но там слишком много функций. Удобней просто редактировать конфиг.
selivanov_pavel
Я бы советовал ppa-репозиторий или snap для самого популярного десктопного линукса — Ubuntu. На второе место я бы наверное поставил не Fedora/CentOS, а ArchLinux — там меньше пользователей, но больше тех, кто ценит вещи такого типа, где можно потрахаться, зато получить идеальный результат под себя. Для Fedora/CentOS — flatpack.
Десктопный линукс, увы, очень фрагментирован.
ИМХО достаточно значка в трее, показывающего что программа работает, и позволяющего открыть активный конфиг в редакторе. Посмотрите на AutoKey, например: https://github.com/autokey/autokey
Вообще, интересная штука, может когда-нибудь дойдут руки попробовать.