## Migrating from GTK 3.x to GTK 4

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 number of adjustments that you may have to do when you actually switch your application to build against GTK 4.

## Preparation in GTK 3.x

The steps outlined in the following sections assume that your application is working with GTK 3.24, 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 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.24 series.

### Do not use deprecated symbols

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 index of all deprecated symbols.

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:

            make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"

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.

### Enable diagnostic warnings

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 `G_ENABLE_DIAGNOSTIC` environment variable when running your application, e.g.:

              G_ENABLE_DIAGNOSTIC=1 ./your-app

### Do not use widget style properties

Style properties do not exist in GTK 4. You should stop using them in your custom CSS and in your code.

### Review your window creation flags

GTK 4 removes the GDK_WA_CURSOR flag. Instead, just use `gdk_window_set_cursor()` to set a cursor on the window after creating it. 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_window_set_visual (`gdk_screen_get_rgba_visual()`)` after creating your window. GTK 4 also removes the GDK_WA_WMCLASS flag. If you need this X11-specific functionality, use `XSetClassHint()` directly.

### Stop using direct access to GdkEvent structs

In GTK 4, event structs are opaque and immutable. Many fields already have accessors in GTK 3, and you should use those to reduce the amount of porting work you have to do at the time of the switch.

### Stop using `gdk_pointer_warp()`

Warping the pointer is disorienting and unfriendly to users. GTK 4 does not support it. In special circumstances (such as when implementing remote connection UIs) it can be necessary to warp the pointer; in this case, use platform APIs such as ``XWarpPointer()`` directly.

### Stop using non-RGBA visuals

GTK 4 always uses RGBA visuals for its windows; you should make sure that your code works with such visuals. At the same time, you should stop using GdkVisual APIs, since this object not longer exists in GTK 4. Most of its APIs are deprecated already and not useful when dealing with RGBA visuals.

### Stop using GtkBox padding, fill and expand child properties

GTK 4 removes these GtkBox child properties, so you should stop using them. You can replace GtkBox:padding using the “margin” properties on your GtkBox child widgets.

The fill child property can be replaced by setting appropriate values for the “halign” and “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.

GtkBox also uses the expand child property. It can be replaced by setting “hexpand” or “vexpand” on the child widgets. To match the old behavior of the GtkBox's expand child property, you need to set “hexpand” on the child widgets of a horizontal GtkBox and “vexpand” on the child widgets of a vertical GtkBox.

Note that there's a subtle but important difference between GtkBox's expand and fill child properties and the ones in GtkWidget: setting “hexpand” or “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.

### Stop using the state argument of GtkStyleContext getters

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.

### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_surface()`

These functions are not supported in GTK 4. Instead, either use backend-specific APIs, or render your widgets using `GtkWidgetClass.snapshot()` (once you are using GTK 4).

### Stop using GtkButton's image-related API

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_new_from_icon_name()`.

### Stop using GtkWidget event signals

Event controllers and GtkGestures replace event signals in GTK 4. They have been backported to GTK 3.x so you can prepare for this change.

### Set a proper application ID

In GTK 4 we want the application's GApplication 'application-id' (and therefore the D-Bus name), the desktop file basename and Wayland's xdg-shell app_id to match. In order to achieve this with GTK 3.x call `g_set_prgname()` with the same application ID you passed to GtkApplication. Rename your desktop files to match the application ID if needed.

The call to `g_set_prgname()` can be removed once you fully migrated to GTK 4.

You should be aware that changing the application ID makes your application appear as a new, different app to application installers. You should consult the appstream documentation for best practices around renaming applications.

### Stop using `gtk_main()` and related APIs

GTK 4 removes the gtk_main_ family of APIs. The recommended replacement is GtkApplication, but you can also iterate the GLib mainloop directly, using GMainContext APIs. The replacement for `gtk_events_pending()` is `g_main_context_pending()`, the replacement for `gtk_main_iteration()` is `g_main_context_iteration()`.

### Reduce the use of `gtk_widget_destroy()`

GTK 4 introduces a `gtk_window_destroy()` api. While that is not available in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()` only on toplevel windows, and replace all other uses with `gtk_container_remove()` or `g_object_unref()`.

### Reduce the use of generic container APIs

GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there is not always a replacement for `gtk_container_remove()` in GTK 3, you can replace many uses of `gtk_container_add()` with equivalent container-specific APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce the amount of work you have to do at the time of the switch.