diff --git a/docs/reference/gobject/signals.md b/docs/reference/gobject/signals.md index 0486cd930..ab7444bfd 100644 --- a/docs/reference/gobject/signals.md +++ b/docs/reference/gobject/signals.md @@ -14,11 +14,13 @@ through strings. Signals introduced for a parent type are available in derived types as well, so basically they are a per-type facility that is inherited. +## Handlers + A signal emission mainly involves invocation of a certain set of callbacks in precisely defined manner. There are two main categories of such callbacks, per-object ones and user provided ones. -(Although signals can deal with any kind of instantiatable type, I'm -referring to those types as "object types" in the following, simply +(Although signals can deal with any kind of instantiatable type, those types are +referred to as ‘object types’ in the following, simply because that is the context most users will encounter signals in.) The per-object callbacks are most often referred to as "object method handler" or "default (signal) handler", while user provided callbacks are @@ -29,16 +31,33 @@ frequently happens at the end of an object class' creation), while user provided handlers are frequently connected and disconnected to/from a certain signal on certain object instances. +A handler must match the type defined by the signal in both its arguments and +return value (which is often `void`). All handlers take a pointer to the type +instance as their first argument, and a `gpointer user_data` as their final +argument, with signal-defined arguments in-between. The `user_data` is always +filled with the user data provided when the handler was connected to the signal. +Handlers are documented as having type [type@GObject.Callback], but this is +simply a generic placeholder type — an artifact of the GSignal APIs being +polymorphic. + +When a signal handler is connected, its first (‘instance’) and final (‘user +data’) arguments may be swapped if [func@GObject.signal_connect_swapped] is used +rather than [func@GObject.signal_connect]. This can sometimes be convenient for +avoiding defining wrapper functions as signal handlers, instead just directly +passing a function which takes the user data as its first argument. + +## Emissions + A signal emission consists of five stages, unless prematurely stopped: 1. Invocation of the object method handler for `G_SIGNAL_RUN_FIRST` signals -2. Invocation of normal user-provided signal handlers (where the @after +2. Invocation of normal user-provided signal handlers (where the `after` flag is not set) 3. Invocation of the object method handler for `G_SIGNAL_RUN_LAST` signals -4. Invocation of user provided signal handlers (where the @after flag is set) +4. Invocation of user provided signal handlers (where the `after` flag is set) 5. Invocation of the object method handler for `G_SIGNAL_RUN_CLEANUP` signals @@ -64,7 +83,7 @@ detail part of the signal specification upon connection) serves as a wildcard and matches any detail argument passed in to emission. While the `detail` argument is typically used to pass an object property name -(as with `GObject::notify`), no specific format is mandated for the detail +(as with [signal@GObject.Object::notify]), no specific format is mandated for the detail string, other than that it must be non-empty. ## Memory management of signal handlers diff --git a/gobject/gsignal.c b/gobject/gsignal.c index 755a515d8..a5b471cb3 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -2301,7 +2301,10 @@ g_signal_get_invocation_hint (gpointer instance) * If @closure is a floating reference (see g_closure_sink()), this function * takes ownership of @closure. * - * Returns: the handler ID (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID (always greater than 0) */ gulong g_signal_connect_closure_by_id (gpointer instance, @@ -2366,7 +2369,10 @@ g_signal_connect_closure_by_id (gpointer instance, * If @closure is a floating reference (see g_closure_sink()), this function * takes ownership of @closure. * - * Returns: the handler ID (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID (always greater than 0) */ gulong g_signal_connect_closure (gpointer instance, @@ -2462,7 +2468,10 @@ node_check_deprecated (const SignalNode *node) * used. Specify @connect_flags if you need `..._after()` or * `..._swapped()` variants of this function. * - * Returns: the handler ID (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID (always greater than 0) */ gulong g_signal_connect_data (gpointer instance, diff --git a/gobject/gsignal.h b/gobject/gsignal.h index 5522b72bd..52d08a809 100644 --- a/gobject/gsignal.h +++ b/gobject/gsignal.h @@ -500,14 +500,18 @@ void g_signal_chain_from_overridden_handler (gpointer instance, * @c_handler: the #GCallback to connect. * @data: data to pass to @c_handler calls. * - * Connects a #GCallback function to a signal for a particular object. + * Connects a [type@GObject.Callback] function to a signal for a particular object. * - * The handler will be called synchronously, before the default handler of the signal. g_signal_emit() will not return control until all handlers are called. + * The handler will be called synchronously, before the default handler of the signal. + * [func@GObject.signal_emit] will not return control until all handlers are called. * - * See [memory management of signal handlers][signals.html#Memory_management_of_signal_handlers] for + * See [memory management of signal handlers](signals.html#Memory_management_of_signal_handlers) for * details on how to handle the return value and memory management of @data. * - * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID, of type `gulong` (always greater than 0) */ /* Intentionally not using G_CONNECT_DEFAULT here to avoid deprecation * warnings with older GLIB_VERSION_MAX_ALLOWED */ @@ -524,7 +528,10 @@ void g_signal_chain_from_overridden_handler (gpointer instance, * * The handler will be called synchronously, after the default handler of the signal. * - * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID, of type `gulong` (always greater than 0) */ #define g_signal_connect_after(instance, detailed_signal, c_handler, data) \ g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_AFTER) @@ -562,7 +569,10 @@ void g_signal_chain_from_overridden_handler (gpointer instance, * (GCallback) button_clicked_cb, other_widget); * ]| * - * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + * This function cannot fail. If the given signal doesn’t exist, a critical + * warning is emitted. + * + * Returns: the handler ID, of type `gulong` (always greater than 0) */ #define g_signal_connect_swapped(instance, detailed_signal, c_handler, data) \ g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_SWAPPED)