2 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
5 <refentry id="chap-drawing-model">
7 <refentrytitle>The GTK+ Drawing Model</refentrytitle>
8 <manvolnum>3</manvolnum>
9 <refmiscinfo>GTK Library</refmiscinfo>
13 <refname>The GTK+ Drawing Model</refname>
15 The GTK+ drawing model in detail
20 <refsect1 id="drawing-overview">
21 <title>Overview of the drawing model</title>
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.
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.
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.
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
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.
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.
95 <refsect2 id="emission of the draw event">
96 <title>Emission of the draw event</title>
99 When the program needs to redraw a region of a
100 <classname>GdkWindow</classname>, generates an event of
102 linkend="GDK_EVENT_EXPOSE"><constant>GDK_EVENT_EXPOSE</constant></link>
103 for that window, specifying the region to redraw in the process.
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.
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.
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.
137 <refsect2 id="window-no-window-widgets">
138 <title>Window and no-window widgets</title>
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.
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
165 No-window widgets are useful for various reasons:
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.
180 <figure id="figure-windowed-label">
181 <title>Windowed label vs. no-window label</title>
183 <graphic fileref="figure-windowed-label.png" format="png"/>
189 Reducing the number of windows creates less traffic between GTK+ and
190 the underlying windowing system, especially when getting events.
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.
205 <refsect2 id="hierarchical-drawing">
206 <title>Hierarchical drawing</title>
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
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
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:
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 —
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,
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
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
274 The frame label has no children, so it just draws its text: "Frame Label".
279 The internal label has no children, so it just draws its text: "This
280 is some text inside the frame!".
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.
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.
301 This is a text label which has no children, so it just draws its
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.
314 Similar to number 8, this is a text label which has no children,
315 so it just draws its own text: "OK".
321 <figure id="figure-hierarchical-drawing">
322 <title>Hierarchical drawing order</title>
324 <graphic fileref="figure-hierarchical-drawing.png" format="png"/>
330 <refsect1 id="double-buffering">
331 <title>Double buffering</title>
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
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.
355 <!-- FIXME: figure with a timeline of non-double-buffered and
356 double-buffered paints:
376 Two basic functions in GDK form the core of the double-buffering
378 linkend="gdk_window_begin_paint_region"><function>gdk_window_begin_paint_region()</function></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.
388 <refsect2 id="automatic-double-buffering">
389 <title>Automatic double buffering</title>
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.
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
413 However, some widgets may prefer to disable this kind of
414 automatic double buffering and do things on their own. To do
416 <function>gtk_widget_set_double_buffered()</function> function
417 in your widget's constructor.
420 <example id="disabling-double-buffering">
421 <title>Disabling automatic double buffering</title>
425 my_widget_init (MyWidget *widget)
429 gtk_widget_set_double_buffered (widget, FALSE);
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
449 Even if you turn off double buffering on a widget, you
451 <function>gdk_window_begin_paint_region()</function> and
452 <function>gdk_window_end_paint()</function> by hand to use
453 temporary drawing buffers.
458 <refsect1 id="app-paintable-widgets">
459 <title>App-paintable widgets</title>
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
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
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:
490 Your own draw handler gets run. It paints something
491 on the window or the event box.
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
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"/>.
520 <title>Summary of app-paintable widgets</title>
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.
538 sgml-parent-document: ("gtk-docs.sgml" "book" "part" "refentry")