A bit about libunique

    Today I would like to talk about one of the ways to create an application that has one instance - the LibUnique library .

    Why is this needed?

    In my case, this was needed when writing a small calendar applet for the tint2 panel . I wanted the calendar to appear when I click on the watch, when I click it again, it’s hidden, like in the gnome-panel. At first, the fact that tint2 did not have such functionality bothered me. But this is open source! An evening for reading code, an evening for writing a patch ... Now tint2 has such functionality.

    Then I began to look for what could serve as such an applet, but I did not find anything suitable. Orage was too heavy, zenity --calendar popped up in the center of the screen and could not be closed by clicking on the clock again. In the end, I decided to write my little calendar: gsimplecal. Moreover, I wanted to try to write something under Linux.

    Using his example, we consider the use of LibUnique.

    Let's write the code already

    First, a link to the full listing .

    In fact, everything is very simple, and the essence of this post is rather to let know about the existence of such a solution. And with such knowledge, it will take only a few steps:
    1. To begin with, of course, we need to include the unique.h header file .

    2. Then, somewhere at the very beginning of the main function, you need to call the unique_app_new function , passing it the application identifier in the form of a domain name, like "ru.habrahabr.singletone_app" . If you want to use your own commands (there are ACTIVATE , NEW , OPEN , CLOSE from the predefined ones ), then instead of unique_app_new you can call unique_app_new_with_commands right away (you can add commands separately by calling unique_app_add_command ).

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

    3. After that, call the unique_app_is_running function , and act on its result:
      • true : send one of the predefined or custom messages to an existing instance.

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

      • false : the program is launched for the first time; we need to create our window and attach the message handler from libunique to it.

            else {
                unique_app_watch_window(app, GTK_WINDOW(main_window));
                g_signal_connect(app, "message-received", G_CALLBACK(message_received_cb), NULL);
    4. Actually, write the message handler itself.

      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. Do not forget to clean up after yourself.

    6. ...
    7. Profit!

    Also popular now: