j4-dmenu-desktop - запускаем программы комфортно и шустро

Опубликовано 29.11.2024 в OpenBSD

Вот как представители красноглазого сообщества обычно запускают программы? Пользователи всяческих DE - понятно как, на то у них встроены всевозможные меню, панели, доки и тому подобное. Любители openbox/fluxbox/blackbox туда же - в их боксах тоже есть встроенное меню. А истинные минималисты, например, пользующиеся оконным менеджером i3? У нас (и подобных) практически дефолтным вариантом считается dmenu (точнее, dmenu_run).

Однако же, поставив i3 в OpenBSD и изучая дефолтный конфиг, я когда-то обнаружил, что там помимо вызова, собственно, dmenu_run, предлагается как вариант использовать более стильную, модную и молодежную, но всё ещё минималистичную запускалку программ rofi - умеющую всякие приятные штуки, вроде запуска не только программ из PATH, но и понимающую .desktop-файлы, хранящую историю команд, поддерживающую отображение иконок и всяческие стили оформления, в общем, красота. И эту красоту я довольно долго использовал - покуда не обратил внимание, что это доставляет мне легкий дискомфорт...

Дискомфорт прежде всего от того, что вовсе не так rofi стремителен, как мне бы хотелось: поиск соответствий по мере ввода немножко, но раздражающе подтормаживает. А изредка по совершенно непонятным мне причинам rofi и вовсе может "упасть в кору" при старте и приходится жмякать хоткей второй раз. Довольно! Хватит это терпеть! Пора причинять себе комфорт и удобство.

Начнем со сбора требований. Как правило, я знаю название программы, которую пытаюсь запустить. То есть, мне не нужно набирать, например, "File Manager", чтобы запустить Thunar, я сразу начинаю набирать название бинарника. Соответственно, мне нужен поиск программ из PATН (а dmenu_run как раз ровно это и умеет).

Но есть исключения - иногда мне удобнее запускать приложение через его .desktop-файл по названию - например, ну вот никак не удается мне запомнить, что любимая коллекция карточных пасьянсов Aisleriot Solitaire (единственная, кстати, игра, которую я установил для себя) запускается бинарём с кратким, но каким-то невыразительным названием "sol". Вот каждый раз с трудом вспоминаю! Соответственно, мне нужна и поддержка работы с desktop-файлами. Это, в принципе, умеет обертка над dmenu под названием i3-dmenu-desktop, которая поставляется вместе с i3 - но зато она не умеет поиск из PATH. Хотя это поправимо...

А еще i3-dmenu-desktop умеет все-таки, если ему ввести руками название консольного приложения с параметрами командной строки - запустить это приложение. Оно еще как-то забавно при этом ругается, если запускать из консоли: мол, соответствий пользовательскому вводу я не нахожу, так что "сомнительно, но ОК", попробую запустить... Не то чтоб это самая частая для меня фича (у меня в i3 на первом воркспейсе абсолютно всегда открыта пара терминалов для работы с консольным софтом), но иногда все-таки бывает удобно.

Далее: самый частый кейс взаимодействия с тем же самым rofi - это когда я даже не начинаю печать название нужной мне программы, а одним/двумя/тремя кликами стрелочки "вниз" (в случае с rofi - у него меню вертикальное по дефолту) выбираю вариант из самых частых по истории вызовов. Ну вот действительно часто запускаемых мною программ совсем немного, меньше десятка, остальное изредка или в эмуляторе терминала... Но тем не менее: сортировка по частоте запуска (а следовательно, и ведение истории) должно быть, это для меня важно. И вот этого ни dmenu_run, ни i3-dmenu-desktop не умеют в принципе.

Ну еще из требований возможность стилизовать запускалку под расцветку моей системы, чтоб не смотрелась чужеродно. Вкусовщина, конечно, но это мелочи, которые создают настроение.

В общем, я уж было совсем собрался писать собственную обертку для dmenu_run/i3-dmenu-desktop, чтоб оно умело в историю команд, но решил прежде погуглить - ну как кто-то уже пилил подобное? Я, видите ли, не тешу себя мыслью, что я прям уникальная снежинка и нитакусик, и потребности мои эксклюзивны... Всё это сто раз приходило в голову другим, разумеется.

И закономерно я нашел решение: проект j4-dmenu-desktop (название выбрано с юмором) реализовал вот ровно то самое, что мне требуется: аналог i3-dmenu-desktop, только с опцией ведения истории команд и сортировки по самым частым. А еще утверждается, что оно побыстрее будет (хотя куда уж, казалось бы). Ну и наличествуют некоторые другие (не сильно нужные мне) опции.

В пакетной базе OpenBSD оно отсутствует, в портах тоже - но когда это было препятствием? Соберем из сорцов! Для сборки авторами, кстати, рекомендован meson, соответственно, сперва сделаем (если еще не) $ doas pkg_add meson

UPDATE Описанные ниже правки скрипта meson-setup.sh выполнять более не требуется: контрибьютор проекта молодец, мегаоперативно отреагировал заведенный тикет и выпустил патч, исправляющий проблему сборки на OpenBSD.
Теперь для сборки проекта достаточно выполнить следующие шаги:
$ git clone https://github.com/enkore/j4-dmenu-desktop
$ cd ./j4-dmenu-desktop
$ ./meson-setup.sh build
$ cd ./build
$ meson compile j4-dmenu-desktop
$ doas meson install

Далее по инструкции:

$ git clone https://github.com/enkore/j4-dmenu-desktop
$ cd ./j4-dmenu-desktop
$ ./meson-setup.sh build

и вот тут возникает легко устранимая проблема: под OpenBSD оно ругнется на

Check usable header "sys/event.h" : NO

src/meson.build:11:6: ERROR: Problem encountered: 
Couldn't determine notify implementation. Please set 
it with -Dnotify-implementation=<inotify or kqueue> 
when creating the builddir.

Лечится это строго по-написанному: открываем в редакторе файлик meson-setup.sh и 55-ю строчку приводим к виду (надо, кстати, разработчикам написать будет):

exec $DRYRUN meson setup --buildtype=release -Db_lto=true -Dnotify-implementation=kqueue "$1"

после чего всё должно пройти уже без проблем:

$ ./meson-setup.sh build
$ cd ./build
$ meson compile j4-dmenu-desktop
$ doas meson install

Еще небольшой нюанс: вместе с, собственно, бинарём j4-dmenu-desktop будет установлен и весьма небезынтересный man к нему, вот только положат его в нестандартное для OpenBSD место: /usr/local/share/man, где оно будет не видно опенковскому man с дефолтными настройками. Поскольку таким страдают и некоторые другие из собранных мной программ (например, xkb-switch-i3, который нам сегодня тоже пригодится), я считаю не лишним научить man искать странички и там тоже. Для этого копируем пример из /etc/examples/man.conf в /etc/man.conf и дописываем туда строчку manpath /usr/local/share/man, а потом выполняем doas makewhatis /usr/local/share/man чтоб оно проиндексировалось. Всё, RTFM доступно.

UPDATE Вышеописанную проблему можно пофиксить также используя стандартные флаги meson, указав, куда именно нужно класть man. Вот таким, например, образом: meson setup -Dprefix=/usr -Dmandir=local/man --buildtype=release build. А можно и как я предложил выше.

А теперь собственно о настройке под нехитрые требования, которые я изложил выше. У меня за час увлекательного красноглазия получилось такое мощное заклинание, что я даже не стал его пихать в конфиг i3, а сохранил отдельным скриптом. Вот он:

#!/bin/ksh

layout=$(xkb-switch)
xkb-switch -s us

j4-dmenu-desktop --dmenu="(cat ; (stest -flx $(echo $PATH | tr : ' ') | sort -u)) \
    | dmenu -fn 'Roboto Mono:style=Regular:size=9' \
    -nb '#282A2E' -sb '#373B41' -nf '#C5C8C6' -sf '#C5C8C6' -p '$' -i" \
    -I --term alacritty --usage-log /home/alexd/.cache/j4-dmenu-desktop.log 2>/dev/null

xkb-switch -s $layout

Краткая расшифровка: вызовы xkb-switch (о нем я писал не так давно) позволяет нам при старте лаунчера переключить раскладку на английскую, а по завершению восстановить прежнюю.

Заклинание --dmenu="(cat ; (stest -flx $(echo $PATH | tr : ' ') | sort -u)) | позволяет j4-dmenu-desktop подмешать к выдаваемым им по умолчанию .desktop-файлам еще и выбор программ из PATH и передать это пайпом на обработку dmenu.

Всякое там -fn 'Roboto Mono:style=Regular:size=9' -nb '#282A2E' -sb '#373B41' -nf '#C5C8C6' -sf '#C5C8C6' -p '$' - это абсолютная вкусовщина, нужная только лишь для того, чтобы менюшка выглядела наименее чужеродной в моем сетапе. А вот ключик -i для dmenu весьма важен - делает поиск нечувствительным к регистру.

Ну а оставшаяся часть строки - параметры j4-dmenu-desktop: -I активирует интеграцию с i3 IPC (я таки пользуюсь i3!), --term alacritty велит учитывать нюансы работы с конкретно мной используемым эмулятором терминала (в man j4-dmenu-desktop можно почитать про другие варианты), а --usage-log ~/.cache/j4-dmenu-desktop.log сообщает, где вести лог частотности запуска .desktop-файлов (вот запуск бинарей из PATH, правда, в лог не пишется, но да мне оно и не нужно).

Собственно, всё: я имею резкий как понос и нативно смотрящийся лаунчер, умеющий:

  • запускать софт через .desktop-файлы поиском по названию

  • выводить в списке самые часто запускаемые приложения первыми

  • запускать программы поиском по PATH, в том числе с возможностью передачи им параметров при запуске

  • и всё это даже без лишних переключений раскладки клавиатуры.

Пустячок, а приятно!