Thanks for your answer Andy. Let’s dive into GApplication then.
I have some trouble wrapping my mind around how it works, despite having read the docs over and over. I couldn’t find an example code actually doing what I’m trying to achieve, so I have taken and modified code from this page. Here it is :
#include <glib.h>
#include <gio/gio.h>
#include <stdlib.h>
void countdown()
{
for(gsize i = 5 ; i >= 1 ; i--)
{
g_print("%" G_GSIZE_FORMAT "\n", i);
g_usleep(1 * G_USEC_PER_SEC);
}
}
void dieIfRemote(GApplication *App)
{
if(g_application_get_is_remote(App))
{
g_printerr("Already running.\n");
exit(EXIT_FAILURE);
}
}
void activate(GApplication *App)
{
dieIfRemote(App);
g_print("I'm activated !\n");
countdown();
}
void startup(GApplication *App)
{
dieIfRemote(App);
g_print("I'm started !\n");
countdown();
}
int main(int argc, char *argv[])
{
GApplication *App;
gint Status;
App = g_application_new("io.myapp.test", 0);
g_signal_connect(App, "activate", G_CALLBACK(activate), NULL);
g_signal_connect(App, "startup", G_CALLBACK(startup), NULL);
Status = g_application_run(G_APPLICATION(App), argc, argv);
g_object_unref(App);
return Status;
}
When I compile and run this code, I get the expected output :
$ gcc gapplication.c $(pkg-config --libs --cflags glib-2.0 gio-2.0)
$ ./a.out
I'm started !
5
4
3
2
1
I'm activated !
5
4
3
2
1
$
However, if I run a second instance of this program while the first one is counting down, it hangs until the first one exits, then yields an error :
$ ./a.out
Failed to register: GDBus.Error:org.freedesktop.DBus.Error.NoReply: Message recipient disconnected from message bus without replying
$
I guess dieIfRemote
is never called because the second instance never shoots the startup or activate signals since it detects that it’s not the primary instance. How can I make it exit immediately then ? I have tried this but it does not work either :
int main(int argc, char *argv[])
{
GApplication *App;
gint Status;
App = g_application_new("io.myapp.test", 0);
g_signal_connect(App, "activate", G_CALLBACK(activate), NULL);
g_signal_connect(App, "startup", G_CALLBACK(startup), NULL);
g_application_register(App, NULL, NULL);
dieIfRemote(App);
Status = g_application_run(G_APPLICATION(App), argc, argv);
g_object_unref(App);
return Status;
}
The second instance still hangs until the primary exits, but yields another error and runs as if it was the primary :
$ ./a.out
(process:3552): GLib-GIO-CRITICAL **: g_application_get_is_remote: assertion 'application->priv->is_registered' failed
I'm started !
5
4
3
2
1
I'm activated !
5
4
3
2
1
$
What should I do to make the non-primary instances exit immediately ?