0

I am working on flutter desktop app. I want to execute only single instance of the app. But currently it allows me to run more than one instance.

There is solution for Windows platform, but how to do the same thing in Linux?

Anton
  • 1
  • 2

1 Answers1

0

For People who want to achieve this on Linux:

So i went on a very long rabbit hole trying to implement a similar fix to the one above but for linux until i found a much simpler version.

You want to go to your my_application.cc file then near the bottom find the function below and change it as follows:

From:

MyApplication* my_application_new() {   
  return MY_APPLICATION(g_object_new(my_application_get_type(),
                                      "application-id", APPLICATION_ID,
                                      "flags", G_APPLICATION_NON_UNIQUE,
                                      nullptr)); }

To:

 MyApplication* my_application_new() {
   return MY_APPLICATION(g_object_new(my_application_get_type(),
                                      "application-id", APPLICATION_ID,
                                      nullptr)); }

The G_APPLICATION_NON_UNIQUE flag explicitly says "Make no attempts to do any of the typical single-instance application negotiation," which is the opposite of what we want. https://docs.gtk.org/gio/flags.ApplicationFlags.html#can_override_app_id

Since we are aiming for a single-instance application, we can remove the G_APPLICATION_NON_UNIQUE flag when creating your application object.

By default, GApplication tries to become a single instance if you provide an application ID, and it uses D-Bus to communicate between instances.

Now in order to make it such that when another instance is attempted to be opened you can do the following to make it grab the exisitng one and focus it instead.

static void my_application_activate(GApplication* application) {
    MyApplication* self = MY_APPLICATION(application);
    GList *list = gtk_application_get_windows(GTK_APPLICATION(application));
    GtkWindow* existing_window = list ? GTK_WINDOW(list->data) : NULL;

    if (existing_window) {
        gtk_window_present(existing_window);
    } else {
        // Put your existing code here
        // this is will normally start like this
        GtkWindow* window =  GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
        // and end like this
        gtk_widget_grab_focus(GTK_WIDGET(view));
    }
}

I hope this helps someone as it was a struggle to find this information anywhere and its rather simple compared to the other routes i was trying.

An_Alpaca
  • 141
  • 4