I am trying to get started with GTK, but I find the documentation for signals (https://developer.gnome.org/gobject/stable/signal.html) hard to understand.
It seems as there is a difference between a "signal" and an "event". For example, the documentation for the "event"-signal for a Widget (https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-event) says
The GTK+ main loop will emit three signals for each GDK event delivered to a widget: one generic ::event signal, another, more specific, signal that matches the type of event delivered (e.g. “key-press-event”) and finally a generic “event-after” signal.
So it seems to me, that GDK uses "events", whereas GTK+ uses "signals". Maybe events are just packed into signals, or the other way around? Or are they completely different things?
My understanding of the above quote:
When a key is pressed, then a GDK-event is fired. This GDK-event calls a callback function of the widget (which is not for the programmer to interfer with). The callback function then in turn emits the three signals ::event
, key-press-event
and event-after
, one after the other. As a programmer I can intercept these signals by writing callback functions. If the callback for the first ::event
signal returns TRUE
, then the second key-press-event
signal is not fired, otherwise it is. The third event-after
signal is always fired.
Is my understanding correct?
Furthermore, in the docs, sometimes signals are prepended by a double colon (::event
) and sometimes they are not (key-press-event
and event-after
). What is the difference? What is the meaning of the double colon?
In GTK+ an event is a message from the X server. When the event reaches a widget, it may react to this event by emitting a signal. The GTK+ programmer can connect a specific callback to the signal. The callback is a handler function that reacts to the signal.
GTK+ uses a height-for-width (and width-for-height) geometry management system. Height-for-width means that a widget can change how much vertical space it needs, depending on the amount of horizontal space that it is given (and similar for width-for-height).
g_signal_connect()Connects a GCallback function to a signal for a particular object. The handler will be called before the default handler of the signal. instance : the instance to connect to.
Description. A GtkWindow is a toplevel window which can contain other widgets. Windows normally have decorations that are under the control of the windowing system and allow the user to manipulate the window (resize it, move it, close it,...).
it's just nomenclature.
signals, in GObject, are just fancy ways to calling named lists of functions; each time an instance "emits" a signal, the GSignal machinery will look at all the callbacks connected to that particular signal, and call them sequentially until either one of these conditions is satisfied:
all signals emitted by GDK or GTK+ (as well as any other GObject-based library) work exactly in that way.
events, in GDK, are structures related to windowing system events, like a button press, a key release, a pointer crossing the window boundaries, a change in the window hierarchy, and so on and so forth. the only interaction you generally have with GDK events happen in specific signals on the GtkWidget
types. as a convention (though it does not always apply) the signals that have a GdkEvent
structure have an -event
suffix, like button-press-event
, or key-release-event
, or enter-notify-event
, or window-state-event
. again, those are GObject signals, and their only specialization is having a GdkEvent
as an argument.
as for the double colon: the full specification of a signal is made of the type that declares it, e.g. GtkWidget
, and the signal name, e.g. button-press-event
, separated by a double colon, e.g. GtkWidget::button-press-event
. the ::button-press-event
notation is just a documentation shorthand, signifying that the speaker is referring to the button-press-event
signal.
The simple way to understand it is that, events are something that you do to an object, say GtkButton (we choose button as something you can see). When you click a button, the button receive an event from you (actually it's from Gdk ( a thin layer between gtk and underlying window and graphics system ). Upon receive an event it has to do something. otherwise it's a dead object.
From there, something has to be done. Since an object has to do something, a signal will pick up the rest. Signal will emitted "from" the object to tell other object something has happened. Short word, signal is a catcher of an event. The most used pre-defined signal for GtkButton is "clicked". Within the callback for the signal, you can do anything you want to be.
Now, another question, hey, why don't we just catch the event from the mouse button and do it from there? Of course you can. Here's how :
Next, Gdk uses signals too. For example GdkScreen emits 3 signals, which react from an event: somehow you turn off the compositing window, somehow you hookup with other screen and somehow you change the screen resolution.
Next, callbacks are not emitted signals. Signal "emits" callbacks. It is up to you if you to connect (intercept, in your term) or not. It is not your function, it's predefined function which you just wrap arounds it with your function name. After you use a signal, you can also disconnect it, for some reason.
Next, yes, if the widget signal "event" return True, the second specific signal is disconnected. Note: do not tamper with event mask of a widget, since a widget has its own default event masks.
Finally, double-colon? either its documenter like the double colon or just saying this signal belong to a class. Don't worry about it, you probably not going to use it in C
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With