summaryrefslogtreecommitdiff
path: root/docs/reference/gtk/migrating-3to4.xml
blob: 4d27d27cbe2d62d9cc36a2df76e98ddcd2c30b96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
]>
<chapter id="gtk-migrating-3-to-4">
  <title>Migrating from GTK+ 3.x to GTK+ 4</title>

  <para>
    GTK+ 4 is a major new version of GTK+ that breaks both API and ABI
    compared to GTK+ 3.x. Thankfully, most of the changes are not hard
    to adapt to and there are a number of steps that you can take to
    prepare your GTK+ 3.x application for the switch to GTK+ 4. After
    that, there's a small number of adjustments that you may have to do
    when you actually switch your application to build against GTK+ 4.
  </para>

  <section>
    <title>Preparation in GTK+ 3.x</title>

    <para>
      The steps outlined in the following sections assume that your
      application is working with GTK+ 3.22, which is the final stable
      release of GTK+ 3.x. It includes all the necessary APIs and tools
      to help you port your application to GTK+ 4. If you are still using
      an older version of GTK+ 3.x, you should first get your application
      to build and work with the latest minor release in the 3.22 series.
    </para>

    <section>
      <title>Do not use deprecated symbols</title>
      <para>
        Over the years, a number of functions, and in some cases, entire
        widgets have been deprecated. These deprecations are clearly spelled
        out in the API reference, with hints about the recommended replacements.
        The API reference for GTK+ 3 also includes an
        <ulink url="https://developer.gnome.org/gtk3/3.22/api-index-deprecated.html">index</ulink> of all deprecated symbols.
      </para>
      <para>
        To verify that your program does not use any deprecated symbols,
        you can use defines to remove deprecated symbols from the header files,
        as follows:
        <programlisting>
        make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
        </programlisting>
      </para>
      <para>
        Note that some parts of our API, such as enumeration values, are
        not well covered by the deprecation warnings. In most cases, using
        them will require you to also use deprecated functions, which will
        trigger warnings.
      </para>
    </section>

    <section>
      <title>Enable diagnostic warnings</title>
      <para>
        Deprecations of properties and signals cannot be caught at compile
        time, as both properties and signals are installed and used after
        types have been instantiated. In order to catch deprecations and
        changes in the run time components, you should use the
        <envar>G_ENABLE_DIAGNOSTIC</envar> environment variable when
        running your application, e.g.:
        <programlisting>
          G_ENABLE_DIAGNOSTIC=1 ./your-app
        </programlisting>
      </para>
    </section>

    <section>
      <title>Do not use widget style properties</title>
      <para>
        Style properties do not exist in GTK+ 4. You should stop using them in
        your custom CSS and in your code.
      </para>
    </section>

    <section>
      <title>Review your window creation flags</title>
      <para>
        GTK+ 4 removes the GDK_WA_CURSOR flag. Instead, just use
        gdk_surface_set_cursor() to set a cursor on the window after
        creating it.
      </para>
      <para>
        GTK+ 4 also removes the GDK_WA_VISUAL flag, and always uses
        an RGBA visual for windows. To prepare your code for this,
        use gdk_surface_set_visual (gdk_screen_get_rgba_visual ()) after
        creating your window.
      </para>
      <para>
        GTK+ 4 also removes the GDK_WA_WMCLASS flag. If you need this
        X11-specific functionality, use XSetClassHint() directly.
      </para>
    </section>

    <section>
      <title>Stop using non-RGBA visuals</title>
      <para>
        GTK+ 4 always uses RGBA visuals for its windows; you should make
        sure that your code works with that.
      </para>
      <para>
        At the same time, you should stop using GdkVisual APIs, this object
        not longer exist in GTK+ 4. Most of its APIs are deprecated already
        and not useful when dealing with RGBA visuals.
      </para>
    </section>

    <section>
      <title>Stop using GtkBox:padding, GtkBox:fill and GtkBox:expand</title>
      <para>
        GTK+4 removes these #GtkBox child properties, so you should not use them.
        You can replace GtkBox:padding using the #GtkWidget:margin properties
        on your #GtkBox child widgets.
      </para>
     <para>
        The fill child property can be replaced by setting appropriate values
        for the #GtkWidget:halign and #GtkWidget:valign properties of the child
        widgets. If you previously set the fill child property to %TRUE, you can
        achieve the same effect by setting the halign or valign properties to
        %GTK_ALIGN_FILL, depending on the parent box -- halign for a horizontal
        box, valign for a vertical one.
      </para>
      <para>
        #GtkBox also uses the expand child property. It can be replaced by setting
        #GtkWidget:hexpand or #GtkWidget:vexpand on the child widgets. To match the
        old behavior of the #GtkBox's expand child property, you need to set
        #GtkWidget:hexpand on the child widgets of a horizontal #GtkBox and
        #GtkWidget:vexpand on the child widgets of a vertical #GtkBox.
      </para>
      <para>
        Note that there's a subtle but important difference between #GtkBox's
        expand and fill child properties and the ones in #GtkWidget: setting
        #GtkWidget:hexpand or #GtkWidget:vexpand to %TRUE will propagate up
        the widget hierarchy, so a pixel-perfect port might require you to reset
        the expansion flags to %FALSE in a parent widget higher up the hierarchy.
      </para>
    </section>

    <section>
      <title>Stop using the state argument of GtkStyleContext getters</title>
      <para>
        The getters in the GtkStyleContext API, such as
        gtk_style_context_get_property(), gtk_style_context_get(),
        or gtk_style_context_get_color() only accept the context's current
        state for their state argument. You should update all callers to pass
        the current state.
      </para>
    </section>

    <section>
      <title>Stop using gdk_pixbuf_get_from_window() and gdk_cairo_set_source_window()</title>
      <para>
        These functions are not supported in GTK+ 4. Instead, either use backend-specific
        APIs, or render your widgets using gtk_widget_render().
      </para>
    </section>

    <section>
      <title>Stop using GtkButton's image-related API</title>
      <para>
        The functions and properties related to automatically add a GtkImage
        to a GtkButton, and using a GtkSetting to control its visibility, are
        not supported in GTK+ 4. Instead, you can just pack a GtkImage inside
        a GtkButton, and control its visibility like you would for any other
        widget. If you only want to add a named icon to a GtkButton, you can
        use gtk_button_set_icon_name().
      </para>
    </section>

  </section>

  <section>
    <title>Changes that need to be done at the time of the switch</title>

    <para>
      This section outlines porting tasks that you need to tackle when
      you get to the point that you actually build your application against
      GTK+ 4. Making it possible to prepare for these in GTK+ 3 would
      have been either impossible or impractical.
    </para>

    <section>
      <title>Stop using GdkScreen</title>
      <para>
        The GdkScreen object has been removed in GTK+ 4. Most of its APIs already
        had replacements in GTK+ 3 and were deprecated, a few remaining replacements
        have been added to GdkDisplay.
      </para>
    </section>

    <section>
      <title>Stop using the root window</title>
      <para>
        The root window is an X11-centric concept that is no longer exposed in the
        backend-neutral GDK API. gdk_surface_get_parent() will return %NULL for toplevel
        windows. If you need to interact with the X11 root window, you can use
        gdk_x11_display_get_xrootwindow() to get its XID.
      </para>
    </section>

    <section>
      <title>Stop using GdkVisual</title>
      <para>
        This object is not useful with current GTK+ drawing APIs and has been removed
        without replacement.
      </para>
    </section>

    <section>
      <title>Stop using GdkDeviceManager</title>
      <para>
        The GdkDeviceManager object has been removed in GTK+ 4. Most of its APIs already
        had replacements in GTK+ 3 and were deprecated in favor of GdkSeat.
      </para>
    </section>

    <section>
      <title>Adapt to GdkSurface API changes</title>
      <para>
        The gdk_surface_new() function has been replaced by a number of more
        specialized constructors: gdk_surface_new_toplevel(), gdk_surface_new_popup(),
        gdk_surface_new_temp(), gdk_surface_new_child(), gdk_surface_new_input(),
        gdk_wayland_surface_new_subsurface(). Use the appropriate ones to create
        your windows.
      </para>
      <para>
        Native and foreign subwindows are no longer supported. These concepts were
        complicating the code and could not be supported across backends.
      </para>
      <para>
        gdk_surface_reparent() is no longer available.
      </para>
    </section>

    <section>
      <title>Stop accessing GdkEvent fields</title>
      <para>
        Direct access to GdkEvent structs is no longer possible in GTK+ 4. Some
        frequently-used fields already had accessors in GTK+ 3, and the remaining
        fields have gained accessors in GTK+ 4.
      </para>
    </section>

    <section>
      <title>Stop using gdk_surface_set_event_compression</title>
      <para>
        Event compression is now always enabled. If you need to see the uncoalesced
        motion history, use gdk_event_get_motion_history().
      </para>
    </section>

    <section>
      <title>Adapt to GdkKeymap API changes</title>
      <para>
        The way to get a keymap has changed slightly. gdk_keymap_get_for_display() has
        been renamed to gdk_display_get_keymap().
      </para>
    </section>

    <section>
      <title>Adapt to GtkHeaderBar API changes</title>
      <para>
        The gtk_header_bar_set_show_close_button() function has been renamed to
        the more accurate name gtk_header_bar_set_show_title_buttons(). The corresponding
        getter and the property itself have also been renamed.
      </para>
    </section>

    <section>
      <title>Adapt to GtkStyleContext API changes</title>
      <para>
        The getters in the GtkStyleContext API, such as
        gtk_style_context_get_property(), gtk_style_context_get(),
        or gtk_style_context_get_color() have lost their state argument,
        and always use the context's current state. Update all callers
        to omit the state argument.
      </para>
    </section>

    <section>
      <title>Adapt to GtkCssProvider API changes</title>
      <para>
        In GTK+ 4, the various #GtkCssProvider load functions have lost
        their #GError argument. If you want to handle CSS loading errors,
        use the #GtkCssProvider::parsing-error signal instead.
      </para>
    </section>

    <section>
      <title>Stop using GtkContainer::border-width</title>
      <para>
        GTK+ 4 has removed the #GtkContainer::border-width property.
        Use other means to influence the spacing of your containers,
        such as the CSS margin and padding properties on child widgets.
      </para>
    </section>

    <section>
      <title>Adapt to GtkWidget's size request changes</title>
      <para>
        GTK+ 3 used five different virtual functions in GtkWidget to
        implement size requisition, namely the gtk_widget_get_preferred_width()
        family of functions. To simplify widget implementations, GTK+4 uses
        only one virtual function, GtkWidgetClass::measure() that widgets
        have to implement.
      </para>
    </section>

    <section>
      <title>Switch to GtkWidget's children APIs</title>
      <para>
        Instead of the GtkContainer subclass, in GTK+ 4, any widget can
        have children, and there is new API to navigate the widget tree:
        gtk_widget_get_first_child(), gtk_widget_get_last_child(),
        gtk_widget_get_next_sibling(), gtk_widget_get_prev_sibling().
        The GtkContainer API still works, but if you are implementing
        your own widgets, you should consider using the new APIs.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-gradient in your CSS</title>
      <para>
        GTK+ now supports standard CSS syntax for both linear and radial
        gradients, just use those.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-icon-effect in your CSS</title>
      <para>
        GTK+ now supports a more versatile -gtk-icon-filter instead. Replace
        -gtk-icon-effect: dim; with -gtk-icon-filter: opacity(0.5); and
        -gtk-icon-effect: hilight; with -gtk-icon-filter: brightness(1.2);.
      </para>
    </section>

    <section>
      <title>Use gtk_widget_measure</title>
      <para>
        gtk_widget_measure() replaces the various gtk_widget_get_preferred_ functions
        for querying sizes.
      </para>
    </section>

    <section>
      <title>Adapt to drawing model changes</title>
      <para>
        This area has seen the most radical changes in the transition from GTK+ 3
        to GTK+ 4. Widgets no longer use a draw() function to render their contents
        to a cairo surface. Instead, they have a snapshot() function that creates
        one or more GskRenderNodes to represent their content. Third-party widgets
        that use a draw() function or a #GtkWidget::draw signal handler for custom
        drawing will need to be converted to use gtk_snapshot_append_cairo().
      </para>
      <para>
        The auxiliary #GtkSnapshot object has APIs to help with creating render
        nodes.
      </para>
      <para>
        If you are using a #GtkDrawingArea for custom drawing, you need to switch
        to using gtk_drawing_area_set_draw_func() to set a draw function instead
        of connnecting a handler to the #GtkWidget::draw signal.
      </para>
    </section>

    <section>
      <title>Stop using APIs to query GdkSurfaces</title>
      <para>
        A number of APIs for querying special-purpose windows have been removed,
        since these windows are no longer publically available:
        gtk_tree_view_get_bin_window(), gtk_viewport_get_bin_window(),
        gtk_viewport_get_view_window().
      </para>
    </section>

    <section>
      <title>Widgets are now visible by default</title>
      <para>
        The default value of #GtkWidget::visible in GTK+ 4 is %TRUE, so you no
        longer need to explicitly show all your widgets. On the flip side, you
        need to hide widgets that are not meant to be visible from the start.
      </para>
      <para>
        A convenient way to remove unnecessary property assignments like this
        from ui files it run the command <command>gtk4-builder-tool simplify --replace</command>
        on them.
      </para>
    </section>

    <section>
      <title>Adapt to changes in animated hiding and showing of widgets</title>
      <para>
        Widgets that appear and disappear with an animation, such as GtkPopover,
        GtkInfoBar, GtkRevealer no longer use gtk_widget_show() and gtk_widget_hide()
        for this, but have gained dedicated APIs for this purpose that you should
        use.
      </para>
    </section>

    <section>
      <title>Stop passing commandline arguments to gtk_init</title>
      <para>
        The gtk_init() and gtk_init_check() functions no longer accept commandline
        arguments. Just call them without arguments. Other initialization functions
        that were purely related to commandline argument handling, such as
        gtk_parse_args() and gtk_get_option_group(), are gone. The APIs to
        initialize GDK separately are also gone, but it is very unlikely
        that you are affected by that.
      </para>
    </section>

    <section>
      <title>GdkPixbuf is deemphasized</title>
      <para>
        A number of #GdkPixbuf-based APIs have been removed. The available replacements
        are either using #GIcon, cairo_surface_t or the newly introduced #GdkTexture class
        instead.
      </para>
      <para>
        If you are dealing with pixbufs, you can use gdk_texture_new_for_pixbuf()
        to convert them to texture objects where needed.
      </para>
    </section>

    <section>
      <title>GtkWidget event signals are deemphasized</title>
      <para>
        Event controllers and #GtkGestures have already been introduced in GTK+ 3 to handle
        input for many cases. In GTK+ 4, even more are available, such as #GtkEventControllerScroll
        and GtkEventControllerMotion, and the traditional widget signals for handling input,
        such as #GtkWidget::motion-event or #GtkWidget::event have been deprecated.
      </para>
    </section>

    <section>
      <title>The gtk_window_fullscreen_on_monitor API has changed</title>
      <para>
        Instead of a monitor number, gtk_window_fullscreen_on_monitor() now takes a
        #GdkMonitor argument.
      </para>
    </section>

    <section>
      <title>Adapt to cursor API changes</title>
      <para>
        Use the new gtk_widget_set_cursor() function to set cursors, instead of
        setting the cursor on the underlying window directly. This is necessary
        because most widgets don't have their own window anymore, turning any
        such calls into global cursor changes.
      </para>
      <para>
        For creating standard cursors, gdk_cursor_new_for_display() has been removed,
        you have to use cursor names instead of GdkCursorType. For creating custom cursors,
        use gdk_cursor_new_from_texture(). The ability to get cursor images has been removed.
      </para>
    </section>

    <section>
      <title>Adapt to icon size API changes</title>
      <para>
        Instead of the existing extensible set of symbolic icon sizes, GTK+ now only
        supports normal and large icons with the #GtkIconSize enumeration. The actual sizes
        can be defined by themes via the CSS property -gtk-icon-size.
      </para>
      <para>
        GtkImage setters like gtk_image_set_from_icon_name() no longer take a #GtkIconSize
        argument. You can use the separate gtk_image_set_icon_size() setter if you need
        to override the icon size.
      </para>
      <para>
        The ::stock-size property of GtkCellRendererPixbuf has been renamed to
        #GtkCellRendererPixbuf:icon-size.
      </para>
    </section>
  </section>

</chapter>