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'">
6 <chapter id="gtk-migrating-2-to-3">
7 <title>Migrating from GTK+ 2.x to GTK+ 3</title>
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.
20 <title>Preparation in GTK+ 2.x</title>
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.
32 <title>Do not include individual headers</title>
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
41 <term><filename>gtk/gtk.h</filename></term>
42 <listitem>for GTK</listitem>
45 <term><filename>gtk/gtkunixprint.h</filename></term>
46 <listitem>for low-level, UNIX-specific printing functions</listitem>
49 <term><filename>gdk/gdk.h</filename></term>
50 <listitem>for GDK</listitem>
53 <term><filename>gdk/gdkx.h</filename></term>
54 <listitem>for GDK functions that are X11-specific</listitem>
57 <term><filename>gdk/gdkwin32.h</filename></term>
58 <listitem>for GDK functions that are Windows-specific</listitem>
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>.)
66 To check that your application only includes the allowed headers,
67 you can use defines to disable inclusion of individual headers,
70 make CFLAGS+="-DGTK_DISABLE_SINGLE_INCLUDES"
76 <title>Do not use deprecated symbols</title>
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
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,
90 make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
96 <title>Use accessor functions instead of direct access</title>
98 GTK+ 3 removes many implementation details and struct members from
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
109 make CFLAGS+="-DGSEAL_ENABLE"
115 <title>Replace GDK_<keyname> with GDK_KEY_<keyname></title>
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.
128 <title>Use GIO for launching applications</title>
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:
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
142 <informalexample><programlisting>
144 GAppLaunchContext *context;
145 GError *error = NULL;
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, &error);
153 g_warning ("Failed to launch epiphany: %s", error->message);
154 g_error_free (error);
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().
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.
179 <title>Use cairo for drawing</title>
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.
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.
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
199 <title>Drawing a GdkPixbuf onto a GdkWindow</title>
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,
208 gdk_pixbuf_get_width (pixbuf),
209 gdk_pixbuf_get_height (pixbuf),
210 GDK_RGB_DITHER_NORMAL,
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);
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().
226 <title>Drawing a tiled GdkPixmap to a GdkWindow</title>
228 Tiled pixmaps are often used for drawing backgrounds.
229 Old code looked something like this:
230 <informalexample><programlisting>
231 GdkGCValues gc_values;
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);
240 gdk_draw_rectangle (drawable, gc, TRUE, 0, 0, width, height);
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>
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);
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().
263 <title>Drawing a PangoLayout to a clipped area</title>
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>
271 gc = gtk_widget_get_style (widget)->text_gc[state];
272 gdk_gc_set_clip_rectangle (gc, &area);
274 gdk_draw_layout (drawable, gc, x, y, layout);
276 gdk_gc_set_clip_rectangle (gc, NULL);
277 </programlisting></informalexample>
278 With cairo, the same effect can be achieved using:
279 <informalexample><programlisting>
282 cr = gdk_cairo_create (drawable);
284 gdk_cairo_rectangle (cr, &area);
286 /* set the correct source color */
287 gdk_cairo_set_source_color (cr, &gtk_widget_get_style (widget)->text[state]);
289 cairo_move_to (cr, x, y);
290 pango_cairo_show_layout (cr, layout);
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
301 <title>What should you be aware of ?</title>
302 <formalpara><title>No more stippling</title>
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)
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;
318 surface = cairo_image_surface_create_for_data (data,
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);
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.
336 <formalpara><title>Using the the target drawable also as source or mask</title>
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,
347 area.x + dx, area.y + dy,
349 area.width, area.height);
350 </programlisting></informalexample>
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
356 gdk_cairo_rectangle (cr, &area);
358 /* Now push a group to change the target */
359 cairo_push_group (cr);
360 gdk_cairo_set_source_pixmap (cr, pixmap, dx, dy);
362 /* Now copy the intermediate target back */
363 cairo_pop_group_to_source (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.
372 <formalpara><title>Using pango_cairo_show_layout(<!-- -->) instead of gdk_draw_layout_with_colors(<!-- -->)</title>
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
390 <title>Changes that need to be done at the time of the switch</title>
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.
400 <title>Replace size_request by get_preferred_width/height</title>
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:
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>
419 my_widget_class_init (MyWidgetClass *class)
421 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
425 widget_class->size_request = my_widget_size_request;
429 </programlisting></informalexample>
431 to something that looks more like this:
433 <informalexample><programlisting>
435 my_widget_get_preferred_width (GtkWidget *widget,
439 GtkRequisition requisition;
441 my_widget_size_request (widget, &requisition);
443 *minimal_width = *natural_width = requisition.width;
447 my_widget_get_preferred_height (GtkWidget *widget,
448 gint *minimal_height,
449 gint *natural_height)
451 GtkRequisition requisition;
453 my_widget_size_request (widget, &requisition);
455 *minimal_height = *natural_height = requisition.height;
461 my_widget_class_init (MyWidgetClass *class)
463 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
467 widget_class->get_preferred_width = my_widget_get_preferred_width;
468 widget_class->get_preferred_height = my_widget_get_preferred_height;
473 </programlisting></informalexample>
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:
479 <informalexample><programlisting>
481 my_widget_get_preferred_size (GtkWidget *widget,
482 GtkOrientation orientation,
487 /* do things that are common for both orientations ... */
489 if (orientation == GTK_ORIENTATION_HORIZONTAL)
491 /* do stuff that only applies to width... */
493 *minimal_size = *natural_size = ...
497 /* do stuff that only applies to height... */
499 *minimal_size = *natural_size = ...
504 my_widget_get_preferred_width (GtkWidget *widget,
508 my_widget_get_preferred_size (widget,
509 GTK_ORIENTATION_HORIZONTAL,
515 my_widget_get_preferred_height (GtkWidget *widget,
516 gint *minimal_height,
517 gint *natural_height)
519 my_widget_get_preferred_size (widget,
520 GTK_ORIENTATION_VERTICAL,
526 </programlisting></informalexample>
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>
546 gtk_fixed_get_preferred_height (GtkWidget *widget,
550 GtkFixed *fixed = GTK_FIXED (widget);
551 GtkFixedPrivate *priv = fixed->priv;
552 GtkFixedChild *child;
554 gint child_min, child_nat;
559 for (children = priv->children; children; children = children->next)
561 child = children->data;
563 if (!gtk_widget_get_visible (child->widget))
566 gtk_widget_get_preferred_height (child->widget, &child_min, &child_nat);
568 *minimum = MAX (*minimum, child->y + child_min);
569 *natural = MAX (*natural, child->y + child_nat);
572 </programlisting></informalexample>
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().
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"/>.
601 <title>Replace GdkRegion by cairo_region_t</title>
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.
609 Porting your application to the cairo region API should be a straight
610 find-and-replace task. Please refer to the following table:
613 <title>GdkRegion to cairo_region_t</title>
615 <row><entry>GDK</entry><entry>cairo</entry></row>
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>
648 <title>Replace GdkPixmap by cairo surfaces</title>
650 The #GdkPixmap object and related functions have been removed.
651 In the cairo-centric world of GTK+ 3, cairo surfaces take over
655 <title>Creating custom cursors</title>
657 One place where pixmaps were commonly used is to create custom
659 <informalexample><programlisting>
663 GdkColor fg = { 0, 0, 0, 0 };
665 pixmap = gdk_pixmap_new (NULL, 1, 1, 1);
667 cr = gdk_cairo_create (pixmap);
668 cairo_rectangle (cr, 0, 0, 1, 1);
672 cursor = gdk_cursor_new_from_pixmap (pixmap, pixmap, &fg, &fg, 0, 0);
674 g_object_unref (pixmap);
675 </programlisting></informalexample>
676 The same can be achieved without pixmaps, by drawing onto
678 <informalexample><programlisting>
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);
690 pixbuf = gdk_pixbuf_get_from_surface (NULL, s,
694 cairo_surface_destroy (s);
696 cursor = gdk_cursor_new_from_pixbuf (display, pixbuf, 0, 0);
698 g_object_unref (pixbuf);
699 </programlisting></informalexample>
705 <title>Replace GdkColormap by GdkVisual</title>
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.
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:
718 <informalexample><programlisting>
720 on_alpha_screen_changed (GtkWidget *widget,
721 GdkScreen *old_screen,
724 GdkScreen *screen = gtk_widget_get_screen (widget);
725 GdkColormap *colormap = gdk_screen_get_rgba_colormap (screen);
727 if (colormap == NULL)
728 colormap = gdk_screen_get_default_colormap (screen);
730 gtk_widget_set_colormap (widget, colormap);
732 </programlisting></informalexample>
734 With visuals instead of colormaps, this will look as follows:
736 <informalexample><programlisting>
738 on_alpha_screen_changed (GtkWindow *window,
739 GdkScreen *old_screen,
742 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
743 GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
746 visual = gdk_screen_get_system_visual (screen);
748 gtk_widget_set_visual (window, visual);
750 </programlisting></informalexample>
755 <title>GdkDrawable is gone</title>
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
765 GdkDrawable functions that are useful with windows have been replaced
766 by corresponding GdkWindow functions:
768 <title>GdkDrawable to GdkWindow</title>
771 <row><entry>GDK 2.x</entry><entry>GDK 3</entry></row>
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>
787 <title>Event filtering</title>
790 If your application uses the low-level event filtering facilities in GDK,
791 there are some changes you need to be aware of.
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)
802 XClientMessageEvent *evt = (XClientMessageEvent *)xevent;
804 /* do something with evt ... */
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)
817 XClientMessageEvent *evt;
818 GdkAtom message_type;
820 if (((XEvent *)xevent)->type != ClientMessage)
821 return GDK_FILTER_CONTINUE;
823 evt = (XClientMessageEvent *)xevent;
824 message_type = XInternAtom (evt->display, "MANAGER", FALSE);
826 if (evt->message_type != message_type)
827 return GDK_FILTER_CONTINUE;
829 /* do something with evt ... */
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().
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
854 <title>Backend-specific code</title>
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);
864 #ifdef GDK_WINDOWING_WIN32
865 /* ... win32 specific code ... */
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))
877 if (timestamp != GDK_CURRENT_TIME)
878 gdk_x11_window_set_user_time (gdk_window, timestamp);
882 #ifdef GDK_WINDOWING_WIN32
883 if (GDK_IS_WIN32_DISPLAY (display))
885 /* ... win32 specific code ... */
890 g_warning ("Unsupported GDK backend");
892 </programlisting></informalexample>
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>
910 <title>GtkPlug and GtkSocket</title>
913 The #GtkPlug and #GtkSocket widgets are now X11-specific, and you
914 have to include the <filename><gtk/gtkx.h></filename> header
915 to use them. The previous section about proper handling of
916 backend-specific code applies, if you care about other backends.
921 <title>The GtkWidget::draw signal</title>
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
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'.
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.
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
946 <informalexample><programlisting>
947 if (event->window == widget->window1)
949 /* ... draw window1 ... */
951 else if (event->window == widget->window2)
953 /* ... draw window2 ... */
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)
965 /* ... draw window1 ... */
967 if (gtk_cairo_should_draw_window (cr, widget->window2)
969 /* ... draw window2 ... */
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.
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
984 <example><title>A simple ::draw function</title>
987 gtk_arrow_draw (GtkWidget *widget,
994 width = gtk_widget_get_allocated_width (widget);
995 height = gtk_widget_get_allocated_height (widget);
997 extent = MIN (width - 2 * PAD, height - 2 * PAD);
1001 gtk_paint_arrow (gtk_widget_get_style (widget),
1003 gtk_widget_get_state (widget),
1007 widget->priv->arrow_type,
1009 x, y, extent, extent);
1016 <title>GtkProgressBar orientation</title>
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:
1029 <colspec colname="1"/>
1030 <colspec colname="2"/>
1031 <colspec colname="3"/>
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>
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>
1048 <title>Check your expand and fill flags</title>
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().
1060 If you experience sizing problems with widgets in ported code,
1061 carefully check the #GtkBox::expand and #GtkBox::fill flags of your
1067 <title>Scrolling changes</title>
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.
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.
1086 <title>GtkObject is gone</title>
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);
1099 object_class->destroy = my_destroy;
1100 </programlisting></informalexample>
1102 <informalexample><programlisting>
1103 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
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.
1114 <title>GtkEntryCompletion signal parameters</title>
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.
1126 <title>Resize grips</title>
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().
1139 <title>Prevent mixed linkage</title>
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).
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.
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,
1163 <title>Install GTK+ modules in the right place</title>
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).
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.
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.
1194 <xi:include href="migrating-GtkStyleContext.xml" />