Архитектура и модульная структура JES

July 23, 2026 · View on GitHub

Архитектурные принципы

  • Разделение UI и логики: QML (Quickshell) отвечает только за рендеринг и ввод. Вся обработка данных, парсинг IPC и системные вызовы вынесены в отдельные модули.
  • Модульность по назначению: Каждый компонент интерфейса (бар, лаунчер, уведомления и т.д.) изолирован в собственной папке. Минимум перекрёстных зависимостей.
  • Событийная модель (subscribe): Вместо polling в bash-циклах используются долгоживущие соединения через Go-бинарники, подписывающиеся на события WM/MPD/системы.
  • Стабильный шелл-слой: Скрипты написаны на POSIX sh/bash. Нет зависимостей от fish/zsh runtime, плагинов или интерактивных фич.
  • Динамическая тема: base16.json использует палитру zenburn. colors.json отвечает за градиентные фоны, текст и акцентные цвета, всё извлекается из обоев благодарая matugen.

-- Дерево рабочей части проекта и назначение модулей --:

.
├── shell.qml                 # Точка входа Quickshell. Регистрирует и позиционирует модули.
├── bar/                      # Панель.
│   ├── components/           # Попапы панели + кнопки воркспейсов.
│   └── images/               # Статические иконки, ассеты.
├── launcher/                 # Лаунчер приложений: поиск, категории, фоновый шейдер, Go-бэкенд.
├── wallpaper/                # Выбор и рендер обоев: превью, применение, TOML-конфиг, рендер обоев.
├── notifications/            # Демон уведомлений.
├── popSysInf/                # Всплывающее окно системной информации (Яркость, Громкость).
├── power/                    # Меню сессии: выключение, перезагрузка, сон, выход, лок.
├── helpers/                  # QML-хелперы.
├── screenpicker/             # Скриншотилка.
└── scripts/                  # Ядро логики: скомпилированные Go-бинарники + bash-скрипты.

-- Поток данных и IPC --:

  1. Инициализация: shell.qml запускает модули. Каждый модуль при старте вызывает соответствующий скрипт из scripts/.
  2. Сбор данных:
    • Go-бинарники (music, Cava-internal, cal) берут на себя логику с большими объёмами данных, которые надо обработать.
    • Bash-скрипты (brightness.sh, vol.sh, workspace-*.sh, ...) являются основной логикой, сделано для переносимости системы и читаемости.
  3. Доставка в UI: Данные передаются через stdout (JSON или для визуальных программ просто строка (как cava)) → парсятся в QML через JsonListen/JsonPoll → обновляют свойства виджетов.
  4. Обратная связь: Действия пользователя (клик, хоткей) → вызов скрипта/бинарника → отправка команды в WM/MPD/pipewire → событие обновляет UI.

-- Стек и оптимизация --:

СлойТехнологияРоль
WMswayfx (primary), DriftWM (primary), Hyprland, Niri (WIP)Тайлинг, эффекты, IPC
UIQuickshell (Qt Quick / QML)Рендеринг, анимации, ввод
BackendGo 1.21+Логика, обрабатывающая большие объёмы данных
ShellBash 5.x / POSIX shОсновная логика
Themebase16 + matugenСтатичная палитра + динамическая тема
LockHyprlockЭкран блокировки
AudioPipeWire + pavucontrol-qtМикширование, MPRIS, Cava

Метрики: CPU idle ~5–10% (Go subscribe) против 35–45% (bash polling). Бинарники собраны статически, вес логики ~3.5-4.5 МБ.

-- Слой совместимости WM --:

Абстракция от тайлинга реализована через три пары скриптов и один файл для подключения к shell.qml:

  • active_window-{sway,hypr,niri}.sh
  • kb_layout-{sway,hypr,niri,driftwm}.sh
  • workspace-{sway,hypr,niri,driftwm}.sh
  • {Sway,Hypr,niri}Bar.qml в папке quickshell подкаталоге bar/

Quickshell определяет текущий WM через $XDG_CURRENT_DESKTOP, маршрутизируя вызовы к нужному скрипту. Для портирования на новый тайлинг достаточно реализовать вывод в том же JSON-формате и добавить маппинг.

-- Как расширять --:

  1. Новый виджет: Создать папку widget_name/ → QML-компонент + бэкенд (Go/sh) → зарегистрировать в shell.qml.
  2. Смена темы: Отредактировать конфиг matugen (можно ещё переписать base16.json, но он почти не влияет на визуальную часть JES) → перегенерировать палитру.
  3. Добавление WM: Реализовать IPC-парсер под спецификацию вывода существующих скриптов → добавить в маршрутизацию.
  4. Оптимизация: Заменить polling-скрипт на Go-бинарник с subscribe → обновить вызов в QML.

-- Прочее --:

  • UI-слой (QML): GPL-3.0
  • Скрипты и бинарники: GPL-3.0
  • Предпочитается постоянный вывод от скриптов/бинарников для улучшения производительности
  • Ассеты (шейдеры, исходники go, пустые скрипты-болванки и qml файл-болванку для подключения другого тайлинга): см. for-quickshell/

-- Плагины --:

Установка

1. откройте ~/.config/quickshell/
2. закиньте папку с плагином
3. откройте config.toml
4. впишите данные строки:
   [[plugin]]
   name = "plugin name" # data in property name from manifest.json
   active = true

Подробная инструкция создания плагинов