LibUnique Example
The example below shows how to correctly set up a UniqueApp instance, send commands and reply to them with the correct response ids.
#include <gtk/gtk.h> #include <unique/unique.h> enum { COMMAND_0, /* unused: 0 is an invalid command */ COMMAND_FOO, COMMAND_BAR }; static GtkWidget *main_window = NULL; static UniqueResponse message_received_cb (UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time_, gpointer user_data) { UniqueResponse res; switch (command) { case UNIQUE_ACTIVATE: /* move the main window to the screen that sent us the command */ gtk_window_set_screen (GTK_WINDOW (main_window), unique_message_data_get_screen (message)); gtk_window_present_with_time (GTK_WINDOW (main_window), time_); res = UNIQUE_RESPONSE_OK; break; case COMMAND_FOO: /* "foo" is a command that can fail */ if (do_command_foo ()) res = UNIQUE_RESPONSE_OK; else res = UNIQUE_RESPONSE_FAIL; break; case COMMAND_BAR: /* "bar" is a command that requires user interaction */ if (!ask_user_for_bar ()) res = UNIQUE_RESPONSE_CANCEL; else { do_command_bar (); res = UNIQUE_RESPONSE_OK; } break; default: res = UNIQUE_RESPONSE_OK; break; } return res; } int main (int argc, char *argv[]) { UniqueApp *app; gtk_init (&argc, &argv); /* as soon as we create the UniqueApp instance we either have the name * we requested ("org.mydomain.MyApplication", in the example) or we * don't because there already is an application using the same name */ app = unique_app_new_with_commands ("org.mydomain.MyApplication", NULL, "foo", COMMAND_FOO, "bar", COMMAND_BAR, NULL); /* if there already is an instance running, this will return TRUE; there * is no race condition because the check is already performed at * construction time */ if (unique_app_is_running (app)) { UniqueCommand command; /* the command we want to send */ UniqueResponse response; /* the response to our command */ command = parse_command_line (&argc, &argv); if (command == UNIQUE_ACTIVATE) response = unique_app_send_message (app, command, NULL); else { UniqueMessageData *message; /* the payload for the command */ /* here, populate_message() will create the message data using * the command line arguments. for instance, if we want to send * a list of URIs we can use unique_message_data_set_uris() to * correctly populate the UniqueMessageData structure with the * URI list. message = populate_message (&argc, &argv); /* send_message() will block until we get our response back */ response = unique_app_send_message (app, command, message); /* the message is copied, so we need to free it before returning */ unique_message_data_free (message); } /* we don't need the application instance anymore */ g_object_unref (app); if (response == UNIQUE_RESPONSE_OK) return 0; else handle_fail_or_user_cancel (); } else { /* this is the first instance, so we can proceed with the usual application * construction sequence */ main_window = create_main_window (); /* the UniqueApp instance must "watch" all the top-level windows the application * creates, so that it can terminate the startup notification sequence for us */ unique_app_watch_window (app, GTK_WINDOW (main_window)); /* using this signal we get notifications from the newly launched instances * and we can reply to them; the default signal handler will just return * UNIQUE_RESPONSE_OK and terminate the startup notification sequence on each * watched window, so you can connect to the message-received signal only if * you want to handle the commands and responses */ g_signal_connect (app, "message-received", G_CALLBACK (message_received_cb), NULL); gtk_main (); /* don't forget to unref the object when cleaning up after the application * execution */ g_object_unref (app); } return 0; }