nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | <?xml version='1.0' encoding="UTF-8"?> |
2 | <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" |
||
3 | "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ |
||
4 | ]> |
||
5 | <chapter id="chapter-signal"> |
||
6 | <title>The GObject messaging system</title> |
||
7 | |||
8 | <sect1 id="closure"> |
||
9 | <title>Closures</title> |
||
10 | |||
11 | <para> |
||
12 | Closures are central to the concept of asynchronous signal delivery |
||
13 | which is widely used throughout GTK+ and GNOME applications. A closure is an |
||
14 | abstraction, a generic representation of a callback. It is a small structure |
||
15 | which contains three objects: |
||
16 | <itemizedlist> |
||
17 | <listitem><para>a function pointer (the callback itself) whose prototype looks like: |
||
18 | <informalexample><programlisting> |
||
19 | return_type function_callback (… , gpointer user_data); |
||
20 | </programlisting></informalexample> |
||
21 | </para></listitem> |
||
22 | <listitem><para> |
||
23 | the <parameter>user_data</parameter> pointer which is passed to the callback upon invocation of the closure |
||
24 | </para></listitem> |
||
25 | <listitem><para> |
||
26 | a function pointer which represents the destructor of the closure: whenever the |
||
27 | closure's refcount reaches zero, this function will be called before the closure |
||
28 | structure is freed. |
||
29 | </para></listitem> |
||
30 | </itemizedlist> |
||
31 | </para> |
||
32 | |||
33 | <para> |
||
34 | The <link linkend="GClosure"><type>GClosure</type></link> structure represents the common functionality of all |
||
35 | closure implementations: there exists a different closure implementation for |
||
36 | each separate runtime which wants to use the GObject type system. |
||
37 | <footnote><para> |
||
38 | In practice, closures sit at the boundary of language runtimes: if you are |
||
39 | writing Python code and one of your Python callbacks receives a signal from |
||
40 | a GTK+ widget, the C code in GTK+ needs to execute your Python |
||
41 | code. The closure invoked by the GTK+ object invokes the Python callback: |
||
42 | it behaves as a normal C object for GTK+ and as a normal Python object for |
||
43 | Python code. |
||
44 | </para></footnote> |
||
45 | The GObject library provides a simple <link linkend="GCClosure"><type>GCClosure</type></link> type which |
||
46 | is a specific implementation of closures to be used with C/C++ callbacks. |
||
47 | </para> |
||
48 | <para> |
||
49 | A <link linkend="GClosure"><type>GClosure</type></link> provides simple services: |
||
50 | <itemizedlist> |
||
51 | <listitem><para> |
||
52 | Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures |
||
53 | were created for: they hide the details of callback invocation from the |
||
54 | callback invoker.</para> |
||
55 | </listitem> |
||
56 | <listitem><para> |
||
57 | Notification: the closure notifies listeners of certain events such as |
||
58 | closure invocation, closure invalidation and closure finalization. Listeners |
||
59 | can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function> |
||
60 | (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function> |
||
61 | (invalidation notification) and |
||
62 | <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification). |
||
63 | There exist symmetric deregistration functions for finalization and invalidation |
||
64 | events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and |
||
65 | <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation |
||
66 | process. |
||
67 | <footnote><para> |
||
68 | Closures are reference counted and notify listeners of their destruction in a two-stage |
||
69 | process: the invalidation notifiers are invoked before the finalization notifiers. |
||
70 | </para></footnote></para> |
||
71 | </listitem> |
||
72 | </itemizedlist> |
||
73 | </para> |
||
74 | |||
75 | <sect2> |
||
76 | <title>C Closures</title> |
||
77 | |||
78 | <para> |
||
79 | If you are using C or C++ |
||
80 | to connect a callback to a given event, you will either use simple <link linkend="GCClosure"><type>GCClosure</type></link>s |
||
81 | which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function> |
||
82 | functions (which will be presented a bit later). |
||
83 | </para> |
||
84 | |||
85 | <para> |
||
86 | <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the |
||
87 | user-provided callback_func with the user-provided |
||
88 | <parameter>user_data</parameter> as its last parameter. When the closure |
||
89 | is finalized (second stage of the destruction process), it will invoke |
||
90 | the <parameter>destroy_data</parameter> function if the user has |
||
91 | supplied one. |
||
92 | </para> |
||
93 | |||
94 | <para> |
||
95 | <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the |
||
96 | user-provided <parameter>callback_func</parameter> with the |
||
97 | user-provided <parameter>user_data</parameter> as its first parameter |
||
98 | (instead of being the |
||
99 | last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure |
||
100 | is finalized (second stage of the destruction process), it will invoke |
||
101 | the <parameter>destroy_data</parameter> function if the user has |
||
102 | supplied one. |
||
103 | </para> |
||
104 | </sect2> |
||
105 | |||
106 | <sect2> |
||
107 | <title>Non-C closures (for the fearless)</title> |
||
108 | |||
109 | <para> |
||
110 | As was explained above, closures hide the details of callback invocation. In C, |
||
111 | callback invocation is just like function invocation: it is a matter of creating |
||
112 | the correct stack frame for the called function and executing a <emphasis>call</emphasis> |
||
113 | assembly instruction. |
||
114 | </para> |
||
115 | |||
116 | <para> |
||
117 | C closure marshallers transform the array of GValues which represent |
||
118 | the parameters to the target function into a C-style function parameter list, invoke |
||
119 | the user-supplied C function with this new parameter list, get the return value of the |
||
120 | function, transform it into a GValue and return this GValue to the marshaller caller. |
||
121 | </para> |
||
122 | |||
123 | <para> |
||
124 | A generic C closure marshaller is available as |
||
125 | <link linkend="g-cclosure-marshal-generic"><function>g_cclosure_marshal_generic</function></link> |
||
126 | which implements marshalling for all function types using libffi. Custom |
||
127 | marshallers for different types are not needed apart from performance |
||
128 | critical code where the libffi-based marshaller may be too slow. |
||
129 | </para> |
||
130 | |||
131 | <para> |
||
132 | An example of a custom marshaller is given below, illustrating how |
||
133 | <type>GValue</type>s can be converted to a C function call. The |
||
134 | marshaller is for a C function which takes an integer as its first |
||
135 | parameter and returns void. |
||
136 | <informalexample><programlisting> |
||
137 | g_cclosure_marshal_VOID__INT (GClosure *closure, |
||
138 | GValue *return_value, |
||
139 | guint n_param_values, |
||
140 | const GValue *param_values, |
||
141 | gpointer invocation_hint, |
||
142 | gpointer marshal_data) |
||
143 | { |
||
144 | typedef void (*GMarshalFunc_VOID__INT) (gpointer data1, |
||
145 | gint arg_1, |
||
146 | gpointer data2); |
||
147 | register GMarshalFunc_VOID__INT callback; |
||
148 | register GCClosure *cc = (GCClosure*) closure; |
||
149 | register gpointer data1, data2; |
||
150 | |||
151 | g_return_if_fail (n_param_values == 2); |
||
152 | |||
153 | data1 = g_value_peek_pointer (param_values + 0); |
||
154 | data2 = closure->data; |
||
155 | |||
156 | callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback); |
||
157 | |||
158 | callback (data1, |
||
159 | g_marshal_value_peek_int (param_values + 1), |
||
160 | data2); |
||
161 | } |
||
162 | </programlisting></informalexample> |
||
163 | </para> |
||
164 | |||
165 | <para> |
||
166 | There exist other kinds of marshallers, for example there is a generic |
||
167 | Python marshaller which is used by all Python closures (a Python closure |
||
168 | is used to invoke a callback written in Python). This Python marshaller |
||
169 | transforms the input GValue list representing the function parameters |
||
170 | into a Python tuple which is the equivalent structure in Python. |
||
171 | </para> |
||
172 | |||
173 | </sect2> |
||
174 | </sect1> |
||
175 | |||
176 | <sect1 id="signal"> |
||
177 | <title>Signals</title> |
||
178 | |||
179 | <para> |
||
180 | GObject's signals have nothing to do with standard UNIX signals: they connect |
||
181 | arbitrary application-specific events with any number of listeners. |
||
182 | For example, in GTK+, every user event (keystroke or mouse move) is received |
||
183 | from the windowing system and generates a GTK+ event in the form of a signal emission |
||
184 | on the widget object instance. |
||
185 | </para> |
||
186 | |||
187 | <para> |
||
188 | Each signal is registered in the type system together with the type on which |
||
189 | it can be emitted: users of the type are said to <emphasis>connect</emphasis> |
||
190 | to the signal on a given type instance when they register a closure to be |
||
191 | invoked upon the signal emission. Users can also emit the signal by themselves |
||
192 | or stop the emission of the signal from within one of the closures connected |
||
193 | to the signal. |
||
194 | </para> |
||
195 | |||
196 | <para> |
||
197 | When a signal is emitted on a given type instance, all the closures |
||
198 | connected to this signal on this type instance will be invoked. All the closures |
||
199 | connected to such a signal represent callbacks whose signature looks like: |
||
200 | <informalexample><programlisting> |
||
201 | return_type function_callback (gpointer instance, …, gpointer user_data); |
||
202 | </programlisting></informalexample> |
||
203 | </para> |
||
204 | |||
205 | <sect2 id="signal-registration"> |
||
206 | <title>Signal registration</title> |
||
207 | |||
208 | <para> |
||
209 | To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>, |
||
210 | <function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions: |
||
211 | <informalexample><programlisting> |
||
212 | guint g_signal_newv (const gchar *signal_name, |
||
213 | GType itype, |
||
214 | GSignalFlags signal_flags, |
||
215 | GClosure *class_closure, |
||
216 | GSignalAccumulator accumulator, |
||
217 | gpointer accu_data, |
||
218 | GSignalCMarshaller c_marshaller, |
||
219 | GType return_type, |
||
220 | guint n_params, |
||
221 | GType *param_types); |
||
222 | </programlisting></informalexample> |
||
223 | The number of parameters to these functions is a bit intimidating but they are relatively |
||
224 | simple: |
||
225 | <itemizedlist> |
||
226 | <listitem><para> |
||
227 | <parameter>signal_name</parameter>: is a string which can be used to uniquely identify a given signal. |
||
228 | </para></listitem> |
||
229 | <listitem><para> |
||
230 | <parameter>itype</parameter>: is the instance type on which this signal can be emitted. |
||
231 | </para></listitem> |
||
232 | <listitem><para> |
||
233 | <parameter>signal_flags</parameter>: partly defines the order in which closures which were connected to the |
||
234 | signal are invoked. |
||
235 | </para></listitem> |
||
236 | <listitem><para> |
||
237 | <parameter>class_closure</parameter>: this is the default closure for the signal: if it is not NULL upon |
||
238 | the signal emission, it will be invoked upon this emission of the signal. The |
||
239 | moment where this closure is invoked compared to other closures connected to that |
||
240 | signal depends partly on the signal_flags. |
||
241 | </para></listitem> |
||
242 | <listitem><para> |
||
243 | <parameter>accumulator</parameter>: this is a function pointer which is invoked after each closure |
||
244 | has been invoked. If it returns FALSE, signal emission is stopped. If it returns |
||
245 | TRUE, signal emission proceeds normally. It is also used to compute the return |
||
246 | value of the signal based on the return value of all the invoked closures. |
||
247 | For example, an accumulator could ignore |
||
248 | <literal>NULL</literal> returns from closures; or it |
||
249 | could build a list of the values returned by the |
||
250 | closures. |
||
251 | </para></listitem> |
||
252 | <listitem><para> |
||
253 | <parameter>accumulator_data</parameter>: this pointer will be passed down to each invocation of the |
||
254 | accumulator during emission. |
||
255 | </para></listitem> |
||
256 | <listitem><para> |
||
257 | <parameter>c_marshaller</parameter>: this is the default C marshaller for any closure which is connected to |
||
258 | this signal. |
||
259 | </para></listitem> |
||
260 | <listitem><para> |
||
261 | <parameter>return_type</parameter>: this is the type of the return value of the signal. |
||
262 | </para></listitem> |
||
263 | <listitem><para> |
||
264 | <parameter>n_params</parameter>: this is the number of parameters this signal takes. |
||
265 | </para></listitem> |
||
266 | <listitem><para> |
||
267 | <parameter>param_types</parameter>: this is an array of GTypes which indicate the type of each parameter |
||
268 | of the signal. The length of this array is indicated by n_params. |
||
269 | </para></listitem> |
||
270 | </itemizedlist> |
||
271 | </para> |
||
272 | |||
273 | <para> |
||
274 | As you can see from the above definition, a signal is basically a description |
||
275 | of the closures which can be connected to this signal and a description of the |
||
276 | order in which the closures connected to this signal will be invoked. |
||
277 | </para> |
||
278 | |||
279 | </sect2> |
||
280 | |||
281 | <sect2 id="signal-connection"> |
||
282 | <title>Signal connection</title> |
||
283 | |||
284 | <para> |
||
285 | If you want to connect to a signal with a closure, you have three possibilities: |
||
286 | <itemizedlist> |
||
287 | <listitem><para> |
||
288 | You can register a class closure at signal registration: this is a |
||
289 | system-wide operation. i.e.: the class closure will be invoked during each emission |
||
290 | of a given signal on <emphasis>any</emphasis> of the instances of the type which supports that signal. |
||
291 | </para></listitem> |
||
292 | <listitem><para> |
||
293 | You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which |
||
294 | overrides the class closure of a given type. It is possible to call this function |
||
295 | only on a derived type of the type on which the signal was registered. |
||
296 | This function is of use only to language bindings. |
||
297 | </para></listitem> |
||
298 | <listitem><para> |
||
299 | You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> |
||
300 | family of functions. This is an instance-specific operation: the closure |
||
301 | will be invoked only during emission of a given signal on a given instance. |
||
302 | </para></listitem> |
||
303 | </itemizedlist> |
||
304 | It is also possible to connect a different kind of callback on a given signal: |
||
305 | emission hooks are invoked whenever a given signal is emitted whatever the instance on |
||
306 | which it is emitted. Emission hooks are used for example to get all mouse_clicked |
||
307 | emissions in an application to be able to emit the small mouse click sound. |
||
308 | Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function> |
||
309 | and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>. |
||
310 | </para> |
||
311 | |||
312 | </sect2> |
||
313 | |||
314 | <sect2 id="signal-emission"> |
||
315 | <title>Signal emission</title> |
||
316 | |||
317 | <para> |
||
318 | Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family |
||
319 | of functions. |
||
320 | <informalexample><programlisting> |
||
321 | void g_signal_emitv (const GValue *instance_and_params, |
||
322 | guint signal_id, |
||
323 | GQuark detail, |
||
324 | GValue *return_value); |
||
325 | </programlisting></informalexample> |
||
326 | <itemizedlist> |
||
327 | <listitem><para> |
||
328 | The <parameter>instance_and_params</parameter> array of GValues contains the list of input |
||
329 | parameters to the signal. The first element of the array is the |
||
330 | instance pointer on which to invoke the signal. The following elements of |
||
331 | the array contain the list of parameters to the signal. |
||
332 | </para></listitem> |
||
333 | <listitem><para> |
||
334 | <parameter>signal_id</parameter> identifies the signal to invoke. |
||
335 | </para></listitem> |
||
336 | <listitem><para> |
||
337 | <parameter>detail</parameter> identifies the specific detail of the signal to invoke. A detail is a kind of |
||
338 | magic token/argument which is passed around during signal emission and which is used |
||
339 | by closures connected to the signal to filter out unwanted signal emissions. In most |
||
340 | cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for |
||
341 | more details about this parameter. |
||
342 | </para></listitem> |
||
343 | <listitem><para> |
||
344 | <parameter>return_value</parameter> holds the return value of the last closure invoked during emission if |
||
345 | no accumulator was specified. If an accumulator was specified during signal creation, |
||
346 | this accumulator is used to calculate the return value as a function of the return |
||
347 | values of all the closures invoked during emission. |
||
348 | If no closure is invoked during |
||
349 | emission, the <parameter>return_value</parameter> is nonetheless initialized to zero/null. |
||
350 | </para></listitem> |
||
351 | </itemizedlist> |
||
352 | </para> |
||
353 | |||
354 | <para> |
||
355 | Signal emission can be decomposed in 5 steps: |
||
356 | <orderedlist> |
||
357 | <listitem><para> |
||
358 | <literal>RUN_FIRST</literal>: if the |
||
359 | <link linkend="G-SIGNAL-RUN-FIRST:CAPS"><literal>G_SIGNAL_RUN_FIRST</literal></link> flag was used |
||
360 | during signal registration and if there exists a class closure for this signal, |
||
361 | the class closure is invoked. |
||
362 | </para></listitem> |
||
363 | <listitem><para> |
||
364 | <literal>EMISSION_HOOK</literal>: if any emission hook was added to |
||
365 | the signal, they are invoked from first to last added. Accumulate return values. |
||
366 | </para></listitem> |
||
367 | <listitem><para> |
||
368 | <literal>HANDLER_RUN_FIRST</literal>: if any closure were connected |
||
369 | with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of |
||
370 | functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function> |
||
371 | family of functions) they are run here, from first to last connected. |
||
372 | </para></listitem> |
||
373 | <listitem><para> |
||
374 | <literal>RUN_LAST</literal>: if the <literal>G_SIGNAL_RUN_LAST</literal> |
||
375 | flag was set during registration and if a class closure |
||
376 | was set, it is invoked here. |
||
377 | </para></listitem> |
||
378 | <listitem><para> |
||
379 | <literal>HANDLER_RUN_LAST</literal>: if any closure were connected |
||
380 | with the <function>g_signal_connect_after</function> family of |
||
381 | functions, if they were not invoked during <literal>HANDLER_RUN_FIRST</literal> and if they |
||
382 | are not blocked, they are run here, from first to last connected. |
||
383 | </para></listitem> |
||
384 | <listitem><para> |
||
385 | <literal>RUN_CLEANUP</literal>: if the <literal>G_SIGNAL_RUN_CLEANUP</literal> flag |
||
386 | was set during registration and if a class closure was set, |
||
387 | it is invoked here. Signal emission is completed here. |
||
388 | </para></listitem> |
||
389 | </orderedlist> |
||
390 | </para> |
||
391 | |||
392 | <para> |
||
393 | If, at any point during emission (except in <literal>RUN_CLEANUP</literal> state), one of the |
||
394 | closures or emission hook stops the signal emission with |
||
395 | <function><link linkend="g-signal-stop-emission">g_signal_stop_emission</link></function>, |
||
396 | emission jumps to <literal>RUN_CLEANUP</literal> state. |
||
397 | </para> |
||
398 | |||
399 | <para> |
||
400 | If, at any point during emission, one of the closures or emission hook |
||
401 | emits the same signal on the same instance, emission is restarted from |
||
402 | the <literal>RUN_FIRST</literal> state. |
||
403 | </para> |
||
404 | |||
405 | <para> |
||
406 | The accumulator function is invoked in all states, after invocation |
||
407 | of each closure (except in <literal>RUN_EMISSION_HOOK</literal> and |
||
408 | <literal>RUN_CLEANUP</literal>). It accumulates |
||
409 | the closure return value into the signal return value and returns TRUE or |
||
410 | FALSE. If, at any point, it does not return TRUE, emission jumps |
||
411 | to <literal>RUN_CLEANUP</literal> state. |
||
412 | </para> |
||
413 | |||
414 | <para> |
||
415 | If no accumulator function was provided, the value returned by the last handler |
||
416 | run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>. |
||
417 | </para> |
||
418 | |||
419 | </sect2> |
||
420 | |||
421 | |||
422 | <sect2 id="signal-detail"> |
||
423 | <title>The <emphasis>detail</emphasis> argument</title> |
||
424 | |||
425 | <para>All the functions related to signal emission or signal connection have a parameter |
||
426 | named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API |
||
427 | but it is always there, in one form or another. |
||
428 | </para> |
||
429 | |||
430 | <para> |
||
431 | Of the three main connection functions, |
||
432 | only one has an explicit detail parameter as a <link linkend="GQuark"><type>GQuark</type></link>: |
||
433 | <link linkend="g-signal-connect-closure-by-id"><function>g_signal_connect_closure_by_id</function></link>. |
||
434 | <footnote> |
||
435 | <para>A GQuark is an integer which uniquely represents a string. It is possible to transform |
||
436 | back and forth between the integer and string representations with the functions |
||
437 | <function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>. |
||
438 | </para> |
||
439 | </footnote> |
||
440 | </para> |
||
441 | <para> |
||
442 | The two other functions, |
||
443 | <link linkend="g-signal-connect-closure"><function>g_signal_connect_closure</function></link> and |
||
444 | <link linkend="g-signal-connect-data"><function>g_signal_connect_data</function></link> |
||
445 | hide the detail parameter in the signal name identification. |
||
446 | Their <parameter>detailed_signal</parameter> parameter is a |
||
447 | string which identifies the name of the signal to connect to. |
||
448 | The format of this string should match |
||
449 | <emphasis>signal_name::detail_name</emphasis>. For example, |
||
450 | connecting to the signal named |
||
451 | <emphasis>notify::cursor_position</emphasis> will actually |
||
452 | connect to the signal named <emphasis>notify</emphasis> with the |
||
453 | <emphasis>cursor_position</emphasis> detail. |
||
454 | Internally, the detail string is transformed to a GQuark if it is present. |
||
455 | </para> |
||
456 | |||
457 | <para> |
||
458 | Of the four main signal emission functions, one hides it in its |
||
459 | signal name parameter: |
||
460 | <link linkend="g-signal-connect"><function>g_signal_connect</function></link>. |
||
461 | The other three have an explicit detail parameter as a |
||
462 | <link linkend="GQuark"><type>GQuark</type></link> again: |
||
463 | <link linkend="g-signal-emit"><function>g_signal_emit</function></link>, |
||
464 | <link linkend="g-signal-emitv"><function>g_signal_emitv</function></link> and |
||
465 | <link linkend="g-signal-emit-valist"><function>g_signal_emit_valist</function></link>. |
||
466 | </para> |
||
467 | |||
468 | <para> |
||
469 | If a detail is provided by the user to the emission function, it is used during emission to match |
||
470 | against the closures which also provide a detail. |
||
471 | If a closure's detail does not match the detail provided by the user, it |
||
472 | will not be invoked (even though it is connected to a signal which is |
||
473 | being emitted). |
||
474 | </para> |
||
475 | |||
476 | <para> |
||
477 | This completely optional filtering mechanism is mainly used as an optimization for signals |
||
478 | which are often emitted for many different reasons: the clients can filter out which events they are |
||
479 | interested in before the closure's marshalling code runs. For example, this is used extensively |
||
480 | by the <link linkend="GObject-notify"><structfield>notify</structfield></link> signal of GObject: whenever a property is modified on a GObject, |
||
481 | instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this |
||
482 | signal emission the name of the property modified. This allows clients who wish to be notified of changes |
||
483 | to only one property to filter most events before receiving them. |
||
484 | </para> |
||
485 | |||
486 | <para> |
||
487 | As a simple rule, users can and should set the detail parameter to zero: this will disable completely |
||
488 | this optional filtering for that signal. |
||
489 | </para> |
||
490 | |||
491 | </sect2> |
||
492 | |||
493 | </sect1> |
||
494 | </chapter> |
||
495 |