Linux & Tools
February 20

Интеграция приложения в KDE Plasma и его запуск в качестве системного сервиса

Для полной интеграции приложения в системе KDE Plasma и его запуска в качестве системного сервиса, нужно создать systemd-сервис, организовать StatusNotifierItem для systray, т.е. значок в системном трее, добавить в системные настройки KDE (скомпилировать KCModule) и радоваться сидеть точить печеньки.

Интеграция приложения в KDE Plasma

1. Создать systemd-сервис

Если приложение должно работать в качестве фонового сервиса, нужно создать unit-файл для systemd.

Шаги:

  1. Открыть терминал и создать файл службы: sudo nano /etc/systemd/system/myapp.service
  2. Добавить следующее содержимое, заменив 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 — пользователь и группа, от имени которых запускается процесс.
  1. Сохранить (CTRL+X, затем Y и Enter).
  2. Перезапустить systemd, чтобы загрузить новый сервис: sudo systemctl daemon-reload
  3. Включить сервис для автозапуска: sudo systemctl enable myapp
  4. Запустить сервис: sudo systemctl start myapp
  5. Проверить статус работы: sudo systemctl status myapp

2. Добавить в автозагрузку KDE (для GUI-приложений)

Если приложение имеет графический интерфейс и должно запускаться при входе пользователя, то лучше использовать автозапуск KDE.

Способ 1: Добавление через GUI

  1. "Параметры системы" → "Автозапуск"
  2. Нажать "Добавить программу", выбрать исполняемый файл.

Способ 2: Создать .desktop-файл

  1. Создать файл в ~/.config/autostart/: nano ~/.config/autostart/myapp.desktop
  2. Добавить содержимое:
[Desktop Entry] 
Type=Application 
Exec=/usr/bin/myapp 
Hidden=false 
NoDisplay=false 
X-GNOME-Autostart-enabled=true 
Name=MyApp 
Comment=Запуск моего приложения 
  1. Сохранить (CTRL+X, затем Y и Enter).

После выхода из системы и повторного входа приложение автоматически запустится.


Выбор метода

  • Если это серверное/фоновое приложение → использовать 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.

  1. Установить библиотеку KDE Frameworks 5: sudo apt install libkf5config-dev
  2. Использовать 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).

  1. Создаём .desktop-файл модуля KDE:
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 
  1. Создаём KCM-файл на C++:

#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"))

  1. Компиляция KCM:

g++ -o myappconfig.so myappconfig.cpp $(pkg-config --cflags --libs KF5ConfigWidgets) -shared -fPIC sudo mv myappconfig.so /usr/lib/qt/plugins/

Теперь настройки появятся в системных параметрах KDE!


Заключение

  1. Добавить значок в трей:
    • Через QSystemTrayIcon (если Qt)
    • Через DBus SNI (если C без Qt)
  2. Сохранение настроек:
    • Использовать KConfig
  3. Добавление в "Параметры системы" KDE:
    • Создать KCModule