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;
}