Сегодня я хотел бы рассказать об одном из способов создания приложения, имеющего один экземпляр — библиотека LibUnique.
Затем я начал искать, что же может послужить в качестве такого апплета, но не нашёл ничего подходящего. Orage был слишком тяжёлым, zenity --calendar выскакивал по центру экрана, и его нельзя было закрыть повторным щелчком на часы. В итоге я решил написать свой маленький календарик: gsimplecal. Тем более, что хотелось попробовать написать что-нибудь под Linux.
На его примере и рассмотрим использование LibUnique.
Для начала ссылка на полный листинг.
На самом деле всё очень просто, и суть этого поста скорее в том, чтобы дать знать о существовании такого решения. А с таким знанием потребуется выполнить всего несколько шагов:
Зачем это нужно?
В моём случае это понадобилось при написании небольшого апплета-календарика для панели tint2. Хотелось, чтобы при клике на часы показывался календарик, при повторном клике — скрывался, как в gnome-panel. Сперва мне мешал тот факт, что в tint2 не было такого функционала. Но это же open source! Вечер на чтение кода, вечер на написание патча… Теперь в tint2 такой функционал есть.Затем я начал искать, что же может послужить в качестве такого апплета, но не нашёл ничего подходящего. Orage был слишком тяжёлым, zenity --calendar выскакивал по центру экрана, и его нельзя было закрыть повторным щелчком на часы. В итоге я решил написать свой маленький календарик: gsimplecal. Тем более, что хотелось попробовать написать что-нибудь под Linux.
На его примере и рассмотрим использование LibUnique.
Давайте уже писать код
Для начала ссылка на полный листинг.
На самом деле всё очень просто, и суть этого поста скорее в том, чтобы дать знать о существовании такого решения. А с таким знанием потребуется выполнить всего несколько шагов:
- Для начала, разумеется, нам потребуется подключить заголовочный файл unique.h.
#include <unique/unique.h>
- Затем, где-то в самом начале функции 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).
- После этого вызвать функцию 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);
}
- true: послать уже существующему экземпляру одно из предопределённых или же кастомных сообщений.
- Собственно, написать сам обработчик сообщений.
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;
}
- Не забыть подчистить за собой.
g_object_unref(app);
- ...
- Profit!