Hatred's Log Place

DON'T PANIC!

Jan 30, 2021 - 3 minute read - Linux

Структура XDG menu

Нельзя вот так просто взять и создать MyProgram.desktop файл в главном меню какого-нить KDE ручками из консоли. Особенно если путь вроде Menu → Wine → Programs → Some Application

Казалось бы, просто идём в ~/.local/share/applications/wine/Programs/Some Application и создаём MyProgram.desktop с нужным содержимым. Ан нет. Во-первых, программа появится в меню только после рестарта или после выполнения команды:

kbuildsycoca5

Во-вторых, она появится совсем в другом месте, а именно в Menu → Прочее. Вот это поворот…

Теория

На самом деле, за структуру меню отвечает достаточно развесистое дерево с файлами различного содержания. Далее краткий пересказ информации, доступной по ссылкам:

А так же не повредит гуглинг на предмет freedesktop.org Desktop Menu Specification.

И так, для создания иерархии меню, нам нужно:

  1. Desktop файлы - сами файлы запуска приложений. Наш MyProgram.desktop может выглядеть так:

    [Desktop entry]
    Type=Application
    Name=My Program
    Comment=My super program
    Exec=my-program
    Categories=Game;Internet
    

    Все поля описаны в спецификации, а поле Categories нужно для размещения внутри меню в одной из стандартных категорий.

    Находятся все эти файлы в ~/.local/share/applications. Ну или в системе, в /usr/share/applications

  2. Файлы описаний директорий - *.directory. Находятся в ~/.local/share/desktop-directories. Через них можно описать каждый уровень вложенных категорий, назначит подсказку, имя, иконку. Примерное содержимое:

    [Desktop entry]
    Type=Directory
    Name=Your App Folderdd
    
  3. Ну и то, что это всё склеивает: Menu-файлы (*.menu). Это уже XML описания. Обычно, создаются при помощи хелпера xdg-desktop-menu. Собственно тут и описывается иерархия меню. Сам файл может выглядеть так:

    <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
    <!-- Do not edit manually - generated and managed by xdg-desktop-menu -->
    <Menu>
        <Name>Applications</Name>
        <Menu>
            <Name>MyProgram</Name>
            <Include>
                <Filename>MyProgram.desktop</Filename>
            </Include>
        </Menu>
    </Menu>
    

    Здесь создаётся меню с одним вложенным пунктом. А вот следующий файл создаёт более развесистое меню:

    <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
    <!-- Do not edit manually - generated and managed by xdg-desktop-menu -->
    <Menu>
        <Name>Applications</Name>
        <Menu>
            <Directory>YourApp-top.directory</Directory>
            <Name>YourApp-top</Name>
            <Menu>
                <Directory>YourApp-second.directory</Directory>
                <Name>YourApp-second</Name>
                <Include>
                    <Filename>MyProgram.desktop</Filename>
                </Include>
            </Menu>
        </Menu>
    </Menu>
    

    И находится всё это безобразие в: ~/.config/menus/applications-merged

Самый простой способ создать запись, это вызвать:

xdg-desktop-menu install YourApp-dir.directory MyProgram.desktop

создаст что-то вроде первого меню. Для более сложных случаев - ручками. Ну или через редактор меню того же KDE ;-)

Практика

А теперь поглядим как это может выглядеть на реальных примерах.

Для начала Desktop файлы (их несколько, но посмотрим на один):

  • .local/share/applications/wine/Programs/IDA Pro 7.5/IDA Pro\ (64-bit).desktop

    [Desktop Entry]
    Name=IDA Pro (64-bit)
    Exec=env WINEPREFIX="/home/user/.wine" /usr/bin/wine C:\\\\windows\\\\command\\\\start.exe /Unix /home/user/Downloads/soft/IDA\\ Pro\\ 7.5/ida64.exe
    Type=Application
    StartupNotify=true
    Path=/home/user/Downloads/soft/IDA Pro 7.5
    Icon=3567_ida64.0
    StartupWMClass=ida64.exe
    

Затем описание директорий. Часть уже создано самим Wine:

  • ~/.local/share/desktop-directories/wine-wine.directory:

    [Desktop Entry]
    Type=Directory
    Name=Wine
    Icon=wine
    
  • ~/.local/share/desktop-directories/wine-Programs.directory:

    [Desktop Entry]
    Type=Directory
    Name=Programs
    Icon=folder
    
  • ~/.local/share/desktop-directories/wine-Programs-IDA Pro 7.5.directory:

    [Desktop Entry]
    Type=Directory
    Name=IDA Pro 7.5
    Icon=folder
    

И теперь меню:

  • ~/.config/menus/applications-merged/wine-Programs-IDA Pro 7.5-IDA Pro (64-bit).menu (и так для каждого desktop-файла (???)):

    <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"
    "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">
    <Menu>
      <Name>Applications</Name>
      <Menu>
        <Name>wine-wine</Name>
        <Directory>wine-wine.directory</Directory>
      <Menu>
        <Name>wine-Programs</Name>
        <Directory>wine-Programs.directory</Directory>
      <Menu>
        <Name>wine-Programs-IDA Pro 7.5</Name>
        <Directory>wine-Programs-IDA Pro 7.5.directory</Directory>
        <Include>
          <Filename>wine-Programs-IDA Pro 7.5-IDA Pro (64-bit).desktop</Filename>
        </Include>
      </Menu>
      </Menu>
      </Menu>
    </Menu>
    

Ну и на KDE запускаем после всего созданного kbuildsycoca5:

$ kbuildsycoca5 --menutest | grep 'IDA Pro 7.5'
kbuildsycoca5 running...
Wine/Programs/IDA Pro 7.5/      wine-Programs-IDA Pro 7.5-IDA Pro (64-bit).desktop

Радуемся, что приложение ровно там, где мы и хотели :) Ну а для меню, просто убираем агрумент и оно перестроит бинарный кеш.

Вместо заключения

Каждый раз подтверждается истина, пусть и не прописная: чем проще вещь снаружи, тем сложнее она устроена внутри. Мы все зубоскалили по поводу реестра Windows. Но уже имеем практически полный аналог в виде GConf бинарный внутри и недоступный для управления без внешних специализированных программ. При этом разбавленный отдельными конфигурационными файлами, специфичными для конкретных утилит. Благо решили собрать их в ~/.config. А потом и его перестало хватать, появились ~/.local, ~/.cache и т.п.

Хорошо это или плохо сможет показать только время. Точно одно: чем больше сущностей, тем сложнее их все реализовать, тем более - реализовать хорошо.