Pull to refresh

Немного о libunique

Reading time3 min
Views1.4K
Сегодня я хотел бы рассказать об одном из способов создания приложения, имеющего один экземпляр — библиотека LibUnique.

Зачем это нужно?

В моём случае это понадобилось при написании небольшого апплета-календарика для панели tint2. Хотелось, чтобы при клике на часы показывался календарик, при повторном клике — скрывался, как в gnome-panel. Сперва мне мешал тот факт, что в tint2 не было такого функционала. Но это же open source! Вечер на чтение кода, вечер на написание патча… Теперь в tint2 такой функционал есть.

Затем я начал искать, что же может послужить в качестве такого апплета, но не нашёл ничего подходящего. Orage был слишком тяжёлым, zenity --calendar выскакивал по центру экрана, и его нельзя было закрыть повторным щелчком на часы. В итоге я решил написать свой маленький календарик: gsimplecal. Тем более, что хотелось попробовать написать что-нибудь под Linux.

На его примере и рассмотрим использование LibUnique.

Давайте уже писать код


Для начала ссылка на полный листинг.

На самом деле всё очень просто, и суть этого поста скорее в том, чтобы дать знать о существовании такого решения. А с таким знанием потребуется выполнить всего несколько шагов:
  1. Для начала, разумеется, нам потребуется подключить заголовочный файл unique.h.
    #include <unique/unique.h>

  2. Затем, где-то в самом начале функции main, необходимо вызвать функцию unique_app_new, передав ей идентификатор приложения в виде доменного имени, вроде «ru.habrahabr.singletone_app».

    int main(int argc, char *argv[])
    {
        UniqueApp *app;
        app = unique_app_new("org.dmedvinsky.gsimplecal", NULL);


    Если вы хотите использовать собственные команды (из предопределённых есть ACTIVATE, NEW, OPEN, CLOSE), то можно вместо unique_app_new вызвать сразу unique_app_new_with_commands (команды можно добавить и отдельно, вызвав unique_app_add_command).

  3. После этого вызвать функцию unique_app_is_running, и действовать в зависимости от её результата:
    • true: послать уже существующему экземпляру одно из предопределённых или же кастомных сообщений.

          if (unique_app_is_running(app)) {
              unique_app_send_message(app, UNIQUE_CLOSE, NULL);
          }

    • false: программа запущена первый раз; нужно создать наше окно и присоединить к нему обработчик сообщений от libunique.

          else {
              create_main_window();
              unique_app_watch_window(app, GTK_WINDOW(main_window));
              g_signal_connect(app, "message-received", G_CALLBACK(message_received_cb), NULL);
          }
  4. Собственно, написать сам обработчик сообщений.

    static UniqueResponse message_received_cb(UniqueApp *app, UniqueCommand command,
            UniqueMessageData *message, guint time_, gpointer user_data)
    {
        if (command == UNIQUE_CLOSE) {
            gtk_signal_emit_by_name(GTK_OBJECT(main_window), "destroy");
        }

        return UNIQUE_RESPONSE_OK;
    }

  5. Не забыть подчистить за собой.
        g_object_unref(app);

  6. ...
  7. Profit!
Tags:
Hubs:
+21
Comments24

Articles

Change theme settings