Привет, Хабр! Меня зовут Артём, и я ведущий дизайнер РЕД ОС. В сегодняшнем материале расскажу, как мы нашли решение, которое позволяет привести приложения РЕД ОС 8 к единому стилю в разных графических окружениях и добиться автоматизации этого процесса. Наш опыт пригодится разработчикам и дизайнерам интерфейсов, а также будет интересен тем, кто следит за развитием продукта.
Проблемы и вопросы
В последнее время мы активно развиваем дизайн в РЕД ОС 8. У нас было множество целей, но главной задачей стало приведение графических оболочек к единому фирменному стилю. Мы уделили внимание темам оформления различных графических окружений (DE), наборам иконок, курсорам, дизайну менеджеров авторизации, обоям для рабочего стола и многому другому. Теперь настало время для редизайна наших собственных приложений, которые стали выбиваться из фирменного стиля.


В РЕД ОС 8 пользователям доступны три основных графических окружения: KDE Plasma, MATE и GNOME, каждое из которых использует различные фреймворки — QT, GTK3 и GTK4 соответственно. Это привело к возникновению ключевых вопросов: "На каком из фреймворков стоит разрабатывать интерфейс приложений?" и "Как унифицировать дизайн интерфейсов приложений?".
Так возникла необходимость автоматизировать процесс оформления приложений:
Во-первых, это позволит избежать ручного прописывания стилей для каждого отдельного приложения.
Во-вторых, это существенно сокращает время на верстку и разработку.
В-третьих, хотелось реализовать возможность применять тему оформления независимо от рабочего окружения, настраивая ее исключительно для конкретного приложения.
Решения
Различия фреймворков и унификация стиля
Стало очевидно, что необходимо привести к единому стилю не только оформление DE, но и оформление всех компонентов, начиная от стиля окон и заканчивая мелкими элементами, такими как кнопки, чекбоксы и другие.
Настройка дизайна через темы оформления
Настройка дизайна осуществляется через темы оформления рабочей среды. В KDE Plasma это реализовано проще благодаря использованию движка Plasma-Breeze, который автоматически обрабатывает все компоненты. Дополнительная настройка включает цветовые схемы, представленные в виде конфигурационных файлов с RGB-значениями.

С MATE и GNOME ситуация сложнее, так как темы оформления разделены на множество частей, каждая из которых отвечает за свои настройки. Нас интересуют только некоторые из них, такие как темы GTK3 и GTK4, которые основаны на CSS-стилях. Эти стили требуют отдельной настройки для каждого компонента. Кроме того, существуют отдельные элементы интерфейса, такие как чекбоксы, представленные в виде изображений, что позволяет их гибко кастомизировать.
Процесс создания унифицированных тем
Процесс начинается с использования готовой темы KDE, основанной на стиле Plasma-Breeze и цветовой схеме. Каждый компонент переносится в дизайн-библиотеку, что позволяет создавать макеты быстрее, используя унифицированные элементы, идентичные десктопным.

Затем подготавливается тема оформления для GTK: стандартные компоненты адаптируются под стиль библиотеки QT. После подготовки всех компонентов они переносятся в тему оформления GTK, благодаря гибкой кастомизации с помощью CSS.
Универсальное решение для фреймворка Qt
Итак, нам нужно добиться того, чтобы можно было разово и на уровне системы настроить определенный модуль в графическом окружении и больше не возвращаться к вопросу оформления каждого приложения. Все изменения должны решаться обобщенным подходом. Изменяя общие настройки и стили оформления определенного модуля, сами изменения сразу применялись бы и к нашим приложениям, без необходимости внесения уникальных правок и пересборок.
Решение. Наша команда приступила к поиску универсального решения проблем для фреймворка Qt, который мы решили выбрать основным. После изучения различных вариантов, возможностей выбранного фреймворка и тщательного анализа документации, стало ясно, как реализовать эту задачу.
Существуют инструменты настройки для приложений Qt — утилиты qt5ct и qt6ct. Они позволяют пользователям настраивать внешний вид приложений Qt, включая темы, шрифты и значки, особенно в средах рабочего стола, отличных от KDE Plasma, где интеграция с Qt часто отсутствует.

Эти утилиты позволяют выбрать в качестве оформления фреймворка один из движков. Например Plasma-Breeze, на котором, как упоминалось ранее, и основана наша тема KDE Plasma. Сам по себе движок Plasma-Breeze по умолчанию использует палитру с синими оттенками, но если он находит конфигурационный файл с цветовой схемой, то переопределяет стандартное оформление и отображает компоненты в нужных оттенках.
На скриншотах показано одно и то же приложение до и после применения переменного окружения qt5ct:
Еще одной проблемой было использование Plasma-Breeze конфигурационного файла цветовой схемы, что ограничивало нас выбором лишь одной темы — либо светлой, либо тёмной. Нам хотелось реализовать автоматическое переключение темы для каждого приложения, чтобы процесс был более удобным и автоматизированным. Для этого требовалось синхронизировать темы оформления графического окружения с цветовыми схемами, используемыми в qt5ct.
Решение: мы разработали небольшой скрипт. Он использует gsettings API для проверки выбранной темы оформления рабочего стола и, в зависимости от нее, автоматически настраивает цветовую схему наших приложений.


Осталось решить, когда именно должен запускаться этот скрипт. Учитывая, что у каждого пользователя могут быть свои настройки оформления, мы создали пользовательский сервис systemd. Чтобы сервис не работал постоянно, мы реализовали его вызов через триггер. Этот триггер настроен на systemd path и срабатывает при изменении темы оформления графического окружения.
Вывод
В ходе работы над дизайном в РЕД ОС 8 мы столкнулись с задачами унификации стиля приложений в различных графических окружениях. Использование QT5, GTK3 и GTK4 потребовало универсальных решений для сохранения единого стиля и упрощения разработки.
С помощью qt5ct мы создали унифицированный дизайн, автоматически применяемый к приложениям, что сократило время на верстку и упростило дизайн-ревью.
Наше решение включало скрипт для синхронизации тем и пользовательский сервис systemd, автоматизирующий применение цветовых схем. Это сделало систему более гибкой и удобной для пользователей, обеспечивая соответствие фирменному стилю и комфортные условия работы.
Таким образом, использование универсальных инструментов упростило разработку и обновления дизайна.
dyadyaSerezha
Удивительно, что в Линуксе до сих пор нет единого механизма настройки стиля всех приложений, если только они сами явно не изменяют этот дефолтный стиль. Если я правильно всё понял.
А почему в тёмном варианте не виден заголовок окна?
Чекбоксы в виде картинок? Это значит, там целый набор на все возможные разрешения и размеры экрана и скейлинги (увеличения/уменьшения дефолта в процентах)? А если нет, как это решается? Просто скейлится сама иконка? Странно все это..
RedEyedAnonymous
Если б/м коротко и упрощенно - то нет никакого "Линукса".
Есть ядро Linux, есть концепт в виде "ядро плюс GNU coreutils и чего-то ещё", поверх этого, если на выходе предполагается десктопная, а не серверная ОС, нахлобучена графика в виде Xorg или Wayland, поверх еще Window Manager и/или Desktop Environment, а на основе этого конструктора настрогано 100500 Linux-based операционок, по историческим причинам называемых "дистрибутивами", и в каждом "дистрибутиве" свои заморочки насчёт UI.
Где есть общесистемная настройка тем, где частичная (для примера, в KDE Plasma можно единообразно настраивать темы для Qt и GTK, в GNOME на Qt плевать хотели, и т.п.).
В общем, конечный пользователь получает Lego, из которого собран некий типовой (с т.з. сборщиков конкретного "дистрибутива") объект, и к нему ещё дают мешок деталей и чертежи.
Extortioner
Еще есть отдельный круг ада в виде зоопарка из версий gtk с вишенкой в виде libadwaita и все это еще сверху приправлено собственным фреймворком от огнелиса, который вообще никто не хочет интегрировать ни в какое DE в адекватном виде
RedEyedAnonymous
В случая моей федуры - всего-то две версии - 3 и 4. И две Qt (что-то осталось на 5х).
В кедо-федоре прикрутил kvantum со скином "под адвайту" - и всё стало единообразно.
Кедовые цветовые схемы средствами оных кед подхватываются всем, кроме того огнелиса, а что там под капотом для этого шевелится - мне не слишком интересно.
bergentroll
Дистрибутив — это распространяемый набор ПО, грубо говоря, чем дистрибутивы ОС и являются. Самостоятельными ОС дистрибутивы GNU/Linux сложно назвать, компоненты ± общие, различия в конфигах, патчах, пакетных менеджерах (и то не всегда), составе ПО «из коробки».
Вариантов «теминга» не особо много — это пара актуальных версий GTK с довольно единообразным видом и пара актуальных версий Qt с довольно единообразным видом, но несколькими вариантами его реализрвать. Другие тулкиты есть, но они не мейнстрим, и в лучшем случае мимикрируют под мейнстримные. GTK и Qt в приличном дистрибутиве имеют консистентные по цветам и более-менее по габаритам темы.
RedEyedAnonymous
Этого уже хватает, чтобы взятый из условной федоры случайный бинарник мог не запуститься в условной убунте и наоборот.
bergentroll
Ну, да, и это не аргумент в пользу «Fedora и Ubunta — две разные ОС». Есть понятие ABI, говорящее о «бинарной совместимости», и ABI может не совпадать у разных сборок разных версий библиотеки. При этом API сторонних библиотек дистрибутивы обычно не ломают.
Если пересобрать исходники того бинарника из одного дистрибутива на другом дистрибутиве, новый бинарник будет работать. Это распространённый путь для СПО.
В то же время у дистрибутивов GNU/Linux, и даже не GNU, не беря какую-нибудь экзотику для каких-нибудь специальных случаев, одинаковый формат исполняемых файлов. Так что если взять бинарник с одного дистрибутива и пересобрать его зависимости на другом дистрибутиве, он будет работать! (Опять же, не беря перенос между несовместимыми процессорными архитектурами). Примерно таким образом, со своими сборками библиотек, поставляется например:
Проприетарное ПО в
/opt/
.AppImage'и.
ПО на Microsoft Windows.
Более того, по аналогии если взять два экземпляра Microsoft Windows одинаковой версии, и на одном не будет необходимой версии .NET Framework, то зависящий от неё бинарник сможет работать на одном экземпляре, но не на другом. Что не побуждает называть эти два экземпляра разными ОС.