]> Pileus Git - ~andy/gtk/blob - docs/reference/gtk/drawing-model.xml
stylecontext: Do invalidation on first resize container
[~andy/gtk] / docs / reference / gtk / drawing-model.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4 ]>
5 <refentry id="chap-drawing-model">
6 <refmeta>
7 <refentrytitle>The GTK+ Drawing Model</refentrytitle>
8 <manvolnum>3</manvolnum>
9 <refmiscinfo>GTK Library</refmiscinfo>
10 </refmeta>
11
12 <refnamediv>
13 <refname>The GTK+ Drawing Model</refname>
14 <refpurpose>
15     The GTK+ drawing model in detail
16 </refpurpose>
17 </refnamediv>
18
19
20   <refsect1 id="drawing-overview">
21     <title>Overview of the drawing model</title>
22
23     <para>
24       This chapter describes the GTK+ drawing model in detail.  If you
25       are interested in the procedure which GTK+ follows to draw its
26       widgets and windows, you should read this chapter; this will be
27       useful to know if you decide to implement your own widgets.  This
28       chapter will also clarify the reasons behind the ways certain
29       things are done in GTK+; for example, why you cannot change the
30       background color of all widgets with the same method.
31     </para>
32
33     <para>
34       Programs that run in a windowing system generally create
35       rectangular regions in the screen called
36       <firstterm>windows</firstterm>.  Traditional windowing systems
37       do not automatically save the graphical content of windows, and
38       instead ask client programs to repaint those windows whenever it
39       is needed.  For example, if a window that is stacked below other
40       windows gets raised to the top, then a client program has to
41       repaint the area that was previously obscured.  When the
42       windowing system asks a client program to redraw part of a
43       window, it sends an <firstterm>exposure event</firstterm> to the
44       program for that window.
45     </para>
46
47     <para>
48       Here, "windows" means "rectangular regions with automatic
49       clipping", instead of "toplevel application windows".  Most
50       windowing systems support nested windows, where the contents of
51       child windows get clipped by the boundaries of their parents.
52       Although GTK+ and GDK in particular may run on a windowing
53       system with no such notion of nested windows, GDK presents the
54       illusion of being under such a system.  A toplevel window may
55       contain many subwindows and sub-subwindows, for example, one for
56       the menu bar, one for the document area, one for each scrollbar,
57       and one for the status bar.  In addition, controls that receive
58       user input, such as clickable buttons, are likely to have their
59       own subwindows as well.
60     </para>
61
62     <para>
63       Generally, the drawing cycle begins when GTK+ receives an
64       exposure event from the underlying windowing system:  if the
65       user drags a window over another one, the windowing system will
66       tell the underlying window that it needs to repaint itself.  The
67       drawing cycle can also be initiated when a widget itself decides
68       that it needs to update its display.  For example, when the user
69       types a character in a <link
70       linkend="GtkEntry"><classname>GtkEntry</classname></link>
71       widget, the entry asks GTK+ to queue a redraw operation for
72       itself.
73     </para>
74
75     <para>
76       The following sections describe how GTK+ decides which widgets
77       need to be repainted, and how widgets work internally in terms
78       of the resources they use from the windowing system.
79     </para>
80
81     <para>
82       A <link linkend="GdkWindow"><classname>GdkWindow</classname></link>
83       represents a window from the underlying windowing system on which GTK+
84       is running.  For example, on X11 it corresponds to a
85       <type>Window</type>; on Win32, it corresponds to a <type>HANDLE</type>.
86       The windowing system generates events for these windows.  The GDK
87       interface to the windowing system translates such native events into
88       <link linkend="GdkEvent"><structname>GdkEvent</structname></link>
89       structures and sends them on to the GTK layer.  In turn, the GTK layer
90       finds the widget that corresponds to a particular
91       <classname>GdkWindow</classname> and emits the corresponding event
92       signals on that widget.
93     </para>
94
95     <refsect2 id="emission of the draw event">
96       <title>Emission of the draw event</title>
97
98       <para>
99         When the program needs to redraw a region of a
100         <classname>GdkWindow</classname>, generates an event of
101         type <link
102         linkend="GDK_EVENT_EXPOSE"><constant>GDK_EVENT_EXPOSE</constant></link>
103         for that window, specifying the region to redraw in the process.
104       </para>
105
106       <para>
107         When generating the event, GDK also sets up double buffering to
108         avoid the flickering that would result from each widget drawing
109         itself in turn.  <xref linkend="double-buffering"/> describes
110         the double buffering mechanism in detail.
111       </para>
112         
113       <para>
114         When the GTK+ widget layer receives the event, it finds the widget that
115         corresponds to the window, and causes it to render itself using the
116         widget's #GtkWidget::draw signal. For this purpose it creates a
117         <link linkend="#cairo_t">cairo context</link>. It then clips the context
118         to the area that needs to be drawn. This makes sure that the minimal
119         amount of work is done if only a small part of the widget needs to be
120         repainted. After translating the context so that its (0, 0) coordinate
121         corresponds to the top left corner of the widget, it effectively calls
122         the widget's <function>gtk_widget_draw</function> function.
123       </para>
124
125       <para>
126         <function>gtk_widget_draw</function> takes care of drawing the widget
127         to the cairo context. It first checks that the widget actually needs to
128         be drawn. Widgets might for example be empty or outside of the cairo
129         context's clipped area, which would make drawing them not do anything.
130         Usually they will need to be drawn. In this case, the context will be
131         clipped to the widget's allocated size and the
132         <link linkend="GtkWidget::draw">draw signal</link> will be emitted on 
133         the widget which will finally draw the widget.
134       </para>
135     </refsect2>
136
137     <refsect2 id="window-no-window-widgets">
138       <title>Window and no-window widgets</title>
139
140       <para>
141         In principle, each widget could have a
142         <classname>GdkWindow</classname> of its own.  With such a
143         scheme, the drawing cycle would be trivial:  when GDK notifies
144         the GTK layer about an exposure event for a
145         <classname>GdkWindow</classname>, the GTK layer would simply
146         emit the #GtkWidget::draw signal for that widget.  The signal
147         handler would subsequently repaint the widget.  No further
148         work would be necessary; the windowing system would generate
149         exposure events for each window that needs it, and then each
150         corresponding widget would draw itself in turn.
151       </para>
152
153       <para>
154         However, in practice it is convenient to have widgets which do
155         not have a <classname>GdkWindow</classname> of their own, but
156         rather share the one from their parent widget.  Such widgets
157         have called <function>gtk_widget_set_has_window</function> to
158         disable it; this can be tested easily with the <link
159         linkend="gtk-widget-get-has-window"><function>gtk_widget_get_has_window()</function></link>
160         function.  As such, these are called <firstterm>no-window
161         widgets</firstterm>.
162       </para>
163
164       <para>
165         No-window widgets are useful for various reasons:
166       </para>
167
168       <itemizedlist>
169         <listitem>
170           <para>
171             Some widgets may want the parent's background to show through, even
172             when they draw on parts of it.  For example, consider a theme that
173             uses textured backgrounds, such as gradients or repeating
174             patterns.  If each widget had its own window, and in turn its own
175             gradient background, labels would look bad because there would be a
176             visible break with respect to their surroundings.  <xref
177               linkend="figure-windowed-label"/> shows this undesirable effect.
178           </para>
179
180           <figure id="figure-windowed-label">
181             <title>Windowed label vs. no-window label</title>
182
183             <graphic fileref="figure-windowed-label.png" format="png"/>
184           </figure>
185         </listitem>
186
187         <listitem>
188           <para>
189             Reducing the number of windows creates less traffic between GTK+ and
190             the underlying windowing system, especially when getting events.
191           </para>
192         </listitem>
193       </itemizedlist>
194
195       <para>
196         On the other hand, widgets that would benefit from having a "hard"
197         clipping region may find it more convenient to create their own
198         windows.  Also, widgets which want to receive events resulting from
199         user interaction may find it convenient to use windows of their own as
200         well.  Widgets may have more than one window if they want to
201         define different regions for capturing events.
202       </para>
203     </refsect2>
204
205     <refsect2 id="hierarchical-drawing">
206       <title>Hierarchical drawing</title>
207
208       <para>
209         When the GTK layer receives an exposure event from GDK, it
210         finds the widget that corresponds to the window which received
211         the event.  By definition, this corresponds to a widget that
212         has the <constant>GTK_NO_WINDOW</constant> flag turned
213         <emphasis>off</emphasis> (otherwise, the widget wouldn't own
214         the window!).  First this widget paints its background, and
215         then, if it is a container widget, it tells each of its
216         <constant>GTK_NO_WINDOW</constant> children to paint
217         themselves.  This process is applied recursively for all the
218         <constant>GTK_NO_WINDOW</constant> descendants of the original
219         widget.
220       </para>
221
222       <para>
223         Note that this process does not get propagated to widgets
224         which have windows of their own, that is, to widgets which
225         have the <constant>GTK_NO_WINDOW</constant> flag turned off.
226         If such widgets require redrawing, then the windowing system
227         will already have sent exposure events to their corresponding
228         windows.  As such, there is no need to
229         <firstterm>propagate</firstterm> the exposure to them on the
230         GTK+ side.
231       </para>
232
233       <para>
234         <xref
235         linkend="figure-hierarchical-drawing"/> shows how a simple toplevel window would
236         paint itself when it contains only <constant>GTK_NO_WINDOW</constant> descendants:
237
238         <orderedlist>
239           <listitem>
240             <para>
241               The outermost, thick rectangle is a toplevel <link
242                 linkend="GtkWindow"><classname>GtkWindow</classname></link>,
243               which is not a <constant>GTK_NO_WINDOW</constant> widget &mdash;
244               as such, it does receive its exposure event as it comes from GDK.
245               First the <classname>GtkWindow</classname> would paint its own
246               background.  Then, it would ask its only child to paint itself,
247               numbered 2.
248             </para>
249           </listitem>
250           <listitem>
251             <para>
252               The dotted rectangle represents a <link
253                 linkend="GtkVBox"><classname>GtkVBox</classname></link>, which
254               has been made the sole child of the
255               <classname>GtkWindow</classname>.  Boxes are just layout
256               containers that do not paint anything by themselves, so this
257               <classname>GtkVBox</classname> would draw nothing, but rather ask
258               its children to draw themselves.  The children are numbered 3 and
259               6.
260             </para>
261           </listitem>
262           <listitem>
263             <para>
264               The thin rectangle is a <link
265                 linkend="GtkFrame"><classname>GtkFrame</classname></link>,
266               which has two children:  a label for the frame, numbered 4, and
267               another label inside, numbered 5.  First the frame would draw its
268               own beveled box, then ask the frame label and its internal child to
269               draw themselves.
270             </para>
271           </listitem>
272           <listitem>
273             <para>
274               The frame label has no children, so it just draws its text:  "Frame&nbsp;Label".
275             </para>
276           </listitem>
277           <listitem>
278             <para>
279               The internal label has no children, so it just draws its text:  "This
280               is some text inside the frame!".
281             </para>
282           </listitem>
283           <listitem>
284             <para>
285               The dotted rectangle represents a <link
286                 linkend="GtkHBox"><classname>GtkHBox</classname></link>.  Again,
287               this does not draw anything by itself, but rather asks its children
288               to draw themselves.  The children are numbered 7 and 9.
289             </para>
290           </listitem>
291           <listitem>
292             <para>
293               The thin rectangle is a <link
294                 linkend="GtkButton"><classname>GtkButton</classname></link> with
295               a single child, numbered 8.  First the button would draw its
296               beveled box, and then it would ask its child to draw itself.
297             </para>
298           </listitem>
299           <listitem>
300             <para>
301               This is a text label which has no children, so it just draws its
302               own text:  "Cancel".
303             </para>
304           </listitem>
305           <listitem>
306             <para>
307               Similar to number 7, this is a button with a single child, numbered
308               10.  First the button would draw its beveled box, and then it would
309               ask its child to draw itself.
310             </para>
311           </listitem>
312           <listitem>
313             <para>
314               Similar to number 8, this is a text label which has no children,
315               so it just draws its own text:  "OK".
316             </para>
317           </listitem>
318         </orderedlist>
319       </para>
320
321       <figure id="figure-hierarchical-drawing">
322         <title>Hierarchical drawing order</title>
323
324         <graphic fileref="figure-hierarchical-drawing.png" format="png"/>
325       </figure>
326     </refsect2>
327
328   </refsect1>
329
330   <refsect1 id="double-buffering">
331     <title>Double buffering</title>
332
333     <para>
334       When the GTK layer receives an exposure event from GDK, it first finds
335       the <literal>!<constant>GTK_NO_WINDOW</constant></literal> widget that
336       corresponds to the event's window.  Then, it emits the
337       #GtkWidget::draw signal for that
338       widget.  As described above, that widget will first draw its background,
339       and then ask each of its <constant>GTK_NO_WINDOW</constant> children to
340       draw themselves.
341     </para>
342
343     <para>
344       If each of the drawing calls made by each subwidget's
345       <literal>draw</literal> handler were sent directly to the
346       windowing system, flicker could result.  This is because areas may get
347       redrawn repeatedly:  the background, then decorative frames, then text
348       labels, etc.  To avoid flicker, GTK+ employs a <firstterm>double
349         buffering</firstterm> system at the GDK level.  Widgets normally don't
350       know that they are drawing to an off-screen buffer; they just issue their
351       normal drawing commands, and the buffer gets sent to the windowing system
352       when all drawing operations are done.
353     </para>
354
355     <!-- FIXME: figure with a timeline of non-double-buffered and
356          double-buffered paints:
357
358          onscreen:
359          [garbage]
360          [background]
361          [button-frame]
362          [icon]
363          [label]
364
365
366          onscreen:             offscreen:
367          [garbage]
368                                [background]
369                                [button-frame]
370                                [icon]
371                                [label]
372          [final result]
373     -->
374
375     <para>
376       Two basic functions in GDK form the core of the double-buffering
377       mechanism:  <link
378       linkend="gdk_window_begin_paint_region"><function>gdk_window_begin_paint_region()</function></link>
379       and <link
380       linkend="gdk_window_end_paint"><function>gdk_window_end_paint()</function></link>.
381       The first function tells a <classname>GdkWindow</classname> to
382       create a temporary off-screen buffer for drawing.  All
383       subsequent drawing operations to this window get automatically
384       redirected to that buffer.  The second function actually paints
385       the buffer onto the on-screen window, and frees the buffer.
386     </para>
387
388     <refsect2 id="automatic-double-buffering">
389       <title>Automatic double buffering</title>
390
391       <para>
392         It would be inconvenient for all widgets to call
393         <function>gdk_window_begin_paint_region()</function> and
394         <function>gdk_window_end_paint()</function> at the beginning
395         and end of their draw handlers.
396       </para>
397
398       <para>
399         To make this easier, most GTK+ widgets have the
400         <constant>GTK_DOUBLE_BUFFERED</constant> <link
401         linkend="GtkWidgetFlags">widget flag</link> turned on by
402         default.  When GTK+ encounters such a widget, it automatically
403         calls <function>gdk_window_begin_paint_region()</function>
404         before emitting the #GtkWidget::draw signal for the widget, and
405         then it calls <function>gdk_window_end_paint()</function>
406         after the signal has been emitted.  This is convenient for
407         most widgets, as they do not need to worry about creating
408         their own temporary drawing buffers or about calling those
409         functions.
410       </para>
411
412       <para>
413         However, some widgets may prefer to disable this kind of
414         automatic double buffering and do things on their own.  To do
415         this, call the
416         <function>gtk_widget_set_double_buffered()</function> function
417         in your widget's constructor.
418       </para>
419
420       <example id="disabling-double-buffering">
421         <title>Disabling automatic double buffering</title>
422
423         <programlisting>
424 static void
425 my_widget_init (MyWidget *widget)
426 {
427   ...
428
429   gtk_widget_set_double_buffered (widget, FALSE);
430
431   ...
432 }
433         </programlisting>
434       </example>
435
436       <para>
437         When is it convenient to disable double buffering?  Generally,
438         this is the case only if your widget gets drawn in such a way
439         that the different drawing operations do not overlap each
440         other.  For example, this may be the case for a simple image
441         viewer:  it can just draw the image in a single operation.
442         This would <emphasis>not</emphasis> be the case with a word
443         processor, since it will need to draw and over-draw the page's
444         background, then the background for highlighted text, and then
445         the text itself.
446       </para>
447
448       <para>
449         Even if you turn off double buffering on a widget, you
450         can still call
451         <function>gdk_window_begin_paint_region()</function> and
452         <function>gdk_window_end_paint()</function> by hand to use
453         temporary drawing buffers.
454       </para>
455     </refsect2>
456   </refsect1>
457
458   <refsect1 id="app-paintable-widgets">
459     <title>App-paintable widgets</title>
460
461     <para>
462       Generally, applications use the pre-defined widgets in GTK+ and
463       they do not draw extra things on top of them (the exception
464       being <classname>GtkDrawingArea</classname>).  However,
465       applications may sometimes find it convenient to draw directly
466       on certain widgets like toplevel windows or event boxes.  When
467       this is the case, GTK+ needs to be told not to overwrite your
468       drawing afterwards, when the window gets to drawing its default
469       contents.
470     </para>
471
472     <para>
473       <classname>GtkWindow</classname> and
474       <classname>GtkEventBox</classname> are the two widgets that allow
475       turning off drawing of default contents by calling
476       <function>gtk_widget_set_app_paintable()</function>. If you call
477       this function, they will not draw their contents and let you do
478       it instead.
479     </para>
480
481     <para>
482       Since the #GtkWidget::draw signal runs user-connected handlers
483       <emphasis>before</emphasis> the widget's default handler, what
484       usually happens is this:
485     </para>
486
487     <orderedlist>
488       <listitem>
489         <para>
490           Your own draw handler gets run.  It paints something
491           on the window or the event box.
492         </para>
493       </listitem>
494
495       <listitem>
496         <para>
497           The widget's default draw handler gets run.  If
498           <function>gtk_widget_set_app_paintable()</function> has not
499           been called to turn off widget drawing (this
500           is the default), <emphasis>your drawing will be
501             overwritten</emphasis>.  An app paintable widget will not
502           draw its default contents however and preserve your drawing
503           instead.
504         </para>
505       </listitem>
506
507       <listitem>
508         <para>
509           The draw handler for the parent class gets run.
510           Since both <classname>GtkWindow</classname> and
511           <classname>GtkEventBox</classname> are descendants of
512           <classname>GtkContainer</classname>, their no-window
513           children will be asked to draw themselves recursively, as
514           described in <xref linkend="hierarchical-drawing"/>.
515         </para>
516       </listitem>
517     </orderedlist>
518
519     <formalpara>
520       <title>Summary of app-paintable widgets</title>
521
522       <para>
523         Call <function>gtk_widget_set_app_paintable()</function> if you
524         intend to draw your own content directly on a
525         <classname>GtkWindow</classname> and
526         <classname>GtkEventBox</classname>.  You seldom need to draw
527         on top of other widgets, and
528         <classname>GtkDrawingArea</classname> ignores this flag, as it
529         <emphasis>is</emphasis> intended to be drawn on.
530       </para>
531     </formalpara>
532   </refsect1>
533 </refentry>
534
535 <!--
536 Local variables:
537 mode: xml
538 sgml-parent-document: ("gtk-docs.sgml" "book" "part" "refentry")
539 End:
540 -->