1Title: Migrating from GTK 3.x to GTK 4
2Slug: gtk-migrating-3-to-4
3
4GTK 4 is a major new version of GTK that breaks both API and ABI
5compared to GTK 3.x. Thankfully, most of the changes are not hard
6to adapt to and there are a number of steps that you can take to
7prepare your GTK 3.x application for the switch to GTK 4. After
8that, there's a number of adjustments that you may have to do
9when you actually switch your application to build against GTK 4.
10
11## Preparation in GTK 3.x
12
13The steps outlined in the following sections assume that your
14application is working with GTK 3.24, which is the final stable
15release of GTK 3.x. It includes all the necessary APIs and tools
16to help you port your application to GTK 4. If you are using
17an older version of GTK 3.x, you should first get your application
18to build and work with the latest minor release in the 3.24 series.
19
20### Do not use deprecated symbols
21
22Over the years, a number of functions, and in some cases, entire
23widgets have been deprecated. These deprecations are clearly spelled
24out in the API reference, with hints about the recommended replacements.
25The API reference for GTK 3 also includes an
26[index](https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html)
27of all deprecated symbols.
28
29To verify that your program does not use any deprecated symbols,
30you can use defines to remove deprecated symbols from the header files,
31as follows:
32
33```
34make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
35```
36
37Note that some parts of our API, such as enumeration values, are
38not well covered by the deprecation warnings. In most cases, using
39them will require you to also use deprecated functions, which will
40trigger warnings.
41
42### Enable diagnostic warnings
43
44Deprecations of properties and signals cannot be caught at compile
45time, as both properties and signals are installed and used after
46types have been instantiated. In order to catch deprecations and
47changes in the run time components, you should use the
48`G_ENABLE_DIAGNOSTIC` environment variable when running your
49application, e.g.:
50
51```
52G_ENABLE_DIAGNOSTIC=1 ./your-app
53```
54
55### Do not use GTK-specific command line arguments
56
57GTK 4 does not parse command line arguments any more. If you are using
58command line arguments like `--gtk-debug` you should use the `GTK_DEBUG`
59environment variable instead. If you are using `--g-fatal-warnings` for
60debugging purposes, you should use the `G_DEBUG` environment variable, as
61specified by the
62[GLib documentation](https://developer.gnome.org/glib/stable/glib-running.html).
63
64### Do not use widget style properties
65
66Style properties do not exist in GTK 4. You should stop using them in
67your custom CSS and in your code.
68
69### Review your window creation flags
70
71GTK 4 removes the `GDK_WA_CURSOR` flag. Instead, just use
72`gdk_window_set_cursor()` to set a cursor on the window after
73creating it. GTK 4 also removes the `GDK_WA_VISUAL` flag, and
74always uses an RGBA visual for windows. To prepare your code for
75this, use `gdk_window_set_visual (gdk_screen_get_rgba_visual ())`
76after creating your window. GTK 4 also removes the `GDK_WA_WMCLASS`
77flag. If you need this X11-specific functionality, use `XSetClassHint()`
78directly.
79
80### Stop using direct access to GdkEvent structs
81
82In GTK 4, event structs are opaque and immutable. Many fields already
83have accessors in GTK 3, and you should use those to reduce the amount
84of porting work you have to do at the time of the switch.
85
86### Stop using `gdk_pointer_warp()`
87
88Warping the pointer is disorienting and unfriendly to users.
89GTK 4 does not support it. In special circumstances (such as when
90implementing remote connection UIs) it can be necessary to
91warp the pointer; in this case, use platform APIs such as
92`XWarpPointer()` directly.
93
94### Stop using non-RGBA visuals
95
96GTK 4 always uses RGBA visuals for its windows; you should make
97sure that your code works with such visuals. At the same time,
98you should stop using `GdkVisual` APIs, since this object not longer
99exists in GTK 4. Most of its APIs are deprecated already and not
100useful when dealing with RGBA visuals.
101
102### Stop using `gtk_widget_set_app_paintable`
103
104This is gone in GTK4 with no direct replacement. But for some usecases there
105are alternatives. If you want to make the background transparent, you can set
106the background color to, for example, `rgba(255, 255, 255, 0)` using CSS instead.
107
108### Stop using `GtkBox` padding, fill and expand child properties
109
110GTK 4 removes these [class@Gtk.Box] child properties, so you should stop using
111them. You can replace `GtkBox:padding` using `GtkWidget`'s `margin-*` properties
112on your child widgets.
113
114The fill child property can be replaced by setting appropriate values for
115the [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign] properties
116of the child widgets. If you previously set the `fill` child property to
117`TRUE`, you can achieve the same effect by setting the `halign` or `valign`
118properties to `GTK_ALIGN_FILL`, depending on the parent box -- `halign` for a
119horizontal box, `valign` for a vertical one.
120
121[class@Gtk.Box] also uses the expand child property. It can be replaced by
122setting [property@Gtk.Widget:hexpand] or [property@Gtk.Widget:vexpand] on
123the child widgets. To match the old behavior of the `GtkBox`'s expand child
124property, you need to set `hexpand` on the child widgets of a horizontal
125`GtkBox` and `vexpand` on the child widgets of a vertical `GtkBox`.
126
127Note that there's a subtle but important difference between `GtkBox`'s
128`expand` and `fill` child properties and the ones in `GtkWidget`: setting
129[property@Gtk.Widget:hexpand] or [property@Gtk.Widget:vexpand] to `TRUE`
130will propagate up the widget hierarchy, so a pixel-perfect port might
131require you to reset the expansion flags to `FALSE` in a parent widget higher
132up the hierarchy.
133
134### Stop using the state argument of `GtkStyleContext` getters
135
136The getters in the [class@Gtk.StyleContext] API, such as
137`gtk_style_context_get_property()`, `gtk_style_context_get()`,
138or `gtk_style_context_get_color()` only accept the context's current
139state for their state argument. You should update all callers to pass
140the current state.
141
142### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_window()`
143
144These functions are not supported in GTK 4. Instead, either use
145backend-specific APIs, or render your widgets using
146[vfunc@Gtk.Widget.snapshot], once you are using GTK 4.
147
148### Stop using `GtkButton`'s image-related API
149
150The functions and properties related to automatically add a
151[class@Gtk.Image] to a [class@Gtk.Button], and using a `GtkSetting` to
152control its visibility, are not supported in GTK 4. Instead, you can just
153pack a GtkImage inside a GtkButton, and control its visibility like you
154would for any other widget. If you only want to add a named icon to a
155GtkButton, you can use [ctor@Gtk.Button.new_from_icon_name].
156
157### Stop using `GtkWidget` event signals
158
159Event controllers and gestures replace event signals in GTK 4.
160
161Most of them have been backported to GTK 3.x so you can prepare
162for this change.
163
164| Signal | Event controller |
165| --- | --- |
166| ::event | [class@Gtk.EventControllerLegacy] |
167| ::event-after | [class@Gtk.EventControllerLegacy] |
168| ::button-press-event | [class@Gtk.GestureClick] |
169| ::button-release-event | [class@Gtk.GestureClick] |
170| ::touch-event | various touch gestures |
171| ::scroll-event | [class@Gtk.EventControllerScroll] |
172| ::motion-notify-event | [class@Gtk.EventControllerMotion] |
173| ::delete-event | - |
174| ::key-press-event | [class@Gtk.EventControllerKey] |
175| ::key-release-event | [class@Gtk.EventControllerKey] |
176| ::enter-notify-event | [class@Gtk.EventControllerMotion] |
177| ::leave-notify-event | [class@Gtk.EventControllerMotion] |
178| ::configure-event | - |
179| ::focus-in-event | [class@Gtk.EventControllerFocus] |
180| ::focus-out-event | [class@Gtk.EventControllerFocus] |
181| ::map-event | - |
182| ::unmap-event | - |
183| ::property-notify-event | replaced by [class@Gdk.Clipboard] |
184| ::selection-clear-event | replaced by [class@Gdk.Clipboard] |
185| ::selection-request-event | replaced by [class@Gdk.Clipboard] |
186| ::selection-notify-event | replaced by [class@Gdk.Clipboard] |
187| Drag-and-Drop signals | [class@Gtk.DragSource], [class@Gtk.DropTarget] |
188| ::proximity-in-event | [class@Gtk.GestureStylus] |
189| ::proximity-out-event | [class@Gtk.GestureStylus] |
190| ::visibility-notify-event | - |
191| ::window-state-event | - |
192| ::damage-event | - |
193| ::grab-broken-event | - |
194
195Event signals which are not directly related to input have to be dealt with
196on a one-by-one basis:
197
198 - If you were using `::configure-event` and `::window-state-event` to save
199   window state, you should use property notification for corresponding
200   [class@Gtk.Window] properties, such as [property@Gtk.Window:default-width],
201   [property@Gtk.Window:default-height], [property@Gtk.Window:maximized] or
202   [property@Gtk.Window:fullscreened].
203 - If you were using `::delete-event` to present a confirmation when using
204   the close button of a window, you should use the
205   [signal@Gtk.Window::close-request] signal.
206 - If you were using `::map-event` and `::unmap-event` to track a window
207   being mapped, you should use property notification for the
208   [property@Gdk.Surface:mapped] property instead.
209 - The `::damage-event` signal has no replacement, as the only consumer
210   of damage events were the offscreen GDK surfaces, which have no
211   replacement in GTK 4.x.
212
213### Set a proper application ID
214
215In GTK 4 we want the application's `GApplication` 'application-id' (and
216therefore the D-Bus name), the desktop file basename and Wayland's xdg-shell
217`app_id` to match. In order to achieve this with GTK 3.x call
218`g_set_prgname()` with the same application ID you passed to
219[class@Gtk.Application].  Rename your desktop files to match the application
220ID if needed.
221
222The call to `g_set_prgname()` can be removed once you fully migrated to GTK 4.
223
224You should be aware that changing the application ID makes your
225application appear as a new, different app to application installers.
226You should consult the appstream documentation for best practices
227around renaming applications.
228
229### Stop using `gtk_main()` and related APIs
230
231GTK 4 removes the `gtk_main_*` family of APIs. The recommended replacement
232is [class@Gtk.Application], but you can also iterate the GLib main loop directly,
233using `GMainContext` APIs. The replacement for `gtk_events_pending()` is
234`g_main_context_pending()`, the replacement for `gtk_main_iteration()` is
235`g_main_context_iteration()`.
236
237In GTK 4, you can use this replacement that will iterate the default main loop
238until all windows have been closed:
239
240```
241while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
242  g_main_context_iteration (NULL, TRUE);
243```
244
245### Reduce the use of `gtk_widget_destroy()`
246
247GTK 4 introduces a [method@Gtk.Window.destroy] api. While that is not available
248in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()`
249only on toplevel windows, and replace all other uses with
250`gtk_container_remove()` or `g_object_unref()`.
251
252### Stop using the GtkWidget.destroy vfunc
253
254Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
255
256### Reduce the use of generic container APIs
257
258GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
259is not always a replacement for `gtk_container_remove()` in GTK 3, you can
260replace many uses of `gtk_container_add()` with equivalent container-specific
261APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce
262the amount of work you have to do at the time of the switch.
263
264### Review your use of icon resources
265
266When using icons as resources, the behavior of GTK 4 is different in one
267respect: Icons that are directly in `$APP_ID/icons/` are treated as unthemed
268icons, which also means that symbolic icons are not recolored. If you want
269your icon resources to have icon theme semantics, they need to be placed
270into theme subdirectories such as `$APP_ID/icons/16x16/actions` or
271`$APP_ID/icons/scalable/status`.
272
273This location works fine in GTK 3 too, so you can prepare for this change
274before switching to GTK 4.
275
276## Changes that need to be done at the time of the switch
277
278This section outlines porting tasks that you need to tackle when
279you get to the point that you actually build your application against
280GTK 4. Making it possible to prepare for these in GTK 3 would
281have been either impossible or impractical.
282
283### Larger changes
284
285Some of the larger themes of GTK 4 development are hard to cover in the form
286of checklist items, so we mention them separately up-front.
287
288#### Subclassing
289
290Compared to previous versions, GTK 4 emphasizes composition and delegation
291over subclassing. As a consequence, many widgets can no longer be subclassed.
292In most cases, you should look deriving your widget directly from GtkWidget
293and use complex widgets as child widgets instead of deriving from them.
294
295#### Life-cycle handling
296
297Widgets in GTK 4 are treated like any other objects - their parent widget
298holds a reference on them, and GTK holds a reference on toplevel windows.
299[method@Gtk.Window.destroy] will drop the reference on the toplevel window,
300and cause the whole widget hierarchy to be finalized unless there are other
301references that keep widgets alive.
302
303The [signal@Gtk.Widget::destroy] signal is emitted when a widget is
304disposed, and therefore can no longer be used to break reference cycles.
305A typical sign of a reference cycle involving a toplevel window is when
306closing the window does not make the application quit.
307
308### Stop using GdkScreen
309
310The `GdkScreen` object has been removed in GTK 4. Most of its APIs already
311had replacements in GTK 3 and were deprecated, a few remaining replacements
312have been added to `GdkDisplay`.
313
314### Stop using the root window
315
316The root window is an X11-centric concept that is no longer exposed in the
317backend-neutral GDK API. If you need to interact with the X11 root window,
318you can use [method@GdkX11.Display.get_xrootwindow] to get its XID.
319
320### Stop using `GdkVisual`
321
322This object is not useful with current GTK drawing APIs and has been removed
323without replacement.
324
325### Stop using `GdkDeviceManager`
326
327The `GdkDeviceManager` object has been removed in GTK 4. Most of its APIs already
328had replacements in GTK 3 and were deprecated in favor of `GdkSeat`.
329
330### Adapt to `GdkWindow` API changes
331
332`GdkWindow` has been renamed to `GdkSurface`.
333
334In GTK 4, the two roles of a standalone toplevel window and of a popup that
335is placed relative to a parent window have been separated out into two
336interfaces, [class@Gdk.Toplevel] and [class@Gdk.Popup]. Surfaces
337implementing these interfaces are created with [ctor@Gdk.Surface.new_toplevel]
338and [ctor@Gdk.Surface.new_popup], respectively, and they are presented on
339screen using [method@Gdk.Toplevel.present] and [method@Gdk.Popup.present].
340The `present()` functions take parameters in the form of an auxiliary layout
341struct, [struct@Gdk.PopupLayout] or [struct@Gdk.ToplevelLayout].
342
343If your code is dealing directly with surfaces, you may have to change it
344to call the API in these interfaces, depending on whether the surface you are
345dealing with is a toplevel or a popup.
346
347As part of this reorganization, X11-only concepts such as sticky,
348keep-below, urgency, skip-taskbar or window groups have either been
349removed or moved to X11 backend api. If you need to use them on your
350X11 windows, you will have to use those backend apis or set the
351corresponding X11 properties (as specified in the EWMH) yourself.
352
353Subsurfaces are not currently supported. Native and foreign subwindows
354are no longer supported. These concepts were complicating the code
355and could not be supported across backends.
356
357A number of GdkWindow APIs are no longer available. This includes
358`gdk_window_reparent()`, `gdk_window_set_geometry_hints()`, `gdk_window_raise()`,
359`gdk_window_restack()`, `gdk_window_move()`, `gdk_window_resize()`. If
360you need to manually control the position or stacking of your X11
361windows, you you will have to use Xlib apis.
362
363A number of minor API cleanups have happened in `GdkSurface`
364as well. For example, `gdk_surface_input_shape_combine_region()`
365has been renamed to [method@Gdk.Surface.set_input_region], and
366`gdk_surface_begin_resize_drag()` has been renamed to
367[method@Gdk.Toplevel.begin_resize].
368
369### The "iconified" window state has been renamed to "minimized"
370
371The `GDK_TOPLEVEL_STATE_ICONIFIED` value of the `GdkSurfaceState` enumeration
372is now `GDK_TOPLEVEL_STATE_MINIMIZED` in the `GdkToplevelState` enumeration.
373
374The `GdkWindow` functions `gdk_window_iconify()` and
375`gdk_window_deiconify()` have been renamed to [method@Gdk.Toplevel.minimize]
376and [method@Gdk.Toplevel.present], respectively.
377
378The behavior of the minimization and unminimization operations have
379not been changed, and they still require support from the underlying
380windowing system.
381
382### Adapt to `GdkEvent` API changes
383
384Direct access to [class@Gdk.Event] structs is no longer possible in GTK 4.
385`GdkEvent` is now a strictly read-only type, and you can no longer
386change any of its fields, or construct new events. All event fields
387have accessors that you will have to use.
388
389Event compression is always enabled in GTK 4, for both motion and
390scroll events. If you need to see the uncoalesced motion or scroll
391history, use [method@Gdk.Event.get_history] on the latest event.
392
393### Stop using grabs
394
395GTK 4 no longer provides the `gdk_device_grab()` or `gdk_seat_grab()`
396apis. If you need to dismiss a popup when the user clicks outside
397(the most common use for grabs), you can use the `GdkPopup`
398[property@Gdk.Popup:autohide] property instead. [class@Gtk.Popover]
399also has a [property@Gtk.Popover:autohide] property for this. If you
400need to prevent the user from interacting with a window while a dialog
401is open, use the [property@Gtk.Window:modal] property of the dialog.
402
403### Adapt to coordinate API changes
404
405A number of coordinate APIs in GTK 3 had `double` variants:
406`gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`.
407These have been changed to use doubles, and the `double` variants
408have been removed. Update your code accordingly.
409
410Any APIs that deal with global (or root) coordinates have been
411removed in GTK 4, since not all backends support them. You should
412replace your use of such APIs with surface-relative equivalents.
413Examples of this are `gdk_surface_get_origin()`, `gdk_surface_move()`
414or `gdk_event_get_root_coords()`.
415
416### Adapt to `GdkKeymap` API changes
417
418`GdkKeymap` no longer exists as an independent object.
419
420If you need access to keymap state, it is now exposed as properties
421on the `GdkDevice` representing the keyboard:
422[property@Gdk.Device:direction],
423[property@Gdk.Device:has-bidi-layouts],
424[property@Gdk.Device:caps-lock-state],
425[property@Gdk.Device:num-lock-state],
426[property@Gdk.Device:scroll-lock-state] and
427[property@Gdk.Device:modifier-state]. To obtain the keyboard device,
428you can use
429
430```
431gdk_seat_get_keyboard (gdk_display_get_default_seat (display)
432```
433
434If you need access to translated keys for event handling, `GdkEvent`
435now includes all of the translated key state, including consumed
436modifiers, group and shift level, so there should be no need to
437manually call `gdk_keymap_translate_keyboard_state()` (which has
438been removed).
439
440If you need to do forward or backward mapping between key codes
441and key values, use [method@Gdk.Display.map_keycode] and
442[method@Gdk.Display.map_keyval], which are the replacements for
443`gdk_keymap_get_entries_for_keycode()` and
444`gdk_keymap_get_entries_for_keyval()`.
445
446### Adapt to changes in keyboard modifier handling
447
448GTK 3 has the idea that use of modifiers may differ between different
449platforms, and has a `GdkModifierIntent` api to let platforms provide
450hint about how modifiers are expected to be used. It also promoted
451the use of `<Primary>` instead of `<Control>` to specify accelerators that
452adapt to platform conventions.
453
454In GTK 4, the meaning of modifiers has been fixed, and backends are
455expected to map the platform conventions to the existing modifiers.
456The expected use of modifiers in GTK 4 is:
457
458`GDK_CONTROL_MASK`
459 : Primary accelerators
460
461`GDK_ALT_MASK`
462 :  Mnemonics
463
464`GDK_SHIFT_MASK`
465 : Extending selections
466
467`GDK_CONTROL_MASK`
468 : Modifying selections
469
470`GDK_CONTROL_MASK|GDK_ALT_MASK`
471 : Prevent text input
472
473Consequently, `GdkModifierIntent` and related APIs have been removed,
474and `<Control>` is preferred over `<Primary>` in accelerators.
475
476A related change is that GTK 4 no longer supports the use of archaic
477X11 'real' modifiers with the names Mod1,..., Mod5, and `GDK_MOD1_MASK`
478has been renamed to `GDK_ALT_MASK`.
479
480### Replace `GtkClipboard` with `GdkClipboard`
481
482The `GtkClipboard` API has been removed, and replaced by `GdkClipboard`.
483There is not direct 1:1 mapping between the old an the new API, so it cannot
484be a mechanical replacement; the new API is based on object types and `GValue`
485like object properties, instead of opaque identifiers, so it should be easier
486to use.
487
488For instance, the example below copies the contents of an entry into the
489clipboard:
490
491```c
492static void
493copy_text (GtkWidget *widget)
494{
495  GtkEditable *editable = GTK_EDITABLE (widget);
496
497  // Initialize a GValue with the contents of the widget
498  GValue value = G_VALUE_INIT;
499  g_value_init (&value, G_TYPE_STRING);
500  g_value_set_string (&value, gtk_editable_get_text (editable));
501
502  // Store the value in the clipboard object
503  GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
504  gdk_clipboard_set_value (clipboard, &value);
505
506  g_value_unset (&value);
507}
508```
509
510whereas the example below pastes the contents into the entry:
511
512```c
513static void
514paste_text (GtkWidget *widget)
515{
516  GtkEditable *editable = GTK_EDITABLE (widget);
517
518  // Initialize a GValue to receive text
519  GValue value = G_VALUE_INIT;
520  g_value_init (&value, G_TYPE_STRING);
521
522  // Get the content provider for the clipboard, and ask it for text
523  GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
524  GdkContentProvider *provider = gdk_clipboard_get_content (clipboard);
525
526  // If the content provider does not contain text, we are not interested
527  if (!gdk_content_provider_get_value (provider, &value, NULL))
528    return;
529
530  const char *str = g_value_get_string (&value);
531
532  gtk_editable_set_text (editable, str);
533
534  g_value_unset (&value);
535}
536```
537
538The convenience API for specific target types in `GtkClipboard` has been
539replaced by their corresponding GType:
540
541| GtkClipboard                        | GType                  |
542| ----------------------------------- | ---------------------- |
543| `gtk_clipboard_request_text()`      | `G_TYPE_STRING`        |
544| `gtk_clipboard_request_rich_text()` | `GTK_TYPE_TEXT_BUFFER` |
545| `gtk_clipboard_request_image()`     | `GDK_TYPE_PIXBUF`      |
546| `gtk_clipboard_request_uris()`      |` GDK_TYPE_FILE_LIST`   |
547
548**Note**: Support for rich text serialization across different processes
549for `GtkTextBuffer` is not available any more.
550
551If you are copying the contents of an image, it is recommended to use
552`GDK_TYPE_PAINTABLE` instead of `GDK_TYPE_PIXBUF`, to minimize the amount of
553potential copies.
554
555### Stop using `gtk_get_current_...` APIs
556
557The function `gtk_get_current_event()` and its variants have been
558replaced by equivalent event controller APIs:
559[method@Gtk.EventController.get_current_event], etc.
560
561### Convert your UI files
562
563A number of the changes outlined below affect `.ui` files. The
564`gtk4-builder-tool simplify` command can perform many of the
565necessary changes automatically, when called with the `--3to4`
566option. You should always review the resulting changes.
567
568The `<requires>` tag now supports for the `lib` attribute the
569`gtk` value only, instead of the `gtk+` one previously.
570
571### Adapt to GtkBuilder API changes
572
573`gtk_builder_connect_signals()` no longer exists. Instead, signals are
574always connected automatically. If you need to add user data to your
575signals, [method@Gtk.Builder.set_current_object] must be called. An important
576caveat is that you have to do this before loading any XML. This means if
577you need to use [method@Gtk.Builder.set_current_object], you can no longer use
578[ctor@Gtk.Builder.new_from_file], [ctor@Gtk.Builder.new_from_resource], or
579[ctor@Gtk.Builder.new_from_string]. Instead, you must use vanilla [ctor@Gtk.Builder.new],
580then call [method@Gtk.Builder.set_current_object], then load the XML using
581[method@Gtk.Builder.add_from_file], [method@Gtk.Builder.add_from_resource], or
582[method@Gtk.Builder.add_from_string]. You must check the return value for
583failure and manually abort with `g_error()` if something went wrong.
584
585You only have to worry about this if you were previously using
586`gtk_builder_connect_signals()`. If you are using templates, then
587`gtk_widget_init_template()` will call `gtk_builder_set_current_object()`
588for you, so templates work like before.
589
590### Adapt to event controller API changes
591
592A few changes to the event controller and [class@Gtk.Gesture] APIs
593did not make it back to GTK 3, and have to be taken into account
594when moving to GTK 4. One is that the [signal@Gtk.EventControllerMotion::enter]
595and [signal@Gtk.EventControllerMotion::leave] signals have gained new arguments.
596Another is that `GtkGestureMultiPress` has been renamed to [class@Gtk.GestureClick],
597and has lost its area property. A [class@Gtk.EventControllerFocus] has been
598split off from [class@Gtk.EventControllerKey].
599
600In GTK 3, `GtkEventController:widget` was a construct-only property, so a
601`GtkWidget` was provided whenever constructing a `GtkEventController`. In
602GTK 4, [property@Gtk.EventController:widget] is now read-only. Use
603[method@Gtk.Widget.add_controller] to add an event controller to a widget.
604
605In GTK 3, widgets did not own their event controllers, and event
606controllers did not own their widgets, so developers were responsible
607for manually keeping event controllers alive for the lifetime of their
608associated widgets. In GTK 4, widgets own their event controllers.
609[method@Gtk.Widget.add_controller] takes ownership of the event controller, so
610there is no longer any need to store a reference to the event controller
611after it has been added to a widget.
612
613Although not normally needed, an event controller could be removed from
614a widget in GTK 3 by destroying the event controller with `g_object_unref()`.
615In GTK 4, you must use [method@Gtk.Widget.remove_controller].
616
617### Focus handling changes
618
619The semantics of the [property@Gtk.Widget:can-focus] property have changed.
620In GTK 3, this property only meant that the widget itself would not
621accept keyboard input, but its children still might (in the case of
622containers). In GTK 4, if `:can-focus` is `FALSE`, the focus cannot enter
623the widget or any of its descendents, and the default value has changed
624from `FALSE` to `TRUE`. In addition, there is a [property@Gtk.Widget:focusable]
625property, which controls whether an individual widget can receive
626the input focus.
627
628The `gtk4-builder-tool` utility, when called with the `--3to4` option of the
629`simplify` command, will replace `:can-focus` by `:focusable`.
630
631The feature to automatically keep the focus widget scrolled into view with
632`gtk_container_set_focus_vadjustment()` has been removed together with
633`GtkContainer`, and is provided by scrollable widgets instead. In the common
634case that the scrollable is a [class@Gtk.Viewport], use
635[property@Gtk.Viewport:scroll-to-focus].
636
637### Use the new apis for keyboard shortcuts
638
639The APIs for keyboard shortcuts and accelerators have changed in GTK 4.
640
641Instead of `GtkAccelGroup`, you now use a [class@Gtk.ShortcutController] with global
642scope, and instead of `GtkBindingSet`, you now use [method@Gtk.WidgetClass.add_shortcut],
643[method@Gtk.WidgetClass.add_binding] and its variants. In both cases, you probably
644want to add actions that can be triggered by your shortcuts.
645
646There is no direct replacement for loading and saving accelerators with
647`GtkAccelMap`. But since `GtkShortcutController` implements `GListModel` and
648both [class@Gtk.ShortcutTrigger] and [class@Gtk.ShortcutAction] can be
649serialized to strings, it is relatively easy to implement saving and loading
650yourself.
651
652### Stop using `GtkEventBox`
653
654`GtkEventBox` is no longer needed and has been removed.
655
656All widgets receive all events.
657
658### Stop using `GtkButtonBox`
659
660`GtkButtonBox` has been removed. Use a [class@Gtk.Box] instead.
661
662### Adapt to `GtkBox` API changes
663
664The GtkBox `pack_start()` and `pack_end()` methods have been replaced by
665[method@Gtk.Box.prepend] and [method@Gtk.Box.append]. You can also reorder
666box children as necessary.
667
668### Adapt to `GtkWindow` API changes
669
670Following the `GdkSurface` changes, a number of `GtkWindow` APIs that were
671X11-specific have been removed. This includes `gtk_window_set_geometry_hints()`,
672`gtk_window_set_gravity()`, `gtk_window_move()`, `gtk_window_parse_geometry()`,
673`gtk_window_set_keep_above()`, `gtk_window_set_keep_below()`,
674`gtk_window_begin_resize_drag()`, `gtk_window_begin_move_drag()`.
675Most likely, you should just stop using them. In some cases, you can
676fall back to using the underlying `GdkToplevel` APIs (for example,
677[method@Gdk.Toplevel.begin_resize]).
678
679The APIs for controlling `GtkWindow` size have changed to be better aligned
680with the way size changes are integrated in the frame cycle. `gtk_window_resize()`
681and `gtk_window_get_size()` have been removed. Instead, use
682[method@Gtk.Window.set_default_size] and [method@Gtk.Window.get_default_size].
683
684### Adapt to `GtkHeaderBar` and `GtkActionBar` API changes
685
686The `gtk_header_bar_set_show_close_button()` function has been renamed to
687the more accurate name [method@Gtk.HeaderBar.set_show_title_buttons]. The
688corresponding getter and the property itself have also been renamed.
689The default value of the property is now `TRUE` instead of `FALSE`.
690
691The `gtk_header_bar_set_custom_title()` function has been renamed to
692the more accurate name [method@Gtk.HeaderBar.set_title_widget]. The
693corresponding getter and the property itself have also been renamed.
694
695The `gtk_header_bar_set_title()` function has been removed along with its
696corresponding getter and the property. By default [class@Gtk.HeaderBar]
697shows the title of the window, so if you were setting the title of the
698header bar, consider setting the window title instead. If you need to show a
699title that's different from the window title, use the
700[property@Gtk.HeaderBar:title-widget] property to add a [class@Gtk.Label] as
701shown in the example in the [class@Gtk.HeaderBar] documentation.
702
703The `gtk_header_bar_set_subtitle()` function has been removed along with
704its corresponding getter and the property. The old "subtitle" behavior
705can be replicated by setting the [property@Gtk.HeaderBar:title-widget] property to
706a [class@Gtk.Box] with two labels inside, with the title label matching the
707example in `GtkHeaderBar` documentation, and the subtitle label being
708similar, but with `"subtitle"` style class instead of `"title"`.
709
710The `gtk_header_bar_set_has_subtitle()` function has been removed along with
711its corresponding getter and the property. Its behavior can be replicated by
712setting the [property@Gtk.HeaderBar:title-widget] property to a
713[class@Gtk.Stack] with [property@Gtk.Stack:vhomogeneous] property set to
714`TRUE` and two pages, each with a [class@Gtk.Box] with title and subtitle as
715described above.
716
717Some of the internal structure of `GtkHeaderBar` has been made available as
718public API: [class@Gtk.WindowHandle] and [class@Gtk.WindowControls]. If you
719have unusual needs for custom headerbars, these might be useful to you.
720
721The `:pack-type` child properties of `GtkHeaderBar` and `GtkActionBar` have
722been removed. If you need to programmatically place children, use the
723[method@Gtk.HeaderBar.pack_start] and [method@Gtk.HeaderBar.pack_end] methods.
724In UI files, use the `type` attribute on the `child` element.
725
726The `gtk4-builder-tool` utility can help with this conversion, with the
727`--3to4` option of the `simplify` command.
728
729### Adapt to GtkStack, GtkAssistant and GtkNotebook API changes
730
731The child properties of `GtkStack`, `GtkAssistant` and `GtkNotebook` have been
732converted into child meta objects.
733
734Instead of `gtk_container_child_set (stack, child, …)`, you can now use
735`g_object_set (gtk_stack_get_page (stack, child), …)`. In .ui files, the
736`GtkStackPage` objects must be created explicitly, and take the child widget
737as property. The changes to `GtkNotebook` and `GtkAssistant` are similar.
738
739`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
740of the `simplify` command.
741
742### Adapt to button class hierarchy changes
743
744`GtkCheckButton` is no longer derived from `GtkToggleButton`. Call
745[method@Gtk.CheckButton.set_active] instead of [method@Gtk.ToggleButton.set_active].
746
747`GtkRadioButton` has been removed, and its grouping functionality has
748been added to `GtkCheckButton` and `GtkToggleButton`. Use grouped
749check buttons for traditional radio groups, and used grouped toggle
750buttons for view switchers. The new API to set up groups of buttons
751is [method@Gtk.CheckButton.set_group] and [method@Gtk.ToggleButton.set_group].
752
753`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
754of the `simplify` command.
755
756### Adapt to GtkScrolledWindow API changes
757
758The constructor for `GtkScrolledWindow` no longer takes the adjustments
759as arguments - these were almost always `NULL`.
760
761### Adapt to GtkBin removal
762
763The abstract base class `GtkBin` for single-child containers has been
764removed. The former subclasses are now derived directly from `GtkWidget`,
765and have a "child" property for their child widget. To add a child, use
766the setter for the "child" property (e.g. [method@Gtk.Frame.set_child]) instead
767of `gtk_container_add()`. Adding a child in a ui file with `<child>` still works.
768
769The affected classes are:
770
771- [class@Gtk.AspectFrame]
772- [class@Gtk.Button] (and subclasses)
773- [class@Gtk.ComboBox]
774- [class@Gtk.FlowBoxChild]
775- [class@Gtk.Frame]
776- [class@Gtk.ListBoxRow]
777- [class@Gtk.Overlay]
778- [class@Gtk.Popover]
779- [class@Gtk.Revealer]
780- [class@Gtk.ScrolledWindow]
781- [class@Gtk.SearchBar]
782- [class@Gtk.Viewport]
783- [class@Gtk.Window] (and subclasses)
784
785If you have custom widgets that were derived from `GtkBin`, you should
786port them to derive from `GtkWidget`. Notable vfuncs that you will have
787to implement include the `GObject` dispose vfunc (to unparent your child),
788[vfunc@Gtk.Widget.compute_expand] (if you want your container to propagate
789expand flags) and [vfunc@Gtk.Widget.get_request_mode] (if you want your
790container to support height-for-width).
791
792You may also want to implement the [iface@Gtk.Buildable] interface, to support
793adding children with `<child>` in ui files.
794
795### Adapt to GtkContainer removal
796
797The abstract base class `GtkContainer` for general containers has been
798removed. The former subclasses are now derived directly from `GtkWidget`,
799and have class-specific add() and remove() functions.
800
801The most noticeable change is the use of [method@Gtk.Box.append] or [method@Gtk.Box.prepend]
802instead of `gtk_container_add()` for adding children to `GtkBox`, and the change
803to use container-specific remove functions, such as [method@Gtk.Stack.remove] instead
804of `gtk_container_remove()`. Adding a child in a ui file with `<child>` still works.
805
806The affected classes are:
807
808- [class@Gtk.ActionBar]
809- [class@Gtk.Box] (and subclasses)
810- [class@Gtk.Expander]
811- [class@Gtk.Fixed]
812- [class@Gtk.FlowBox]
813- [class@Gtk.Grid]
814- [class@Gtk.HeaderBar]
815- [class@Gtk.IconView]
816- [class@Gtk.InfoBar]
817- [class@Gtk.ListBox]
818- [class@Gtk.Notebook]
819- [class@Gtk.Paned]
820- [class@Gtk.Stack]
821- [class@Gtk.TextView]
822- [class@Gtk.TreeView]
823
824Without `GtkContainer`, there are no longer facilities for defining and
825using child properties. If you have custom widgets using child properties,
826they will have to be converted either to layout properties provided
827by a layout manager (if they are layout-related), or handled in some
828other way. One possibility is to use child meta objects, as seen with
829[class@Gtk.AssistantPage], [class@Gtk.StackPage] and the like.
830
831If you used to define child properties with `<packing>` in ui files, you have
832to switch to using `<layout>` for the corresponding layout properties.
833`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
834of the `simplify` command.
835
836The replacements for gtk_container_add() are:
837
838| Widget | Replacement |
839| ------ | ----------- |
840| `GtkActionBar`    | [method@Gtk.ActionBar.pack_start], [method@Gtk.ActionBar.pack_end] |
841| `GtkBox`          | [method@Gtk.Box.prepend], [method@Gtk.Box.append] |
842| `GtkExpander`     | [method@Gtk.Expander.set_child] |
843| `GtkFixed`        | [method@Gtk.Fixed.put] |
844| `GtkFlowBox`      | [method@Gtk.FlowBox.insert] |
845| `GtkGrid`         | [method@Gtk.Grid.attach] |
846| `GtkHeaderBar`    | [method@Gtk.HeaderBar.pack_start], [method@Gtk.HeaderBar.pack_end] |
847| `GtkIconView`     | - |
848| `GtkInfoBar`      | [method@Gtk.InfoBar.add_child] |
849| `GtkListBox`      | [method@Gtk.ListBox.insert] |
850| `GtkNotebook`     | [method@Gtk.Notebook.append_page] |
851| `GtkPaned`        | [method@Gtk.Paned.set_start_child], [method@Gtk.Paned.set_end_child] |
852| `GtkStack`        | [method@Gtk.Stack.add_child] |
853| `GtkTextView`     | [method@Gtk.TextView.add_child_at_anchor], [method@Gtk.TextView.add_overlay] |
854| `GtkTreeView`     | - |
855
856### Stop using GtkContainer::border-width
857
858GTK 4 has removed the `GtkContainer::border-width` property (together
859with the rest of `GtkContainer`). Use other means to influence the spacing
860of your containers, such as the CSS margin and padding properties on child
861widgets, or the CSS border-spacing property on containers.
862
863### Adapt to gtk_widget_destroy() removal
864
865The function `gtk_widget_destroy()` has been removed. To explicitly destroy
866a toplevel window, use [method@Gtk.Window.destroy]. To destroy a widget that is
867part of a hierarchy, remove it from its parent using a container-specific
868remove API, such as [method@Gtk.Box.remove] or [method@Gtk.Stack.remove]. To
869destroy a freestanding non-toplevel widget, use `g_object_unref()` to drop your
870reference.
871
872### Adapt to coordinate API changes
873
874A number of APIs that are accepting or returning coordinates have
875been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
876`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
877except for cases where out parameters are involved: you need to
878pass double* now, instead of int*.
879
880### Adapt to GtkStyleContext API changes
881
882The getters in the GtkStyleContext API, such as
883[method@Gtk.StyleContext.get_color], [method@Gtk.StyleContext.get_border],
884or [method@Gtk.StyleContext.get_margin] have lost their state argument,
885and always use the context's current state. Update all callers
886to omit the state argument.
887
888The most commonly used GtkStyleContext API, `gtk_style_context_add_class()`,
889has been moved to GtkWidget as [method@Gtk.Widget.add_css_class], as have the
890corresponding `gtk_style_context_remove_class()` and
891`gtk_style_context_has_class()` APIs.
892
893### Adapt to GtkCssProvider API changes
894
895In GTK 4, the various `GtkCssProvider` load functions have lost their
896`GError` argument. If you want to handle CSS loading errors, use the
897[signal@Gtk.CssProvider::parsing-error] signal instead. gtk_css_provider_get_named()
898has been replaced by [method@Gtk.CssProvider.load_named].
899
900### Stop using GtkShadowType and GtkRelief properties
901
902The shadow-type properties in `GtkScrolledWindow`, `GtkViewport`,
903and `GtkFrame`, as well as the relief properties in `GtkButton`
904and its subclasses have been removed. `GtkScrolledWindow`, `GtkButton`
905and `GtkMenuButton` have instead gained a boolean has-frame property.
906
907### Adapt to GtkWidget's size request changes
908
909GTK 3 used five different virtual functions in GtkWidget to
910implement size requisition, namely the `gtk_widget_get_preferred_width()`
911family of functions. To simplify widget implementations, GTK 4 uses
912only one virtual function, [vfunc@Gtk.Widget.measure], that widgets
913have to implement. [method@Gtk.Widget.measure] replaces the various
914`gtk_widget_get_preferred_` functions for querying sizes.
915
916### Adapt to GtkWidget's size allocation changes
917
918The [vfunc@Gtk.Widget.size_allocate] vfunc takes the baseline as an argument
919now, so you no longer need to call `gtk_widget_get_allocated_baseline()`
920to get it.
921
922The ::size-allocate signal has been removed, since it is easy
923to misuse. If you need to learn about sizing changes of custom
924drawing widgets, use the [signal@Gtk.DrawingArea::resize] or
925[signal@Gtk.GLArea::resize] signals. If you want to track the size
926of toplevel windows, use property notification for
927[property@Gtk.Window:default-width] and [property@Gtk.Window:default-height].
928
929### Switch to GtkWidget's children APIs
930
931In GTK 4, any widget can have children (and `GtkContainer` is gone).
932There is new API to navigate the widget tree, for use in widget
933implementations:
934[method@Gtk.Widget.get_first_child],
935[method@Gtk.Widget.get_last_child],
936[method@Gtk.Widget.get_next_sibling],
937[method@Gtk.Widget.get_prev_sibling].
938
939### Don't use -gtk-gradient in your CSS
940
941GTK now supports standard CSS syntax for both linear and radial
942gradients, just use those.
943
944### Don't use -gtk-icon-effect in your CSS
945
946GTK now supports a more versatile -gtk-icon-filter instead.
947
948Replace
949
950| Old | Replacement |
951| ------ | ----------- |
952| -gtk-icon-effect: dim | -gtk-icon-filter: opacity(0.5) |
953| -gtk-icon-effect: highlight | -gtk-icon-filter: brightness(1.2) |
954
955### Don't use -gtk-icon-theme in your CSS
956
957GTK 4 always uses the current icon theme, with no way to change this.
958
959### Don't use -gtk-outline-...-radius in your CSS
960
961These non-standard properties have been removed from GTK
962CSS. Just use regular border radius.
963
964### Adapt to drawing model changes
965
966This area has seen the most radical changes in the transition from GTK 3
967to GTK 4. Widgets no longer use a draw() function to render their contents
968to a cairo surface. Instead, they have a [vfunc@Gtk.Widget.snapshot] function
969that creates one or more GskRenderNodes to represent their content. Third-party
970widgets that use a draw() function or a `GtkWidget::draw` signal handler for
971custom drawing will need to be converted to use [method@Gtk.Snapshot.append_cairo].
972
973The auxiliary [class@Gtk.Snapshot] object has APIs to help with creating render
974nodes.
975
976If you are using a `GtkDrawingArea` for custom drawing, you need to switch
977to using [method@Gtk.DrawingArea.set_draw_func] to set a draw function instead
978of connecting a handler to the `GtkWidget::draw` signal.
979
980### Stop using APIs to query GdkSurfaces
981
982A number of APIs for querying special-purpose windows have been removed,
983since these windows no longer exist:
984`gtk_tree_view_get_bin_window()`, `gtk_viewport_get_bin_window()`,
985`gtk_viewport_get_view_window()`.
986
987### Widgets are now visible by default
988
989The default value of [property@Gtk.Widget:visible] in GTK 4 is %TRUE, so you no
990longer need to explicitly show all your widgets. On the flip side, you
991need to hide widgets that are not meant to be visible from the start.
992The only widgets that still need to be explicitly shown are toplevel
993windows, dialogs and popovers.
994
995A convenient way to remove unnecessary property assignments like this
996from ui files it run the command `gtk4-builder-tool simplify --replace`
997on them.
998
999The function `gtk_widget_show_all()`, the `GtkWidget:no-show-all` property
1000and its getter and setter have been removed in GTK 4, so you should stop
1001using them.
1002
1003### Adapt to changes in animated hiding and showing of widgets
1004
1005Widgets that appear and disappear with an animation, such as
1006`GtkInfoBar`, `GtkRevealer` no longer use `gtk_widget_show()` and
1007`gtk_widget_hide()` for this, but have gained dedicated APIs for this
1008purpose that you should use instead, such as [method@Gtk.InfoBar.set_revealed].
1009
1010### Stop passing commandline arguments to gtk_init
1011
1012The [func@Gtk.init] and [func@Gtk.init_check] functions no longer accept
1013commandline arguments. Just call them without arguments. Other initialization
1014functions that were purely related to commandline argument handling, such as
1015`gtk_parse_args()` and `gtk_get_option_group()`, are gone.
1016
1017The APIs to initialize GDK separately are also gone, but it is very unlikely
1018that you are affected by that.
1019
1020### GdkPixbuf is deemphasized
1021
1022A number of `GdkPixbuf`-based APIs have been removed. The available replacements
1023are either using `GIcon`, or the newly introduced [class@Gdk.Texture] or
1024[iface@Gdk.Paintable] classes instead. If you are dealing with pixbufs, you can use
1025[ctor@Gdk.Texture.new_for_pixbuf] to convert them to texture objects where needed.
1026
1027### GtkWidget event signals are removed
1028
1029Event controllers and GtkGestures have already been introduced in GTK 3 to handle
1030input for many cases. In GTK 4, the traditional widget signals for handling input,
1031such as `GtkWidget::motion-event` or `GtkWidget::event` have been removed. All event
1032handling is done via event controllers now.
1033
1034### Invalidation handling has changed
1035
1036Only [method@Gtk.Widget.queue_draw] is left to mark a widget as needing redraw.
1037Variations like `gtk_widget_queue_draw_rectangle()` or `gtk_widget_queue_draw_region()`
1038are no longer available.
1039
1040### Stop using GtkWidget::draw
1041
1042The `GtkWidget::draw` signal has been removed. Widgets need to implement the
1043[vfunc@Gtk.Widget.snapshot] function now. Connecting draw signal handlers is
1044no longer possible. If you want to keep using cairo for drawing, use
1045[method@Gtk.Snapshot.append_cairo].
1046
1047### Window content observation has changed
1048
1049Observing widget contents and widget size is now done by using the
1050[class@Gtk.WidgetPaintable] object instead of connecting to widget signals.
1051
1052### Monitor handling has changed
1053
1054Instead of a monitor number, [class@Gdk.Monitor] is now used throughout.
1055[method@Gdk.Display.get_monitors] returns the list of monitors that can be queried
1056or observed for monitors to pass to APIs like [method@Gtk.Window.fullscreen_on_monitor].
1057
1058### Adapt to monitor API changes
1059
1060The `gdk_monitor_get_workarea()` API is gone. Individual backends can still
1061provide this information, for example with [method@GdkX11.Monitor.get_workarea].
1062
1063If you use this information, your code should check which backend is in
1064use and then call the appropriate backend API.
1065
1066### Adapt to cursor API changes
1067
1068Use the new [method@Gtk.Widget.set_cursor] function to set cursors, instead of
1069setting the cursor on the underlying window directly. This is necessary
1070because most widgets don't have their own window anymore, turning any
1071such calls into global cursor changes.
1072
1073For creating standard cursors, `gdk_cursor_new_for_display()` has been removed,
1074you have to use cursor names instead of `GdkCursorType`. For creating custom cursors,
1075use [ctor@Gdk.Cursor.new_from_texture]. The ability to get cursor images has been removed.
1076
1077### Adapt to icon size API changes
1078
1079Instead of the existing extensible set of symbolic icon sizes, GTK now only
1080supports normal and large icons with the [enum@Gtk.IconSize] enumeration. The actual sizes
1081can be defined by themes via the CSS property -gtk-icon-size.
1082
1083GtkImage setters like [method@Gtk.Image.set_from_icon_name] no longer take a `GtkIconSize`
1084argument. You can use the separate [method@Gtk.Image.set_icon_size] setter if you need
1085to override the icon size.
1086
1087The :stock-size property of GtkCellRendererPixbuf has been renamed to
1088[property@Gtk.CellRendererPixbuf:icon-size].
1089
1090### Adapt to changes in the GtkAssistant API
1091
1092The :has-padding property is gone, and `GtkAssistant` no longer adds padding
1093to pages. You can easily do that yourself.
1094
1095### Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton
1096
1097The [iface@Gtk.Editable] interface has been made more useful, and the core functionality of
1098`GtkEntry` has been broken out as a [class@Gtk.Text] widget.
1099[class@Gtk.Entry],
1100[class@Gtk.SearchEntry],
1101[class@Gtk.SpinButton] and the new
1102[class@Gtk.PasswordEntry] now use a [class@Gtk.Text] widget internally
1103and implement [iface@Gtk.Editable]. In particular, this means that it is no longer
1104possible to use `GtkEntry` API such as `gtk_entry_grab_focus_without_selecting()`
1105on a search entry.
1106
1107Use `GtkEditable` API for editable functionality, and widget-specific APIs for
1108things that go beyond the common interface. For password entries, use
1109[class@Gtk.PasswordEntry]. As an example, `gtk_spin_button_set_max_width_chars()`
1110has been removed in favor of [method@Gtk.Editable.set_max_width_chars].
1111
1112### Adapt to changes in GtkOverlay API
1113
1114The GtkOverlay :pass-through child property has been replaced by the
1115[property@Gtk.Widget:can-target] property. Note that they have the opposite sense:
1116pass-through == !can-target.
1117
1118### Use GtkFixed instead of GtkLayout
1119
1120Since `GtkScrolledWindow` can deal with widgets that do not implement
1121the `GtkScrollable` interface by automatically wrapping them into a
1122`GtkViewport`, `GtkLayout` is redundant, and has been removed in favor
1123of the existing [class@Gtk.Fixed] widget.
1124
1125### Adapt to search entry changes
1126
1127The way search entries are connected to global events has changed;
1128`gtk_search_entry_handle_event()` has been dropped and replaced by
1129[method@Gtk.SearchEntry.set_key_capture_widget] and
1130[method@Gtk.EventControllerKey.forward].
1131
1132### Adapt to GtkScale changes
1133
1134The default value of `GtkScale:draw-value` has been changed to %FALSE.
1135If you want your scales to draw values, you will have to set this
1136property explicitly now.
1137
1138`gtk4-builder-tool` can help with this conversion, with the `--3to4` option
1139of the `simplify` command.
1140
1141### Stop using gtk_window_activate_default()
1142
1143The handling of default widgets has been changed, and activating
1144the default now works by calling [method@Gtk.Widget.activate_default]
1145on the widget that caused the activation. If you have a custom widget
1146that wants to override the default handling, you can provide an
1147implementation of the "default.activate" action in your widgets' action
1148groups.
1149
1150### Stop using gtk_widget_grab_default()
1151
1152The function `gtk_widget_grab_default()` has been removed. If you need
1153to mark a widget as default, use [method@Gtk.Window.set_default_widget]
1154directly.
1155
1156### Stop setting ::has-default and ::has-focus in .ui files
1157
1158The special handling for the :has-default and :has-focus properties
1159has been removed. If you want to define the initial focus or the
1160the default widget in a .ui file, set the [property@Gtk.Window:default-widget] or
1161[property@Gtk.Window:focus-widget] properties of the toplevel window.
1162
1163### Stop using the GtkWidget::display-changed signal
1164
1165To track the current display, use the [property@Gtk.Widget:root] property instead.
1166
1167### GtkPopover::modal has been renamed to autohide
1168
1169The modal property has been renamed to [property@Gtk.Popover:autohide].
1170
1171`gtk-builder-tool` can assist with the rename in ui files.
1172
1173### gtk_widget_get_surface has been removed
1174
1175`gtk_widget_get_surface()` has been removed.
1176Use [method@Gtk.Native.get_surface] in combination with
1177[method@Gtk.Widget.get_native] instead.
1178
1179### gtk_widget_is_toplevel has been removed
1180
1181`gtk_widget_is_toplevel()` has been removed.
1182Use `GTK_IS_ROOT`, `GTK_IS_NATIVE` or `GTK_IS_WINDOW`
1183instead, as appropriate.
1184
1185### gtk_widget_get_toplevel has been removed
1186
1187`gtk_widget_get_toplevel()` has been removed.
1188Use [method@Gtk.Widget.get_root] or [method@Gtk.Widget.get_native]
1189instead, as appropriate.
1190
1191### GtkEntryBuffer ::deleted-text has changed
1192
1193To allow signal handlers to access the deleted text before it
1194has been deleted, the [signal@Gtk.EntryBuffer::deleted-text] signal
1195has changed from %G_SIGNAL_RUN_FIRST to %G_SIGNAL_RUN_LAST. The default
1196handler removes the text from the [class@Gtk.EntryBuffer].
1197
1198To adapt existing code, use `g_signal_connect_after()` or
1199%G_CONNECT_AFTER when using `g_signal_connect_data()` or
1200`g_signal_connect_object()`.
1201
1202### GtkMenu, GtkMenuBar and GtkMenuItem are gone
1203
1204These widgets were heavily relying on X11-centric concepts such as
1205override-redirect windows and grabs, and were hard to adjust to other
1206windowing systems.
1207
1208Menus can already be replaced using GtkPopoverMenu in GTK 3. Additionally,
1209GTK 4 introduces GtkPopoverMenuBar to replace menubars. These new widgets
1210can only be constructed from menu models, so the porting effort involves
1211switching to menu models and actions.
1212
1213Tabular menus were rarely used and complicated the menu code,
1214so they have not been brought over to [class@Gtk.PopoverMenu].
1215If you need complex layout in menu-like popups, consider directly using a
1216[class@Gtk.Popover] instead.
1217
1218Since menus are gone, `GtkMenuButton` also lost its ability to show menus,
1219and needs to be used with popovers in GTK 4.
1220
1221### GtkToolbar has been removed
1222
1223Toolbars were using outdated concepts such as requiring special toolitem
1224widgets. Toolbars should be replaced by using a `GtkBox` with regular widgets
1225instead and the "toolbar" style class.
1226
1227### GtkAspectFrame is no longer a frame
1228
1229`GtkAspectFrame` is no longer derived from `GtkFrame` and does not
1230place a label and frame around its child anymore. It still lets
1231you control the aspect ratio of its child.
1232
1233### Stop using custom tooltip windows
1234
1235Tooltips no longer use `GtkWindow`s in GTK 4, and it is no longer
1236possible to provide a custom window for tooltips. Replacing the content
1237of the tooltip with a custom widget is still possible, with
1238[method@Gtk.Tooltip.set_custom].
1239
1240### Switch to the new Drag-and-Drop api
1241
1242The source-side Drag-and-Drop apis in GTK 4 have been changed to use an event
1243controller, [class@Gtk.DragSource]. Instead of calling `gtk_drag_source_set()`
1244and connecting to `GtkWidget` signals, you create a [class@Gtk.DragSource] object,
1245attach it to the widget with [method@Gtk.Widget.add_controller], and connect
1246to `GtkDragSource` signals. Instead of calling `gtk_drag_begin()` on a widget
1247to start a drag manually, call [func@Gdk.Drag.begin].
1248The `::drag-data-get` signal has been replaced by the [signal@Gtk.DragSource::prepare]
1249signal, which returns a [class@Gdk.ContentProvider] for the drag operation.
1250
1251The destination-side Drag-and-Drop API in GTK 4 have also been changed
1252to use an event controller, [class@Gtk.DropTarget]. Instead of calling
1253`gtk_drag_dest_set()` and connecting to `GtkWidget` signals, you create
1254a [class@Gtk.DropTarget] object, attach it to the widget with
1255[method@Gtk.Widget.add_controller], and connect to `GtkDropTarget` signals.
1256The `::drag-motion` signal has been renamed to [signal@Gtk.DropTarget::accept],
1257and instead of `::drag-data-received`, you need to use async read methods on the
1258[class@Gdk.Drop] object, such as [method@Gdk.Drop.read_async] or
1259[method@Gdk.Drop.read_value_async].
1260
1261### Adapt to GtkIconTheme API changes
1262
1263`gtk_icon_theme_lookup_icon()` returns a [class@Gtk.IconPaintable] object now,
1264instead of a `GtkIconInfo`. It always returns a paintable in the requested size,
1265and never fails. A number of no-longer-relevant lookup flags and API variants
1266have been removed.
1267
1268Note that while GTK 4 is moving towards [iface@Gdk.Paintable] as a primary API
1269for paintable content, it is meant to be a 'pure' content producer, therefore
1270a [class@Gtk.IconPaintable] for a symbolic icon will *not* get recolored depending
1271on the context it is rendered it. To properly render a symbolic icon that
1272is provided in the form of a `GtkIconPaintable` (this can be checked with
1273[method@Gtk.IconPaintable.is_symbolic]), you have to call
1274[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`.
1275
1276### Update to GtkFileChooser API changes
1277
1278`GtkFileChooser` moved to a GFile-based API. If you need to convert a path
1279or a URI, use `g_file_new_for_path()`, `g_file_new_for_commandline_arg()`,
1280or `g_file_new_for_uri()`; similarly, if you need to get a path, name or URI
1281from a `GFile`, use `g_file_get_path()`, `g_file_get_basename()` or `g_file_get_uri()`.
1282With the removal or path and URI-based functions, the "local-only" property
1283has been removed; GFile can be used to access non-local as well as local
1284resources.
1285
1286The `GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER` action has been removed. Use
1287%GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, instead. If a new folder is needed,
1288the user can create one.
1289
1290The "confirm-overwrite" signal, and the "do-overwrite-confirmation"
1291property have been removed from `GtkFileChooser`. The file chooser widgets
1292will automatically handle the confirmation of overwriting a file when
1293using `GTK_FILE_CHOOSER_ACTION_SAVE`.
1294
1295`GtkFileChooser` does not support a custom extra widget any more. If you
1296need to add extra widgets, use [method@Gtk.FileChooser.add_choice] instead.
1297
1298`GtkFileChooser` does not support a custom preview widget any more.
1299
1300### Stop using blocking dialog functions
1301
1302`GtkDialog`, `GtkNativeDialog`, and `GtkPrintOperation` removed their
1303blocking API using nested main loops. Nested main loops present
1304re-entrancy issues and other hard to debug issues when coupled
1305with other event sources (IPC, accessibility, network operations)
1306that are not under the toolkit or the application developer's
1307control. Additionally, "stop-the-world" functions do not fit
1308the event-driven programming model of GTK.
1309
1310You can replace calls to `gtk_dialog_run()` by specifying that the
1311`GtkDialog` must be modal using [method@Gtk.Window.set_modal] or the
1312%GTK_DIALOG_MODAL flag, and connecting to the [signal@Gtk.Dialog::response]
1313signal.
1314
1315### Stop using GtkBuildable API
1316
1317All the `GtkBuildable` API was made private, except for the
1318getter function to retrieve the buildable ID. If you are
1319using `gtk_buildable_get_name()` you should replace it with
1320[method@Gtk.Buildable.get_buildable_id].
1321
1322### Adapt to GtkAboutDialog API changes
1323
1324`GtkAboutDialog` now directly derives from `GtkWindow`, the `GtkDialog`
1325API can no longer be used on it.
1326
1327### Adapt to GtkTreeView and GtkIconView tooltip context changes
1328
1329The getter functions for retrieving the data from `GtkTreeView`
1330and `GtkIconView` inside a `GtkWidget::query-tooltip` signal do not take the
1331pointer coordinates as inout arguments any more, but as normal in ones.
1332
1333See: [method@Gtk.TreeView.get_tooltip_context], [method@Gtk.IconView.get_tooltip_context]
1334
1335### Adapt to GtkPopover changes
1336
1337In GTK 3, a `GtkPopover` could be attached to any widget, using the `relative-to`
1338property. This is no longer possible in GTK 4. The parent widget has to be aware
1339of its popover children, and manage their size allocation. Therefore, only widgets
1340with dedicated popover support can have them, such as [class@Gtk.MenuButton] or
1341[class@Gtk.PopoverMenuBar].
1342
1343If you want to make a custom widget that has an attached popover, you need to call
1344[method@Gtk.Popover.present] in your [vfunc@Gtk.Widget.size_allocate] vfunc, in order
1345to update the positioning of the popover.
1346
1347### Stop using GtkFileChooserButton
1348
1349The `GtkFileChooserButton` widget was removed, due to its shortcomings in
1350the user interaction. You can replace it with a simple `GtkButton` that
1351shows a [class@Gtk.FileChooserNative] dialog when clicked; once the file selection
1352has completed, you can update the label of the `GtkButton` with the selected
1353file.
1354
1355### Adapt to changed GtkSettings properties
1356
1357In GTK 3 the [property@Gtk.Settings:gtk-cursor-aspect-ratio] property of
1358`GtkSettings` was a `float`. In GTK 4 this has been changed to a `double`.
1359
1360## Changes to consider after the switch
1361
1362GTK 4 has a number of new features that you may want to take
1363advantage of once the dust has settled over the initial migration.
1364
1365### Consider porting to the new list widgets
1366
1367In GTK 2 and 3, `GtkTreeModel` and `GtkCellRenderer` and widgets using
1368these were the primary way of displaying data and lists. GTK 4 brings
1369a new family of widgets for this purpose that uses list models instead
1370of tree models, and widgets instead of cell renderers.
1371
1372To learn more about the new list widgets, you can read the [List Widget
1373Overview](#ListWidget).
1374
1375