]> Pileus Git - ~andy/gtk/blob - docs/reference/gtk/migrating-2to3.xml
docs: migrating-2to3: improve cross-reference
[~andy/gtk] / docs / reference / gtk / migrating-2to3.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3                "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4 <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
5 ]>
6 <chapter id="gtk-migrating-2-to-3">
7   <title>Migrating from GTK+ 2.x to GTK+ 3</title>
8
9   <para>
10     GTK+ 3 is a major new version of GTK+ that breaks both API and ABI
11     compared to GTK+ 2.x, which has remained API- and ABI-stable for a
12     long time. Thankfully, most of the changes are not hard to adapt to
13     and there are a number of steps that you can take to prepare your
14     GTK+ 2.x application for the switch to GTK+ 3. After that, there's
15     a small number of adjustments that you may have to do when you actually
16     switch your application to build against GTK+ 3.
17   </para>
18
19   <section>
20     <title>Preparation in GTK+ 2.x</title>
21
22     <para>
23       The steps outlined in the following sections assume that your
24       application is working with GTK+ 2.24, which is the final stable
25       release of GTK+ 2.x. It includes all the necessary APIs and tools
26       to help you port your application to GTK+ 3. If you are still using
27       an older version of GTK+ 2.x, you should first get your application
28       to build and work with 2.24.
29     </para>
30
31   <section>
32   <title>Do not include individual headers</title>
33   <para>
34     With GTK+ 2.x it was common to include just the header files for
35     a few widgets that your application was using, which could lead
36     to problems with missing definitions, etc. GTK+ 3 tightens the
37     rules about which header files you are allowed to include directly.
38     The allowed header files are are
39     <variablelist>
40       <varlistentry>
41         <term><filename>gtk/gtk.h</filename></term>
42         <listitem>for GTK</listitem>
43       </varlistentry>
44       <varlistentry>
45         <term><filename>gtk/gtkunixprint.h</filename></term>
46         <listitem>for low-level, UNIX-specific printing functions</listitem>
47       </varlistentry>
48       <varlistentry>
49         <term><filename>gdk/gdk.h</filename></term>
50         <listitem>for GDK</listitem>
51       </varlistentry>
52       <varlistentry>
53         <term><filename>gdk/gdkx.h</filename></term>
54         <listitem>for GDK functions that are X11-specific</listitem>
55       </varlistentry>
56       <varlistentry>
57         <term><filename>gdk/gdkwin32.h</filename></term>
58         <listitem>for GDK functions that are Windows-specific</listitem>
59       </varlistentry>
60     </variablelist>
61     (these relative paths are assuming that you are using the include
62      paths that are specified in the gtk+-2.0.pc file, as returned by
63      <literal>pkg-config --cflags gtk+-2.0.pc</literal>.)
64   </para>
65   <para>
66     To check that your application only includes the allowed headers,
67     you can use defines to disable inclusion of individual headers,
68     as follows:
69     <programlisting>
70     make CFLAGS+="-DGTK_DISABLE_SINGLE_INCLUDES"
71     </programlisting>
72   </para>
73   </section>
74
75   <section>
76   <title>Do not use deprecated symbols</title>
77   <para>
78     Over the years, a number of functions, and in some cases, entire
79     widgets have been deprecated. These deprecations are clearly spelled
80     out in the API reference, with hints about the recommended replacements.
81     The API reference also includes an
82     <link linkend="api-index-deprecated">index</link> of all deprecated
83     symbols.
84   </para>
85   <para>
86     To verify that your program does not use any deprecated symbols,
87     you can use defines to remove deprecated symbols from the header files,
88     as follows:
89     <programlisting>
90     make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
91     </programlisting>
92   </para>
93   </section>
94
95   <section>
96   <title>Use accessor functions instead of direct access</title>
97   <para>
98     GTK+ 3 removes many implementation details and struct members from
99     its public headers.
100   </para>
101   <para>
102     To ensure that your application does not have problems with this, you
103     define the preprocessor symbol <literal>GSEAL_ENABLE</literal> while
104     building your application against GTK+ 2.x. This will make the compiler
105     catch all uses of direct access to struct fields so that you can go
106     through them one by one and replace them with a call to an accessor
107     function instead.
108     <programlisting>
109     make CFLAGS+="-DGSEAL_ENABLE"
110     </programlisting>
111   </para>
112   </section>
113
114   <section>
115     <title>Replace GDK_&lt;keyname&gt; with GDK_KEY_&lt;keyname&gt;</title>
116
117     <para>
118       Key constants have gained a <literal>_KEY_</literal> infix.
119       For example, <literal>GDK_a</literal> is now
120       <literal>GDK_KEY_a</literal>.  In GTK+ 2, the old names continue
121       to be available.  In GTK+ 3 however, the old names will require
122       an explicit include of the <literal>gdkkeysyms-compat.h</literal> header.
123     </para>
124
125   </section>
126
127   <section>
128     <title>Use GIO for launching applications</title>
129     <para>
130       The <literal>gdk_spawn</literal> family of functions has been
131       deprecated in GDK 2.24 and removed from GDK 3. Various replacements
132       exist; the best replacement depends on the circumstances:
133       <itemizedlist>
134         <listitem>If you are opening a document or URI by launching a command
135         like <literal>firefox http://my-favourite-website.com</literal> or
136         <literal>gnome-open ghelp:epiphany</literal>, it is best to just use
137         gtk_show_uri(); as an added benefit, your application will henceforth
138         respect the users preference for what application to use.</listitem>
139         <listitem>If you are launching a regular, installed application that
140         has a desktop file, it is best to use GIOs #GAppInfo with a suitable
141         launch context.
142         <informalexample><programlisting>
143         GAppInfo *info;
144         GAppLaunchContext *context;
145         GError *error = NULL;
146
147         info = (GAppInfo*) g_desktop_app_info_new ("epiphany.desktop");
148         context = (GAppLaunchContext*) gdk_display_get_app_launch_context (display);
149         g_app_info_launch (info, NULL, context, &amp;error);
150
151         if (error)
152           {
153             g_warning ("Failed to launch epiphany: %s", error-&gt;message);
154             g_error_free (error);
155           }
156
157         g_object_unref (info);
158         g_object_unref (context);
159         </programlisting></informalexample>
160         Remember that you have to include
161         <filename>gio/gdesktopappinfo.h</filename>
162         and use the <filename>gio-unix-2.0</filename> pkg-config file
163         when using g_desktop_app_info_new().
164         </listitem>
165         <listitem>If you are launching a custom commandline, you can
166         still use g_app_info_launch() with a GAppInfo that is constructed
167         with g_app_info_create_from_commandline(), or you can use the
168         more lowlevel <literal>g_spawn</literal> family of functions
169         (e.g. g_spawn_command_line_async()), and pass <envar>DISPLAY</envar>
170         in the environment. gdk_screen_make_display_name() can be
171         used to find the right value for the <envar>DISPLAY</envar>
172         environment variable.
173         </listitem>
174       </itemizedlist>
175     </para>
176   </section>
177
178   <section>
179     <title>Use cairo for drawing</title>
180     <para>
181       In GTK+ 3, the GDK drawing API (which closely mimics the X
182       drawing API, which is itself modeled after PostScript) has been
183       removed. All drawing in GTK+ 3 is done via cairo.
184     </para>
185     <para>
186       The #GdkGC and #GdkImage objects, as well as all the functions using
187       them, are gone. This includes the <literal>gdk_draw</literal> family
188       of functions like gdk_draw_rectangle() and gdk_draw_drawable(). As
189       #GdkGC is roughly equivalent to #cairo_t and #GdkImage was used for
190       drawing images to GdkWindows, which cairo supports automatically,
191       a transition is usually straightforward.
192     </para>
193     <para>
194       The following examples show a few common drawing idioms used by
195       applications that have been ported to use cairo and how the code
196       was replaced.
197     </para>
198     <example>
199        <title>Drawing a GdkPixbuf onto a GdkWindow</title>
200          <para>
201            Drawing a pixbuf onto a drawable used to be done like this:
202            <informalexample><programlisting>
203 gdk_draw_pixbuf (window,
204                  gtk_widget_get_style (widget)->black_gc,
205                  pixbuf,
206                  0, 0
207                  x, y,
208                  gdk_pixbuf_get_width (pixbuf),
209                  gdk_pixbuf_get_height (pixbuf),
210                  GDK_RGB_DITHER_NORMAL,
211                  0, 0);
212            </programlisting></informalexample>
213            Doing the same thing with cairo:
214            <informalexample><programlisting>
215 cairo_t *cr = gdk_cairo_create (window);
216 gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
217 cairo_paint (cr);
218 cairo_destroy (cr);
219            </programlisting></informalexample>
220            Note that very similar code can be used for drawing pixmaps
221            by using gdk_cairo_set_source_pixmap() instead of
222            gdk_cairo_set_source_pixbuf().
223          </para>
224       </example>
225       <example>
226         <title>Drawing a tiled GdkPixmap to a GdkWindow</title>
227         <para>
228           Tiled pixmaps are often used for drawing backgrounds.
229           Old code looked something like this:
230           <informalexample><programlisting>
231 GdkGCValues gc_values;
232 GdkGC *gc;
233
234 /* setup */
235 gc = gtk_widget_get_style (widget)->black_gc;
236 gdk_gc_set_tile (gc, pixmap);
237 gdk_gc_set_fill (gc, GDK_TILED);
238 gdk_gc_set_ts_origin (gc, x_origin, y_origin);
239 /* use */
240 gdk_draw_rectangle (drawable, gc, TRUE, 0, 0, width, height);
241 /* restore */
242 gdk_gc_set_tile (gc, NULL);
243 gdk_gc_set_fill (gc, GDK_SOLID);
244 gdk_gc_set_ts_origin (gc, 0, 0);
245           </programlisting></informalexample>
246           The equivalent cairo code looks like this:
247           <informalexample><programlisting>
248 cairo_t *cr;
249
250 cr = gdk_cairo_create (drawable);
251 gdk_cairo_set_source_pixmap (cr, pixmap, x_origin, y_origin);
252 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
253 cairo_rectangle (cr, 0, 0, width, height);
254 cairo_fill (cr);
255 cairo_destroy (cr);
256           </programlisting></informalexample>
257           Again, you can exchange pixbufs and pixmaps by using
258           gdk_cairo_set_source_pixbuf() instead of
259           gdk_cairo_set_source_pixmap().
260         </para>
261       </example>
262       <example>
263         <title>Drawing a PangoLayout to a clipped area</title>
264         <para>
265           Drawing layouts clipped is often used to avoid overdraw or to
266           allow drawing selections. Code would have looked like this:
267           <informalexample><programlisting>
268 GdkGC *gc;
269
270 /* setup */
271 gc = gtk_widget_get_style (widget)->text_gc[state];
272 gdk_gc_set_clip_rectangle (gc, &amp;area);
273 /* use */
274 gdk_draw_layout (drawable, gc, x, y, layout);
275 /* restore */
276 gdk_gc_set_clip_rectangle (gc, NULL);
277           </programlisting></informalexample>
278           With cairo, the same effect can be achieved using:
279           <informalexample><programlisting>
280 cairo_t *cr;
281
282 cr = gdk_cairo_create (drawable);
283 /* clip */
284 gdk_cairo_rectangle (cr, &amp;area);
285 cairo_clip (cr);
286 /* set the correct source color */
287 gdk_cairo_set_source_color (cr, &amp;gtk_widget_get_style (widget)->text[state]);
288 /* draw the text */
289 cairo_move_to (cr, x, y);
290 pango_cairo_show_layout (cr, layout);
291 cairo_destroy (cr);
292           </programlisting></informalexample>
293           Clipping using cairo_clip() is of course not restricted to text
294           rendering and can be used everywhere where GC clips were used.
295           And using gdk_cairo_set_source_color() with style colors should
296           be used in all the places where a style’s GC was used to achieve
297           a particular color.
298         </para>
299       </example>
300     <section>
301       <title>What should you be aware of ?</title>
302       <formalpara><title>No more stippling</title>
303         <para>
304           Stippling is the usage of a bi-level mask, called a #GdkBitmap.
305           It was often used to achieve a checkerboard effect. You can use
306           cairo_mask() to achieve this effect. To get a checkerbox mask,
307           you can use code like this:
308           <informalexample><programlisting>
309 static cairo_pattern_t *
310 gtk_color_button_get_checkered (void)
311 {
312     /* need to respect pixman's stride being a multiple of 4 */
313     static unsigned char data[8] = { 0xFF, 0x00, 0x00, 0x00,
314                                      0x00, 0xFF, 0x00, 0x00 };
315     cairo_surface_t *surface;
316     cairo_pattern_t *pattern;
317
318     surface = cairo_image_surface_create_for_data (data,
319                                                    CAIRO_FORMAT_A8,
320                                                    2, 2,
321                                                    4);
322     pattern = cairo_pattern_create_for_surface (surface);
323     cairo_surface_destroy (surface);
324     cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
325     cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
326
327     return pattern;
328 }
329           </programlisting></informalexample>
330           Note that stippling looks very outdated in UIs, and is rarely
331           used in modern applications. All properties that made use of
332           stippling have been removed from GTK+ 3. Most prominently,
333           stippling is absent from text rendering, in particular #GtkTextTag.
334         </para>
335       </formalpara>
336       <formalpara><title>Using the the target drawable also as source or mask</title>
337         <para>
338           The gdk_draw_drawable() function allowed using the same drawable
339           as source and target. This was often used to achieve a scrolling
340           effect. Cairo does not allow this yet. You can however use
341           cairo_push_group() to get a different intermediate target that
342           you can copy to. So you can replace this code:
343           <informalexample><programlisting>
344 gdk_draw_drawable (pixmap,
345                    gc,
346                    pixmap,
347                    area.x + dx, area.y + dy,
348                    area.x, area.y,
349                    area.width, area.height);
350           </programlisting></informalexample>
351           By using this code:
352           <informalexample><programlisting>
353 cairo_t *cr = gdk_cairo_create (pixmap);
354 /* clipping restricts the intermediate surface's size, so it's a good idea
355  * to use it. */
356 gdk_cairo_rectangle (cr, &amp;area);
357 cairo_clip (cr);
358 /* Now push a group to change the target */
359 cairo_push_group (cr);
360 gdk_cairo_set_source_pixmap (cr, pixmap, dx, dy);
361 cairo_paint (cr);
362 /* Now copy the intermediate target back */
363 cairo_pop_group_to_source (cr);
364 cairo_paint (cr);
365 cairo_destroy (cr);
366           </programlisting></informalexample>
367           The cairo developers plan to add self-copies in the future to allow
368           exactly this effect, so you might want to keep up on cairo
369           development to be able to change your code.
370         </para>
371       </formalpara>
372       <formalpara><title>Using pango_cairo_show_layout(<!-- -->) instead of gdk_draw_layout_with_colors(<!-- -->)</title>
373         <para>
374           GDK provided a way to ignore the color attributes of text and use
375           a hardcoded text color with the gdk_draw_layout_with_colors()
376           function. This is often used to draw text shadows or selections.
377           Pango’s cairo support does not yet provide this functionality. If
378           you use Pango layouts that change colors, the easiest way to achieve
379           a similar effect is using pango_cairo_layout_path() and cairo_fill()
380           instead of gdk_draw_layout_with_colors(). Note that this results in
381           a slightly uglier-looking text, as subpixel anti-aliasing is not
382           supported.
383         </para>
384       </formalpara>
385     </section>
386     </section>
387   </section>
388
389   <section>
390     <title>Changes that need to be done at the time of the switch</title>
391
392   <para>
393     This section outlines porting tasks that you need to tackle when
394     you get to the point that you actually build your application against
395     GTK+ 3. Making it possible to prepare for these in GTK+ 2.24 would
396     have been either impossible or impractical.
397   </para>
398
399   <section>
400     <title>Replace size_request by get_preferred_width/height</title>
401
402     <para>
403       The request-phase of the traditional GTK+ geometry management
404       has been replaced by a more flexible height-for-width system,
405       which is described in detail in the API documentation
406       (see <xref linkend="geometry-management"/>). As a consequence,
407       the ::size-request signal and vfunc has been removed from
408       #GtkWidgetClass. The replacement for size_request() can
409       take several levels of sophistication:
410       <itemizedlist>
411         <listitem>
412         <para>
413         As a minimal replacement to keep current functionality,
414         you can simply implement the #GtkWidgetClass.get_preferred_width() and
415         #GtkWidgetClass.get_preferred_height() vfuncs by calling your existing
416         size_request() function. So you go from
417         <informalexample><programlisting>
418 static void
419 my_widget_class_init (MyWidgetClass *class)
420 {
421   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
422
423   /* ... */
424
425   widget_class->size_request = my_widget_size_request;
426
427   /* ... */
428 }
429         </programlisting></informalexample>
430         <para>
431         to something that looks more like this:
432         </para>
433         <informalexample><programlisting>
434 static void
435 my_widget_get_preferred_width (GtkWidget *widget,
436                                gint      *minimal_width,
437                                gint      *natural_width)
438 {
439   GtkRequisition requisition;
440
441   my_widget_size_request (widget, &amp;requisition);
442
443   *minimal_width = *natural_width = requisition.width;
444 }
445
446 static void
447 my_widget_get_preferred_height (GtkWidget *widget,
448                                 gint      *minimal_height,
449                                 gint      *natural_height)
450 {
451   GtkRequisition requisition;
452
453   my_widget_size_request (widget, &amp;requisition);
454
455   *minimal_height = *natural_height = requisition.height;
456 }
457
458  /* ... */
459
460 static void
461 my_widget_class_init (MyWidgetClass *class)
462 {
463   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
464
465   /* ... */
466
467   widget_class->get_preferred_width = my_widget_get_preferred_width;
468   widget_class->get_preferred_height = my_widget_get_preferred_height;
469
470   /* ... */
471
472 }
473         </programlisting></informalexample>
474           <para>
475           Sometimes you can make things a little more streamlined
476           by replacing your existing size_request() implementation by
477           one that takes an orientation parameter:
478           </para>
479           <informalexample><programlisting>
480 static void
481 my_widget_get_preferred_size (GtkWidget      *widget,
482                               GtkOrientation  orientation,
483                                gint          *minimal_size,
484                                gint          *natural_size)
485 {
486
487   /* do things that are common for both orientations ... */
488
489   if (orientation == GTK_ORIENTATION_HORIZONTAL)
490     {
491       /* do stuff that only applies to width... */
492
493       *minimal_size = *natural_size = ...
494     }
495   else
496    {
497       /* do stuff that only applies to height... */
498
499       *minimal_size = *natural_size = ...
500    }
501 }
502
503 static void
504 my_widget_get_preferred_width (GtkWidget *widget,
505                                gint      *minimal_width,
506                                gint      *natural_width)
507 {
508   my_widget_get_preferred_size (widget,
509                                 GTK_ORIENTATION_HORIZONTAL,
510                                 minimal_width,
511                                 natural_width);
512 }
513
514 static void
515 my_widget_get_preferred_height (GtkWidget *widget,
516                                 gint      *minimal_height,
517                                 gint      *natural_height)
518 {
519   my_widget_get_preferred_size (widget,
520                                 GTK_ORIENTATION_VERTICAL,
521                                 minimal_height,
522                                 natural_height);
523 }
524
525  /* ... */
526           </programlisting></informalexample>
527           </para>
528         </listitem>
529         <listitem>
530           <para>If your widget can cope with a small size,
531           but would appreciate getting some more space (a common
532           example would be that it contains ellipsizable labels),
533           you can do that by making your #GtkWidgetClass.get_preferred_width() /
534           #GtkWidgetClass.get_preferred_height()
535           functions return a smaller value for @minimal than for @natural.
536           For @minimal, you probably want to return the same value
537           that your size_request() function returned before (since
538           size_request() was defined as returning the minimal size
539           a widget can work with). A simple way to obtain good
540           values for @natural, in the case of containers, is to use
541           gtk_widget_get_preferred_width() and
542           gtk_widget_get_preferred_height() on the children of the
543           container, as in the following example:
544           <informalexample><programlisting>
545 static void
546 gtk_fixed_get_preferred_height (GtkWidget *widget,
547                                 gint      *minimum,
548                                 gint      *natural)
549 {
550   GtkFixed *fixed = GTK_FIXED (widget);
551   GtkFixedPrivate *priv = fixed->priv;
552   GtkFixedChild *child;
553   GList *children;
554   gint child_min, child_nat;
555
556   *minimum = 0;
557   *natural = 0;
558
559   for (children = priv->children; children; children = children->next)
560     {
561       child = children->data;
562
563       if (!gtk_widget_get_visible (child->widget))
564         continue;
565
566       gtk_widget_get_preferred_height (child->widget, &amp;child_min, &amp;child_nat);
567
568       *minimum = MAX (*minimum, child->y + child_min);
569       *natural = MAX (*natural, child->y + child_nat);
570     }
571 }
572           </programlisting></informalexample>
573           </para>
574         </listitem>
575         <listitem>
576           <para>
577           Note that the #GtkWidgetClass.get_preferred_width() /
578           #GtkWidgetClass.get_preferred_height() functions
579           only allow you to deal with one dimension at a time. If your
580           size_request() handler is doing things that involve both
581           width and height at the same time (e.g. limiting the aspect
582           ratio), you will have to implement
583           #GtkWidgetClass.get_preferred_height_for_width()
584           and #GtkWidgetClass.get_preferred_width_for_height().
585           </para>
586         </listitem>
587         <listitem>
588           <para>
589           To make full use of the new capabilities of the
590           height-for-width geometry management, you need to additionally
591           implement the #GtkWidgetClass.get_preferred_height_for_width() and
592           #GtkWidgetClass.get_preferred_width_for_height(). For details on
593           these functions, see <xref linkend="geometry-management"/>.
594           </para>
595         </listitem>
596       </itemizedlist>
597     </para>
598   </section>
599
600   <section>
601     <title>Replace GdkRegion by cairo_region_t</title>
602
603     <para>
604       Starting with version 1.10, cairo provides a region API that is
605       equivalent to the GDK region API (which was itself copied from
606       the X server). Therefore, the region API has been removed in GTK+ 3.
607     </para>
608     <para>
609       Porting your application to the cairo region API should be a straight
610       find-and-replace task. Please refer to the following table:
611       <table>
612         <tgroup cols="2">
613           <title>GdkRegion to cairo_region_t</title>
614           <thead>
615             <row><entry>GDK</entry><entry>cairo</entry></row>
616           </thead>
617           <tbody>
618             <row><entry>#GdkRegion</entry><entry>#cairo_region_t</entry></row>
619             <row><entry>#GdkRectangle</entry><entry>#cairo_rectangle_int_t</entry></row>
620             <row><entry>gdk_rectangle_intersect()</entry><entry>this function is still there</entry></row>
621             <row><entry>gdk_rectangle_union()</entry><entry>this function is still there</entry></row>
622             <row><entry>gdk_region_new()</entry><entry>cairo_region_create()</entry></row>
623             <row><entry>gdk_region_copy()</entry><entry>cairo_region_copy()</entry></row>
624             <row><entry>gdk_region_destroy()</entry><entry>cairo_region_destroy()</entry></row>
625             <row><entry>gdk_region_rectangle()</entry><entry>cairo_region_create_rectangle()</entry></row>
626             <row><entry>gdk_region_get_clipbox()</entry><entry>cairo_region_get_extents()</entry></row>
627             <row><entry>gdk_region_get_rectangles()</entry><entry>cairo_region_num_rectangles() and
628                                 cairo_region_get_rectangle()</entry></row>
629             <row><entry>gdk_region_empty()</entry><entry>cairo_region_is_empty()</entry></row>
630             <row><entry>gdk_region_equal()</entry><entry>cairo_region_equal()</entry></row>
631             <row><entry>gdk_region_point_in()</entry><entry>cairo_region_contains_point()</entry></row>
632             <row><entry>gdk_region_rect_in()</entry><entry>cairo_region_contains_rectangle()</entry></row>
633             <row><entry>gdk_region_offset()</entry><entry>cairo_region_translate()</entry></row>
634             <row><entry>gdk_region_union_with_rect()</entry><entry>cairo_region_union_rectangle()</entry></row>
635             <row><entry>gdk_region_intersect()</entry><entry>cairo_region_intersect()</entry></row>
636             <row><entry>gdk_region_union()</entry><entry>cairo_region_union()</entry></row>
637             <row><entry>gdk_region_subtract()</entry><entry>cairo_region_subtract()</entry></row>
638             <row><entry>gdk_region_xor()</entry><entry>cairo_region_xor()</entry></row>
639             <row><entry>gdk_region_shrink()</entry><entry>no replacement</entry></row>
640             <row><entry>gdk_region_polygon()</entry><entry>no replacement, use cairo paths instead</entry></row>
641           </tbody>
642         </tgroup>
643       </table>
644     </para>
645   </section>
646
647   <section>
648     <title>Replace GdkPixmap by cairo surfaces</title>
649     <para>
650       The #GdkPixmap object and related functions have been removed.
651       In the cairo-centric world of GTK+ 3, cairo surfaces take over
652       the role of pixmaps.
653     </para>
654     <example>
655       <title>Creating custom cursors</title>
656       <para>
657         One place where pixmaps were commonly used is to create custom
658         cursors:
659       <informalexample><programlisting>
660 GdkCursor *cursor;
661 GdkPixmap *pixmap;
662 cairo_t *cr;
663 GdkColor fg = { 0, 0, 0, 0 };
664
665 pixmap = gdk_pixmap_new (NULL, 1, 1, 1);
666
667 cr = gdk_cairo_create (pixmap);
668 cairo_rectangle (cr, 0, 0, 1, 1);
669 cairo_fill (cr);
670 cairo_destroy (cr);
671
672 cursor = gdk_cursor_new_from_pixmap (pixmap, pixmap, &amp;fg, &amp;fg, 0, 0);
673
674 g_object_unref (pixmap);
675       </programlisting></informalexample>
676       The same can be achieved without pixmaps, by drawing onto
677       an image surface:
678       <informalexample><programlisting>
679 GdkCursor *cursor;
680 cairo_surface_t *s;
681 cairo_t *cr;
682 GdkPixbuf *pixbuf;
683
684 s = cairo_image_surface_create (CAIRO_FORMAT_A1, 3, 3);
685 cr = cairo_create (s);
686 cairo_arc (cr, 1.5, 1.5, 1.5, 0, 2 * M_PI);
687 cairo_fill (cr);
688 cairo_destroy (cr);
689
690 pixbuf = gdk_pixbuf_get_from_surface (NULL, s,
691                                       0, 0, 0, 0,
692                                       3, 3);
693
694 cairo_surface_destroy (s);
695
696 cursor = gdk_cursor_new_from_pixbuf (display, pixbuf, 0, 0);
697
698 g_object_unref (pixbuf);
699       </programlisting></informalexample>
700       </para>
701     </example>
702   </section>
703
704   <section>
705     <title>Replace GdkColormap by GdkVisual</title>
706     <para>
707       For drawing with cairo, it is not necessary to allocate colors, and
708       a #GdkVisual provides enough information for cairo to handle colors
709       in 'native' surfaces. Therefore, #GdkColormap and related functions
710       have been removed in GTK+ 3, and visuals are used instead. The
711       colormap-handling functions of #GtkWidget (gtk_widget_set_colormap(),
712       etc) have been removed and gtk_widget_set_visual() has been added.
713     </para>
714     <example><title>Setting up a translucent window</title>
715     <para>You might have a screen-changed handler like the following
716      to set up a translucent window with an alpha-channel:
717     </para>
718     <informalexample><programlisting>
719 static void
720 on_alpha_screen_changed (GtkWidget *widget,
721                          GdkScreen *old_screen,
722                          GtkWidget *label)
723 {
724   GdkScreen *screen = gtk_widget_get_screen (widget);
725   GdkColormap *colormap = gdk_screen_get_rgba_colormap (screen);
726
727   if (colormap == NULL)
728     colormap = gdk_screen_get_default_colormap (screen);
729
730   gtk_widget_set_colormap (widget, colormap);
731 }
732     </programlisting></informalexample>
733     <para>
734     With visuals instead of colormaps, this will look as follows:
735     </para>
736     <informalexample><programlisting>
737 static void
738 on_alpha_screen_changed (GtkWindow *window,
739                          GdkScreen *old_screen,
740                          GtkWidget *label)
741 {
742   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
743   GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
744
745   if (visual == NULL)
746     visual = gdk_screen_get_system_visual (screen);
747
748   gtk_widget_set_visual (window, visual);
749 }
750     </programlisting></informalexample>
751     </example>
752   </section>
753
754   <section>
755     <title>GdkDrawable is gone</title>
756
757     <para>
758       #GdkDrawable has been removed in GTK+ 3, together with #GdkPixmap
759       and #GdkImage. The only remaining drawable class is #GdkWindow.
760       For dealing with image data, you should use cairo surfaces or
761       #GdkPixbufs.
762     </para>
763
764     <para>
765       GdkDrawable functions that are useful with windows have been replaced
766       by corresponding GdkWindow functions:
767       <table>
768         <title>GdkDrawable to GdkWindow</title>
769         <tgroup cols="2">
770           <thead>
771             <row><entry>GDK 2.x</entry><entry>GDK 3</entry></row>
772           </thead>
773           <tbody>
774             <row><entry>gdk_drawable_get_visual()</entry><entry>gdk_window_get_visual()</entry></row>
775             <row><entry>gdk_drawable_get_size()</entry><entry>gdk_window_get_width()
776                                                               gdk_window_get_height()</entry></row>
777             <row><entry>gdk_pixbuf_get_from_drawable()</entry><entry>gdk_pixbuf_get_from_window()</entry></row>
778             <row><entry>gdk_drawable_get_clip_region()</entry><entry>gdk_window_get_clip_region()</entry></row>
779             <row><entry>gdk_drawable_get_visible_region()</entry><entry>gdk_window_get_visible_region()</entry></row>
780           </tbody>
781         </tgroup>
782       </table>
783     </para>
784   </section>
785
786   <section>
787     <title>Event filtering</title>
788
789     <para>
790       If your application uses the low-level event filtering facilities in GDK,
791       there are some changes you need to be aware of.
792     </para>
793
794     <para>
795       The special-purpose GdkEventClient events and the gdk_add_client_message_filter() and gdk_display_add_client_message_filter() functions have been
796       removed. Receiving X11 ClientMessage events is still possible, using
797       the general gdk_window_add_filter() API. A client message filter like
798 <informalexample><programlisting>
799 static GdkFilterReturn
800 message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
801 {
802   XClientMessageEvent *evt = (XClientMessageEvent *)xevent;
803
804   /* do something with evt ... */
805 }
806
807  ...
808
809 message_type = gdk_atom_intern ("MANAGER", FALSE);
810 gdk_display_add_client_message_filter (display, message_type, message_filter, NULL);
811 </programlisting></informalexample>
812     then looks like this:
813     <informalexample><programlisting>
814 static GdkFilterReturn
815 event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
816 {
817   XClientMessageEvent *evt;
818   GdkAtom message_type;
819
820   if (((XEvent *)xevent)->type != ClientMessage)
821     return GDK_FILTER_CONTINUE;
822
823   evt = (XClientMessageEvent *)xevent;
824   message_type = XInternAtom (evt->display, "MANAGER", FALSE);
825
826   if (evt->message_type != message_type)
827     return GDK_FILTER_CONTINUE;
828
829   /* do something with evt ... */
830 }
831
832  ...
833
834 gdk_window_add_filter (NULL, message_filter, NULL);
835 </programlisting></informalexample>
836       One advantage of using an event filter is that you can actually
837       remove the filter when you don't need it anymore, using
838       gdk_window_remove_filter().
839     </para>
840
841     <para>
842       The other difference to be aware of when working with event filters
843       in GTK+ 3 is that GDK now uses XI2 by default when available. That
844       means that your application does not receive core X11 key or button
845       events. Instead, all input events are delivered as XIDeviceEvents.
846       As a short-term workaround for this, you can force your application
847       to not use XI2, with gdk_disable_multidevice(). In the long term,
848       you probably want to rewrite your event filter to deal with
849       XIDeviceEvents.
850     </para>
851   </section>
852
853   <section>
854     <title>Backend-specific code</title>
855     <para>
856       In GTK+ 2.x, GDK could only be compiled for one backend at a time,
857       and the %GDK_WINDOWING_X11 or %GDK_WINDOWING_WIN32 macros could
858       be used to find out which one you are dealing with:
859       <informalexample><programlisting>
860 #ifdef GDK_WINDOWING_X11
861       if (timestamp != GDK_CURRENT_TIME)
862         gdk_x11_window_set_user_time (gdk_window, timestamp);
863 #endif
864 #ifdef GDK_WINDOWING_WIN32
865         /* ... win32 specific code ... */
866 #endif
867       </programlisting></informalexample>
868       In GTK+ 3, GDK can be built with multiple backends, and currently
869       used backend has to be determined at runtime, typically using
870       type-check macros on a #GdkDisplay or #GdkWindow. You still need
871       to use the #GDK_WINDOWING macros to only compile code referring
872       to supported backends:
873       <informalexample><programlisting>
874 #ifdef GDK_WINDOWING_X11
875       if (GDK_IS_X11_DISPLAY (display))
876         {
877           if (timestamp != GDK_CURRENT_TIME)
878             gdk_x11_window_set_user_time (gdk_window, timestamp);
879         }
880       else
881 #endif
882 #ifdef GDK_WINDOWING_WIN32
883       if (GDK_IS_WIN32_DISPLAY (display))
884         {
885           /* ... win32 specific code ... */
886         }
887       else
888 #endif
889        {
890          g_warning ("Unsupported GDK backend");
891        }
892       </programlisting></informalexample>
893     </para>
894     <para>
895       If you used the pkg-config variable <varname>target</varname> to
896       conditionally build part of your project depending on the GDK backend,
897       for instance like this:
898       <informalexample><programlisting>
899 AM_CONDITIONAL(BUILD_X11, test `$PKG_CONFIG --variable=target gtk+-2.0` = "x11")
900       </programlisting></informalexample>
901       then you should now use the M4 macro provided by GTK+ itself:
902       <informalexample><programlisting>
903 GTK_CHECK_BACKEND([x11], [3.0.2], [have_x11=yes], [have_x11=no])
904 AM_CONDITIONAL(BUILD_x11, [test "x$have_x11" = "xyes"])
905       </programlisting></informalexample>
906     </para>
907   </section>
908
909   <section>
910     <title>GtkPlug and GtkSocket</title>
911
912     <para>
913       The #GtkPlug and #GtkSocket widgets are now X11-specific, and you
914       have to include the <filename>&lt;gtk/gtkx.h&gt;</filename> header
915       to use them. The previous section about proper handling of
916       backend-specific code applies, if you care about other backends.
917     </para>
918   </section>
919
920   <section>
921     <title>The GtkWidget::draw signal</title>
922     <para>
923       The GtkWidget #GtkWidget::expose-event signal has been replaced by
924       a new #GtkWidget::draw signal, which takes a #cairo_t instead of
925       an expose event. The cairo context is being set up so that the origin
926       at (0, 0) coincides with the upper left corner of the widget, and
927       is properly clipped.
928     </para>
929     <note><para>In other words, the cairo context of the draw signal is set
930       up in 'widget coordinates', which is different from traditional expose
931       event handlers, which always assume 'window coordinates'.
932     </para></note>
933     <para>
934       The widget is expected to draw itself with its allocated size, which
935       is available via the new gtk_widget_get_allocated_width() and
936       gtk_widget_get_allocated_height() functions. It is not necessary to
937       check for GTK_WIDGET_IS_DRAWABLE(), since GTK+ already does this check
938       before emitting the #GtkWidget::draw signal.
939     </para>
940     <para>
941       There are some special considerations for widgets with multiple windows.
942       Expose events are window-specific, and widgets with multiple windows
943       could expect to get an expose event for each window that needs to be
944       redrawn. Therefore, multi-window expose event handlers typically look
945       like this:
946       <informalexample><programlisting>
947       if (event->window == widget->window1)
948         {
949            /* ... draw window1 ... */
950         }
951       else if (event->window == widget->window2)
952         {
953            /* ... draw window2 ... */
954         }
955       ...
956       </programlisting></informalexample>
957       In contrast, the #GtkWidget::draw signal handler may have to draw multiple
958       windows in one call. GTK+ has a convenience function
959       gtk_cairo_should_draw_window() that can be used to find out if
960       a window needs to be drawn. With that, the example above would look
961       like this (note that the 'else' is gone):
962       <informalexample><programlisting>
963       if (gtk_cairo_should_draw_window (cr, widget->window1)
964         {
965            /* ... draw window1 ... */
966         }
967       if (gtk_cairo_should_draw_window (cr, widget->window2)
968         {
969            /* ... draw window2 ... */
970         }
971       ...
972       </programlisting></informalexample>
973       Another convenience function that can help when implementing
974       ::draw for multi-window widgets is gtk_cairo_transform_to_window(),
975       which transforms a cairo context from widget-relative coordinates
976       to window-relative coordinates.
977     </para>
978     <para>
979       All GtkStyle drawing functions (gtk_paint_box(), etc) have been changed
980       to take a #cairo_t instead of a window and a clip area. ::draw
981       implementations will usually just use the cairo context that has been
982       passed in for this.
983     </para>
984     <example><title>A simple ::draw function</title>
985     <programlisting>
986 gboolean
987 gtk_arrow_draw (GtkWidget *widget,
988                 cairo_t   *cr)
989 {
990   gint x, y;
991   gint width, height;
992   gint extent;
993
994   width = gtk_widget_get_allocated_width (widget);
995   height = gtk_widget_get_allocated_height (widget);
996
997   extent = MIN (width - 2 * PAD, height - 2 * PAD);
998   x = PAD;
999   y = PAD;
1000
1001   gtk_paint_arrow (gtk_widget_get_style (widget),
1002                    cr,
1003                    gtk_widget_get_state (widget),
1004                    GTK_SHADOW_OUT,
1005                    widget,
1006                    "arrow",
1007                    widget->priv->arrow_type,
1008                    TRUE,
1009                    x, y, extent, extent);
1010 }
1011     </programlisting>
1012     </example>
1013   </section>
1014
1015   <section>
1016     <title>GtkProgressBar orientation</title>
1017
1018     <para>
1019       In GTK+ 2.x, #GtkProgressBar and #GtkCellRendererProgress were using the
1020       GtkProgressBarOrientation enumeration to specify their orientation and
1021       direction. In GTK+ 3, both the widget and the cell renderer implement
1022       #GtkOrientable, and have an additional 'inverted' property to determine
1023       their direction. Therefore, a call to gtk_progress_bar_set_orientation()
1024       needs to be replaced by a pair of calls to
1025       gtk_orientable_set_orientation() and gtk_progress_bar_set_inverted().
1026       The following values correspond:
1027       <table>
1028         <tgroup cols="3">
1029           <colspec colname="1"/>
1030           <colspec colname="2"/>
1031           <colspec colname="3"/>
1032           <thead>
1033             <row><entry>GTK+ 2.x</entry><entry namest="2" nameend="3">GTK+ 3</entry></row>
1034             <row><entry>GtkProgressBarOrientation</entry><entry>GtkOrientation</entry><entry>inverted</entry></row>
1035           </thead>
1036           <tbody>
1037             <row><entry>GTK_PROGRESS_LEFT_TO_RIGHT</entry><entry>GTK_ORIENTATION_HORIZONTAL</entry><entry>FALSE</entry></row>
1038             <row><entry>GTK_PROGRESS_RIGHT_TO_LEFT</entry><entry>GTK_ORIENTATION_HORIZONTAL</entry><entry>TRUE</entry></row>
1039             <row><entry>GTK_PROGRESS_TOP_TO_BOTTOM</entry><entry>GTK_ORIENTATION_VERTICAL</entry><entry>FALSE</entry></row>
1040             <row><entry>GTK_PROGRESS_BOTTOM_TO_TOP</entry><entry>GTK_ORIENTATION_VERTICAL</entry><entry>TRUE</entry></row>
1041           </tbody>
1042         </tgroup>
1043       </table>
1044     </para>
1045   </section>
1046
1047   <section>
1048     <title>Check your expand and fill flags</title>
1049
1050     <para>
1051       The behaviour of expanding widgets has changed slightly in GTK+ 3,
1052       compared to GTK+ 2.x. It is now 'inherited', i.e. a container that
1053       has an expanding child is considered expanding itself. This is often
1054       the desired behaviour. In places where you don't want this to happen,
1055       setting the container explicity as not expanding will stop the
1056       expand flag of the child from being inherited. See
1057       gtk_widget_set_hexpand() and gtk_widget_set_vexpand().
1058     </para>
1059     <para>
1060       If you experience sizing problems with widgets in ported code,
1061       carefully check the #GtkBox::expand and #GtkBox::fill flags of your
1062       boxes.
1063     </para>
1064   </section>
1065
1066   <section>
1067     <title>Scrolling changes</title>
1068
1069     <para>
1070       The default values for the #GtkScrolledWindow:hscrollbar-policy and
1071       #GtkScrolledWindow:vscrollbar-policy properties have been changed from
1072       'never' to 'automatic'. If your application was relying on the default
1073       value, you will have explicitly set it explicitly.
1074     </para>
1075
1076     <para>
1077       The ::set-scroll-adjustments signal on GtkWidget has been replaced
1078       by the #GtkScrollable interface which must be implemented by a widget
1079       that wants to be placed in a #GtkScrolledWindow. Instead of emitting
1080       ::set-scroll-adjustments, the scrolled window simply sets the
1081       #GtkScrollable::hadjustment and #GtkScrollable::vadjustment properties.
1082     </para>
1083   </section>
1084
1085   <section>
1086     <title>GtkObject is gone</title>
1087
1088     <para>
1089       GtkObject has been removed in GTK+ 3. Its remaining functionality,
1090       the ::destroy signal, has been moved to GtkWidget. If you have non-widget
1091       classes that are directly derived from GtkObject, you have to make
1092       them derive from #GInitiallyUnowned (or, if you don't need the floating
1093       functionality, #GObject). If you have widgets that override the
1094       destroy class handler, you have to adust your class_init function,
1095       since destroy is now a member of GtkWidgetClass:
1096       <informalexample><programlisting>
1097       GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
1098
1099       object_class->destroy = my_destroy;
1100       </programlisting></informalexample>
1101       becomes
1102       <informalexample><programlisting>
1103       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
1104
1105       widget_class->destroy = my_destroy;
1106       </programlisting></informalexample>
1107       In the unlikely case that you have a non-widget class that is derived
1108       from GtkObject and makes use of the destroy functionality, you have
1109       to implement ::destroy yourself.
1110     </para>
1111   </section>
1112
1113   <section>
1114     <title>GtkEntryCompletion signal parameters</title>
1115
1116     <para>
1117       The #GtkEntryCompletion::match-selected and
1118       #GtkEntryCompletion::cursor-on-match signals were erroneously
1119       given the internal filter model instead of the users model.
1120       This oversight has been fixed in GTK+ 3; if you have handlers
1121       for these signals, they will likely need slight adjustments.
1122     </para>
1123   </section>
1124
1125   <section>
1126     <title>Resize grips</title>
1127
1128     <para>
1129      The resize grip functionality has been moved from #GtkStatusbar
1130      to #GtkWindow. Any window can now have resize grips, regardless whether
1131      it has a statusbar or not. The functions
1132      gtk_statusbar_set_has_resize_grip() and gtk_statusbar_get_has_resize_grip()
1133      have disappeared, and instead there are now
1134      gtk_window_set_has_resize_grip() and gtk_window_get_has_resize_grip().
1135     </para>
1136   </section>
1137
1138   <section>
1139     <title>Prevent mixed linkage</title>
1140     <para>
1141       Linking against GTK+ 2.x and GTK+ 3 in the same process is problematic
1142       and can lead to hard-to-diagnose crashes. The gtk_init() function in
1143       both GTK+ 2.22 and in GTK+ 3 tries to detect this situation and abort
1144       with a diagnostic message, but this check is not 100% reliable (e.g. if
1145       the problematic linking happens only in loadable modules).
1146     </para>
1147     <para>
1148       Direct linking of your application against both versions of GTK+ is
1149       easy to avoid; the problem gets harder when your application is using
1150       libraries that are themselves linked against some version of GTK+.
1151       In that case, you have to verify that you are using a version of the
1152       library that is linked against GTK+ 3.
1153     </para>
1154     <para>
1155       If you are using packages provided by a distributor, it is likely that
1156       parallel installable versions of the library exist for GTK+ 2.x and
1157       GTK+ 3, e.g for vte, check for vte3; for webkitgtk look for webkitgtk3,
1158       and so on.
1159     </para>
1160   </section>
1161
1162   <section>
1163   <title>Install GTK+ modules in the right place</title>
1164   <para>
1165     Some software packages install loadable GTK+ modules such as theme engines,
1166     gdk-pixbuf loaders or input methods. Since GTK+ 3 is parallel-installable
1167     with GTK+ 2.x, the two GTK+ versions have separate locations for their
1168     loadable modules. The location for GTK+ 2.x is
1169     <filename><replaceable>libdir</replaceable>/gtk-2.0</filename>
1170     (and its subdirectories), for GTK+ 3 the location is
1171     <filename><replaceable>libdir</replaceable>/gtk-3.0</filename>
1172     (and its subdirectories).
1173   </para>
1174   <para>
1175     For some kinds of modules, namely input methods and pixbuf loaders,
1176     GTK+ keeps a cache file with extra information about the modules.
1177     For GTK+ 2.x, these cache files are located in
1178     <filename><replaceable>sysconfdir</replaceable>/gtk-2.0</filename>.
1179     For GTK+ 3, they have been moved to
1180     <filename><replaceable>libdir</replaceable>/gtk-3.0/3.0.0/</filename>.
1181     The commands that create these cache files have been renamed with a -3
1182     suffix to make them parallel-installable.
1183   </para>
1184   <para>
1185     Note that GTK+ modules often link against libgtk, libgdk-pixbuf, etc.
1186     If that is the case for your module, you have to be careful to link the
1187     GTK+ 2.x version of your module against the 2.x version of the libraries,
1188     and the GTK+ 3 version against hte 3.x versions. Loading a module linked
1189     against libgtk 2.x into an application using GTK+ 3 will lead to
1190     unhappiness and must be avoided.
1191   </para>
1192   </section>
1193
1194   <xi:include href="migrating-GtkStyleContext.xml" />
1195
1196   </section>
1197
1198 </chapter>