Интеграция приложения в KDE Plasma и его запуск в качестве системного сервиса
Для полной интеграции приложения в системе KDE Plasma и его запуска в качестве системного сервиса, нужно создать systemd-сервис, организовать StatusNotifierItem для systray, т.е. значок в системном трее, добавить в системные настройки KDE (скомпилировать KCModule) и радоваться сидеть точить печеньки.
1. Создать systemd-сервис
Если приложение должно работать в качестве фонового сервиса, нужно создать unit-файл для systemd.
Шаги:
- Открыть терминал и создать файл службы:
sudo nano /etc/systemd/system/myapp.service - Добавить следующее содержимое, заменив
myappна реальное имя приложения:
[Unit] Description=My Custom App After=network.target [Service] ExecStart=/usr/bin/myapp Restart=always User=myuser Group=mygroup [Install] WantedBy=multi-user.target
- ExecStart — путь к исполняемому файлу приложения.
- User/Group — пользователь и группа, от имени которых запускается процесс.
- Сохранить (
CTRL+X, затемYиEnter). - Перезапустить
systemd, чтобы загрузить новый сервис:sudo systemctl daemon-reload - Включить сервис для автозапуска:
sudo systemctl enable myapp - Запустить сервис:
sudo systemctl start myapp - Проверить статус работы:
sudo systemctl status myapp
2. Добавить в автозагрузку KDE (для GUI-приложений)
Если приложение имеет графический интерфейс и должно запускаться при входе пользователя, то лучше использовать автозапуск KDE.
Способ 1: Добавление через GUI
Способ 2: Создать .desktop-файл
[Desktop Entry] Type=Application Exec=/usr/bin/myapp Hidden=false NoDisplay=false X-GNOME-Autostart-enabled=true Name=MyApp Comment=Запуск моего приложения
После выхода из системы и повторного входа приложение автоматически запустится.
Выбор метода
- Если это серверное/фоновое приложение → использовать
systemd. - Если это GUI-приложение → добавить в автозапуск KDE через
~/.config/autostart/.
Если нужно запускать GUI-приложение через systemd, то ExecStart в .service-файле нужно изменить на:
ExecStart=/usr/bin/env DISPLAY=:0 /usr/bin/myapp
Это укажет, что приложение должно работать в графической среде.
Чтобы приложение на C интегрировалось в системный трей KDE Plasma и его настройки можно было управлять через системные параметры, нужно использовать StatusNotifierItem (SNI) и KConfig.
1. Добавление значка в системный трей (StatusNotifierItem)
KDE Plasma больше не поддерживает старый XEmbed, поэтому нужно использовать DBus интерфейс SNI. Для этого можно использовать Qt или писать вручную через DBus.
Способ 1: Использование Qt и QSystemTrayIcon
Если приложение уже использует Qt, то можно просто использовать QSystemTrayIcon:
#include <QApplication>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QSystemTrayIcon trayIcon;
trayIcon.setIcon(QIcon(
"/usr/share/icons/hicolor/48x48/apps/myapp.png"));
QMenu menu;
QAction exitAction("Выход", &app);
QObject::connect(
&exitAction, &QAction::triggered, &app, &QApplication::quit);
menu.addAction(&exitAction);
trayIcon.setContextMenu(&menu);
trayIcon.show();
return app.exec();
}
🔹 Этот код создаст значок в трее с контекстным меню.
⚠️ Важно: Если значок не отображается, установите пакет libappindicator:
sudo apt install libappindicator3-1
Способ 2: Реализация SNI через DBus
Если приложение не использует Qt, можно зарегистрировать значок вручную через DBus. Вот пример на C:
#include <stdio.h>
#include <stdlib.h>
#include <gio/gio.h>
int main() {
GDBusConnection *connection;
GError *error = NULL;
// Подключаемся к DBus
connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
if (error) {
g_printerr("Ошибка подключения к DBus: %s\n", error->message);
g_error_free(error);
return 1;
}
// Регистрируем значок в трее
g_dbus_connection_call_sync
(connection,
"org.kde.StatusNotifierWatcher",
"/StatusNotifierWatcher",
"org.kde.StatusNotifierWatcher",
"RegisterStatusNotifierItem",
g_variant_new
("(s)", "/org/myapp/StatusNotifierItem"),
NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error) {
g_printerr("Ошибка регистрации SNI: %s\n", error->message);
g_error_free(error);
return 1;
}
printf("Значок добавлен в трей!\n");
return 0;
}
Этот код регистрирует StatusNotifierItem в Plasma через DBus.
2. Интеграция в системные настройки (KConfig)
Чтобы приложение сохраняло настройки в системных параметрах KDE, можно использовать KConfig.
- Установить библиотеку KDE Frameworks 5:
sudo apt install libkf5config-dev - Использовать KConfig в коде:
#include <KConfig>
#include <KConfigGroup>
#include <QString>
#include <QDebug>
void saveSettings() {
KConfig config("myappsettingsrc");
KConfigGroup group(&config, "General");
group.writeEntry("showTrayIcon", true);
config.sync();
}
void loadSettings() {
KConfig config("myappsettingsrc");
KConfigGroup group(&config, "General");
bool showTray = group.readEntry("showTrayIcon", true);
qDebug() << "Значок в трее:" << showTray;
}
int main() {
saveSettings();
loadSettings();
return 0;
}
🔹 Файл конфигурации сохранится в ~/.config/myappsettingsrc.
3. Добавление в системные настройки KDE (KCModule)
Если нужно, чтобы приложение имело свой пункт в "Параметры системы", то создаётся KCM (KDE Configuration Module).
sudo nano /usr/share/kservices5/myapp.desktop Содержимое: [Desktop Entry] Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=myappconfig X-KDE-PluginInfo-Name=myapp X-KDE-PluginInfo-Category=Settings Name=Настройки MyApp Comment=Конфигурация приложения MyApp
#include <KCModule> #include <KAboutData> #include <KPluginFactory> #include <QVBoxLayout> #include <QCheckBox> class MyAppConfig : public KCModule { Q_OBJECT public: MyAppConfig(QWidget *parent, const QVariantList &) : KCModule(parent) { auto *layout = new QVBoxLayout(this); auto *checkbox = new QCheckBox("Показывать значок в трее", this); layout->addWidget(checkbox); } }; K_PLUGIN_FACTORY(MyAppConfigFactory, registerPlugin<MyAppConfig>();) K_EXPORT_PLUGIN(MyAppConfigFactory("myappconfig"))
g++ -o myappconfig.so myappconfig.cpp $(pkg-config --cflags --libs KF5ConfigWidgets) -shared -fPIC sudo mv myappconfig.so /usr/lib/qt/plugins/
Теперь настройки появятся в системных параметрах KDE!