On Wed, 11 Oct 2017 18:42:26 -0300
Antonio Scuri <[email protected]> wrote:

>   Actually I take back what I said, we can use your fix:
> 
> +  g_signal_handlers_disconnect_by_data(G_OBJECT(ih->handle), ih);
> +  parent = iupDialogGetNativeParent(ih);
> +  if (parent)
> +    g_signal_handlers_disconnect_by_func(G_OBJECT(parent),
> gtkDialogChildDestroyEvent, ih);
> 
> 
>   But I think there is another serious problem in what we are doing.
> Suppose we have several dialogs that set their parentdialog to the
> same main dialog. Those "child" dialogs will all call:
> 
>     g_signal_connect(G_OBJECT(parent), "destroy",
> G_CALLBACK(gtkDialogChildDestroyEvent), ih);
> 
>   So for the same parent, they will al set destroy, but each time one
> will replace another and only the last one set will actually be
> called. Am I right? Or I misunderstood g_signal_connect? Does every
> call to g_signal_connect with a different data will ensure a
> different callback association? I can't remember and I couldn't find
> this info explicit in GLIB docs.
> 
> Thanks,
> Scuri
> 
> PS: already committed your contribution.
> 
 
Thanks for committing the fix.

As for the GLib signals handlers, I think you are safe and no problems
should occur in that regard.
Each call of g_signal_connect() creates a unique signal handler that is
identified by an ID (returned by g_signal_connect()).
Even if the GLib docs may not be explicit, the behaviour can be
inferred from various description in Glib docs.
This sentence from
https://developer.gnome.org/gobject/stable/signal.html
"When a signal is emitted on a given type instance, all the closures
connected to this signal on this type instance will be invoked. All the
closures connected to such a signal represent callbacks whose signature
looks like..."
seems to support that best.
The signal handlers are also called in a deterministic way.
https://developer.gnome.org/gobject/stable/gobject-Signals.html says:
"The user-provided signal handlers are called in the order they were
connected in."
And if you look at the source code, you would find that the handlers
are all stored in a hash table and don't replace itself.

I've written a quick test confirming that all signal handlers are
called (even if the g_signal_connect() is completely the same,
including the data parameter). Find the code in the attachment.

Best regards,
blueowl

PS: GLib documentation is traditionally cumbersome. Not only in regards
to signals. But the very basic concept of GObject creation is very hard
to understand from the official documentation [1]. It is described much
much better here [2].

[1] https://developer.gnome.org/gobject/stable/chapter-gobject.html
[2] 
https://blogs.gnome.org/desrt/2012/02/26/a-gentle-introduction-to-gobject-construction/
/*
 *  Test for calling signals that only differ in 'data'
 *
 *  The original base code was copied from
 *  https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
 *
 *  gcc `pkg-config --cflags gtk+-3.0` -o signals signals.c `pkg-config --libs gtk+-3.0`
 */

#include <gtk/gtk.h>

static void activate (GtkApplication* app, gpointer user_data)
{
  GtkWidget *window;

  if (user_data) {
    g_print ("Activate handler, data: %s\n", (char *)user_data);
    return;
  }

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
  gtk_widget_show_all (window);
}

int main (int argc, char **argv)
{
  GtkApplication *app;
  int status;
  gulong sig1, sig2, sig3, sig4;
  char *mydata = "World";

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  sig1 = g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);

  sig2 = g_signal_connect (app, "activate", G_CALLBACK (activate), "Hello");
  sig3 = g_signal_connect (app, "activate", G_CALLBACK (activate), mydata);
  sig4 = g_signal_connect (app, "activate", G_CALLBACK (activate), mydata);

  g_print ("Signal handlers connected: sig1=%ld (%s), sig2=%ld (%s), sig3=%ld (%s), sig4=%ld (%s)\n",
	    sig1, g_signal_handler_is_connected (app, sig1) ? "yes" : "no",
	    sig2, g_signal_handler_is_connected (app, sig2) ? "yes" : "no",
	    sig3, g_signal_handler_is_connected (app, sig3) ? "yes" : "no",
	    sig4, g_signal_handler_is_connected (app, sig4) ? "yes" : "no");

  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Iup-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/iup-users

Reply via email to