Garethmoffatt
Posts: 39
Joined: Sat Feb 25, 2017 10:11 pm

[solved] Ensuring gtk_application is unique

Fri Jul 06, 2018 3:00 pm

I am using GTK3+ (in c).

I want to ensure I don't have multiple instances of the application running. (conflicts over resources)

Googling suggests that using a GtkApplication with unique application ID ensures this... but my practical experience is that it doesn't!

Any pointers to how to detect is a new instance is unique or one is already running?

Thanks

Gareth

Here is a simple program that I made to test something else that demonstrates the problem (i.e, you can launch multiple instances.)

Code: Select all

#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define true TRUE
#define false FALSE

#define DOES_NOTHING_BUTTON 1
#define QUIT_BUTTON 2

GtkWidget *parent;

// update calling code to only call here if something has changed.  Try to stop flashing of bullet

static void button_click_cb(GtkWidget * widget, gpointer data)
{
   gint which;

   g_print("Button Pressed\n");



   which = GPOINTER_TO_INT(data);

   switch (which) {
   case QUIT_BUTTON:

      gtk_window_close(GTK_WINDOW(parent));
      break;
   }
}

static gboolean delete_event(GtkWidget * widget, GdkEvent * event, gpointer data)
{
   gint result;

   /* If you return FALSE in the "delete-event" signal handler,
    * GTK will emit the "destroy" signal. Returning TRUE means
    * you don't want the window to be destroyed.
    * This is useful for popping up 'are you sure you want to quit?'
    * type dialogs. */
   GtkWidget *mbox;

   mbox =
       gtk_dialog_new_with_buttons("Quit?", GTK_WINDOW(widget),
               GTK_DIALOG_DESTROY_WITH_PARENT, "_Quit", 0, "_Cancel", 1, NULL);

   gtk_dialog_set_default_response(GTK_DIALOG(mbox), 1);

   result = gtk_dialog_run(GTK_DIALOG(mbox));

   gtk_widget_destroy(mbox);

   g_print("delete event occurred\n");
   /* Change TRUE to FALSE and the main window will be destroyed with
    * a "delete-event". */


   if (result == 0)
      return (false);
   else
      return (true);
}

static int destroy(GtkWidget * widget, gpointer data)
{

   return (FALSE);
}

static void activate(GtkApplication * app, gpointer user_data)
{
   /* GtkWidget is the storage type for widgets */
   GtkWidget *window;
   GtkWidget *button;
   GtkWidget *container;
   GtkWidget *topContainer;

   /* create a new window */
   window = gtk_application_window_new(app);
   parent = window;  // save this as a meaningful pointer, could so renamed window as parent...
   g_signal_connect(window, "delete-event", G_CALLBACK(delete_event), NULL);
   g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);

   /* Sets the border width of the window. */
   gtk_container_set_border_width(GTK_CONTAINER(window), 10);
   gtk_window_set_title(GTK_WINDOW(window), "Simple test emit");

   /* Start building first column */
   topContainer = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1);
   container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);

   // build buttons column
   button = gtk_button_new_with_label("Does Nothing");
   gtk_box_pack_start(GTK_BOX(container), button, true, true, 1);
   g_signal_connect(button, "clicked", G_CALLBACK(button_click_cb), GINT_TO_POINTER(DOES_NOTHING_BUTTON));
   button = gtk_button_new_with_label("Quit");
   gtk_box_pack_start(GTK_BOX(container), button, true, true, 1);
   g_signal_connect(button, "clicked", G_CALLBACK(button_click_cb), GINT_TO_POINTER(QUIT_BUTTON));

// put column in to top container
   gtk_box_pack_start(GTK_BOX(topContainer), container, false, false, 1);


   /* put the composite container in to the top level window */
   gtk_container_add(GTK_CONTAINER(window), topContainer);

// show all widgets
   gtk_widget_show_all(window);

}

int main(int argc, char **argv)
{
   GtkApplication *app;
   int status;

   tzset();    // call to set timezone

   app = gtk_application_new("org.gmail.mipi.gareth.simple", G_APPLICATION_FLAGS_NONE);
   g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
   status = g_application_run(G_APPLICATION(app), argc, argv);
   g_object_unref(app);

   return status;
}
Here is the make file

Code: Select all

simple : simple.o
	gcc -Wall -g -o simple simple.o `pkg-config --libs --cflags gtk+-3.0` -lm

simple.o : simple.c
	gcc -Wall -g -c simple.c `pkg-config --libs --cflags gtk+-3.0`
Last edited by Garethmoffatt on Sat Jul 14, 2018 9:41 pm, edited 1 time in total.

Garethmoffatt
Posts: 39
Joined: Sat Feb 25, 2017 10:11 pm

Re: Ensuring gtk_application is unique

Sat Jul 14, 2018 9:40 pm

Ok, so nobody wanted to come up with a solution, so I did it using a named semaphore.

Best regards

Gareth

Return to “Graphics programming”

Who is online

Users browsing this forum: No registered users and 1 guest