Friday, April 15, 2011

signal confusion

Signals and events in GDK/GTK/X are one of those things that you can have a superficial knowledge about and get away with it. It's also one of those things you could spent weeks (months, even) getting really well versed with. I don't mean the specific signals emitted for all the objects (buttons, windows, other widgets), I mean the order in which they come and how they flow through the system and the handlers.

Like I said, you can get away with a superficial knowledge. You press a button and it emits a pressed signal and you have a function that's looking out for this and had been connected in the code with the g_signal_connect function. Easy enough - from the API here:

g_signal_connect(instance, detailed_signal, c_handler, data)

The handler will be called before the default handler of the signal.

instance :the instance to connect to.
detailed_signal :a string of the form "signal-name::detail".
c_handler :the GCallback to connect.
data :data to pass to c_handler calls.
Returns :the handler id


So.... let's say I have a pointer to a button called "button", a signal called "clicked", a function called "do_something", and for now we don't have any extra data so we'll pass NULL at the end.

g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (do_something), NULL);

GTK is cast heavy and it's NOT always obvious when I need to cast to G_OBJECT or G_CALLBACK and I think once I left them out and it still compiled and ran. Hmm..

Ok so the point of this is that there is an often used (in this book) different method of connecting a signal to a function. From the API again:

g_signal_connect_swapped(instance, detailed_signal, c_handler, data)
The instance on which the signal is emitted and data will be swapped when calling the handler.

instance :the instance to connect to.
detailed_signal :a string of the form "signal-name::detail".
c_handler :the GCallback to connect.
data :data to pass to c_handler calls.
Returns :the handler id


Here is the connect swapped in action:

g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), (gpointer) button);

So it LOOKS like I'm skipping the need to have a function that destroys the widget by passing the widget a signal directly? gtk_widget_destroy is a function.

It says "the instance on which the signal is emitted and data will be swapped when calling the handler". I'm having a tough time parsing that sentence. What is the instance? The thing emitting the signal? If so then why does it say "on which" instead of "from which", or is this one of those times I need to know the signals system better because maybe signals are emitted on things instead of from thing?

Woof. For real.

Well, the point is that I don't understand why it works but it's a decent enough shortcut for now to avoid needing a new function.

Maybe the swapping passes (gpointer)button to gtk_widget_destroy()?

No comments:

Post a Comment