| Файл | Назначение |
|---|---|
| app.py | Интерфейс GTK 3: разделы, поиск, drag-and-drop, свойства, избранное и управление Undo/Redo. |
| menu_backend.py | Работа с Cinnamon CMenu, форматом XDG .menu / .desktop, пользовательскими overrides и журналом изменений. |
| install.py | Установка пользовательского ярлыка и файлов приложения; отдельные флаги для надстройки. |
| menu_bridge.py | Генератор необязательной пользовательской версии стандартного апплета Cinnamon с поддержкой порядка. |
| icon.svg | Значок редактора. |
| tests/ | Проверки перетаскивания/порядка, установки, изоляции и конфликтов. |
Основной редактор и механизм данных написаны на Python, не требуют отдельного демона и не открывают сетевых соединений. Для реального дерева приложений используется системная библиотека CMenu из Cinnamon. Основные параметры и команды запуска сохраняются в стандартных XDG файлах; формат .desktop применяется точечно, чтобы не удалять посторонние ключи и локализованные переводы.
При запуске backend загружает реальное дерево Cinnamon CMenu и формирует перечень разделов и соответствующих приложений. Имя, иконка, аргументы запуска и категории читаются из .desktop / .directory файлов. Правки принадлежности оформляются пользовательским .menu XML, без изменения системного дерева.
Для назначения папок/тегов контекстное меню показывает категории из CMenu как галочки. Состояние каждой галочки определяется фактической принадлежностью приложения. Установка добавляет в пользовательский .menu правило Include для выбранного раздела, а снятие добавляет Exclude для выбранного раздела и вложенных ветвей, оставляя другие привязки и исходный .desktop нетронутыми. Операции проходят через общий журнал отмены и его защиту от конфликтов. Настоящие теги здесь являются категориями меню Cinnamon, а не отдельными системными метками.
Порядок хранится отдельно от категорий. Пример ~/.config/mint-menu-studio/order.json:
{
"version": 1,
"categories": ["Internet", "Office", "Graphics"],
"apps": {
"@all": ["firefox.desktop", "org.gnome.Calculator.desktop"],
"Internet": ["firefox.desktop", "some-web-app.desktop"]
}
}Здесь приводится только пример ID приложений. Неизвестные и вновь установленные программы сохраняют базовый порядок Cinnamon после перечисленных пользователем элементов; удалённые элементы не блокируют работу. В избранном порядок управляется через стандартный ключ настроек Cinnamon, а не через order.json.
Backend ограничивает запись пользовательскими каталогами XDG и ведёт историю операций в ~/.local/state/mint-menu-studio/history.json. Для каждой операции сохраняются снимки изменённых файлов «до» и «после», а при необходимости предыдущее и следующее значение избранного. Журнал содержит указатель текущей позиции, поэтому Ctrl+Z / Ctrl+Shift+Z продолжают работать после перезапуска.
Перед записью выполняется проверка ожидаемого содержимого. Временный pending-журнал помогает восстановиться при прерывании записи. Запись файлов выполняется через временный файл и атомарную замену. Если другое приложение уже изменило затронутый файл, изменение блокируется, а чужая версия не стирается.
История не является резервной копией всего домашнего каталога. При переносе проекта и публикации в GitHub файлы пользовательских конфигураций и истории не включаются.
Стандартный апплет menu@cinnamon.org в Cinnamon 6.6.9 вызывает собственную логику сортировки разделов и приложений по отображаемым именам. Поэтому запись порядка в XDG .menu или собственном JSON без изменения механизма отображения не гарантирует эффекта в реальном меню. Простой редактор может упорядочить свои строки, но штатный апплет продолжит показывать алфавитный список.
menu_bridge.py решает это как opt-in:
- При явном вызове install.py --with-order-applet читает исходники стандартного апплета из /usr/share/cinnamon/applets/menu@cinnamon.org.
- Вносит ограниченные изменения в сортировку и наблюдение за пользовательским order.json.
- Генерирует пользовательскую версию в ~/.local/share/cinnamon/applets/menu@cinnamon.org.
- Записывает файл-маркер с SHA-256 всех управляемых файлов, чтобы не перезаписать сторонний апплет или локальные ручные правки.
- После ReloadXlet Cinnamon использует пользовательскую копию, сохраняя общую структуру и интерфейс обычного меню.
Никаких файлов системного пакета Cinnamon не изменяется. При изменении order.json пользовательский апплет подхватывает новый порядок. Если JSON отсутствует или повреждён, сортировка апплета возвращается к штатной. При несовпадении ожидаемых фрагментов исходников после обновления Cinnamon генератор останавливается и сохраняет старую копию без изменений.
При обычной установке install.py этот генератор не запускается. Повторный запуск обычного установщика не включает и не отключает уже установленную надстройку. Флаг --remove-order-applet удаляет только подтверждённую собственную версию; настройки порядка остаются.
Установка редактора использует Python 3, PyGObject (GI), GTK 3 и CMenu 3. Поведение надстройки проверено на исходниках Cinnamon 6.6.9. Другие версии могут отличаться в API или внутренней сортировке, поэтому после обновления рабочего окружения следует пересоздать надстройку и проверить загрузку меню, а при необходимости отключить её.
Исходный код самого редактора и генератора лицензирован MIT. Системный код апплета Cinnamon не включён в этот Git-репозиторий. Генерируемая на компьютере пользователя копия представляет собой модификацию исходного Cinnamon и подчиняется соответствующим условиям лицензирования установленной версии Cinnamon. Публикация одного лишь генератора под MIT не изменяет лицензии upstream-кода.
Для независимого аудита и вклада см. SECURITY.md, TESTING.md и TROUBLESHOOTING.md.