Adw – 1: Migrating from Libhandy 1.4 to Libadwaita
Description: Reference for Adw-1: Migrating from Libhandy 1.4 to Libadwaita

# Migrating from Libhandy 1.4 to Libadwaita

Libadwaita is being developed as a successor to Libhandy 1.4. As such, it offers to GTK 4 many features Libhandy was offering to GTK 3.

Migrating from Libhandy 1.4 to Libadwaita implies migrating from GTK 3 to 4. This guide only focuses on on Libhandy and Libadwaita, and is designed to be used together with the GTK 3 to 4 migration guide.

If you notice that some differences between Libhandy and Libadwaita are missing in this guide, please report them.

## Preparation in Libhandy 1.4

The steps outlined in the following sections assume that your software is working with Libhandy 1.4, which is the latest stable release of Libhandy 1.x. It includes all the necessary APIs and tools to help you port your software to Libadwaita. If you are using an older version of Libhandy, you should first get your software to build and work with Libhandy 1.4.

### 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 Libhandy 1.4 also includes an index of all deprecated symbols.

### Subclassing

Following GTK4’s emphasis on composition and delegation over subclassing, `AdwLeaflet` and `AdwHeaderBar` are no longer derivable. As a replacement, you can subclass `GtkBin` or `GtkBox` and include a leaflet or a header bar as a child widget.

### Stop Using `HdyKeypad`

`HdyKeypad` has been removed from Libadwaita. Applications that had used it can copy it in tree instead.

### Stop Using Named WM Colors

The following named colors have been removed from the stylesheet in Libadwaita:

- `wm_title`
- `wm_unfocused_title`
- `wm_highlight`
- `wm_borders_edge`
- `wm_bg_a`
- `wm_bg_b`
- `wm_shadow`
- `wm_border`
- `wm_button_hover_color_a`
- `wm_button_hover_color_b`
- `wm_button_active_color_a`
- `wm_button_active_color_b`
- `wm_button_active_color_c`

Applications should not use them.

### Bundle the Icons You're Using

The preferred way to use icons in applications is to copy them into the application and to bundle them via `GResource`. Referencing system icons won’t work in Libadwaita other than for icons GTK itself ships, so make sure to bundle the icons.

### Use `HdyFlap` Properties for Adding Children Instead of `gtk_container_add()`

`HdyFlap` provides the “content”, “flap” and “separator” properties that can be used for managing children instead of `GtkContainer` API. In Libadwaita `AdwFlap:content`, `AdwFlap:flap` and `AdwFlap:separator` are the only way to manage `AdwFlap` children.

Adding children in a UI file still works.

## Changes that Need to Be Done at the Time of the Switch

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

### Adapt to `GtkContainer` Removal

Same as GTK itself, all widgets that have children have a new API to replace `gtk_container_add()` and `gtk_container_remove()`.

The following widgets that formerly subclassed `GtkBin` have a “child” property now:

- `AdwApplicationWindow`
- `AdwClamp`
- `AdwStatusPage`
- `AdwWindow`

For other widgets use the following replacements:

Widget | `gtk_container_add()` replacement | `gtk_container_remove()` replacement
--- | --- | ---
`AdwActionRow` | adw_action_row_add_suffix() | adw_action_row_remove()
`AdwCarousel` | adw_carousel_append() | adw_carousel_remove()
`AdwExpanderRow` | adw_expander_row_add() | adw_expander_row_remove()
`AdwLeaflet` | adw_leaflet_append() | adw_leaflet_remove()
`AdwPreferencesGroup` | adw_preferences_group_add() | adw_preferences_group_remove()
`AdwPreferencesPage` | adw_preferences_page_add() | adw_preferences_page_remove()
`AdwPreferencesWindow` | adw_preferences_window_add() | adw_preferences_window_remove()

Adding children in a UI file still works.

### Adapt to `HdySearchBar` Removal

`HdySearchBar` has been removed, use `GtkSearchBar` instead.

### Adapt to `HdyWindowHandle` Removal

`HdyWindowHandle` has been removed, use `GtkWindowHandle` instead.

### Adapt to `AdwClamp` API Changes

`HdyClamp` previously had `.small`, `.medium` or `.large` style classes depending on the current size of its child. These style classes are now added to the child instead of the clamp itself.

### Adapt to `AdwComboRow` API Changes

`AdwComboRow` API has been completely overhauled compared to `HdyComboRow` and closely mirrors `GtkDropDown`. Refer to `GtkDropDown`‘s documentation for details.

`hdy_combo_row_bind_name_model()` can be replaced with using the `AdwComboRow:model` property in conjunction with `AdwComboRow:expression`.

`hdy_combo_row_bind_model()` can be replaced with using the `AdwComboRow:model` property in conjunction with `AdwComboRow:factory` and/or `AdwComboRow:list-factory`.

`hdy_combo_row_set_for_enum()` can be replaced with an `AdwEnumListModel` in conjunction with the `AdwComboRow:expression` property, for example:

    expr = gtk_property_expression_new (ADW_TYPE_ENUM_VALUE_OBJECT, NULL, "nick");
    model = G_LIST_MODEL (adw_enum_list_model_new (GTK_TYPE_ORIENTATION));

    adw_combo_row_set_expression (row, expr);
    adw_combo_row_set_model (row, model);

As with `GtkDropDown`, if the model is a `GtkStringList`, the model items can be converted into human-readable strings automatically without requiring an expression.

The `HdyComboRow:selected-index` property has been renamed to `AdwComboRow:selected`, matching `GtkDropDown`.

### Stop Creating `HdyEnumValueObject` Instances

`AdwEnumValueObject` can no longer be manually created and is only intended to be used with `AdwEnumListModel`.

### Adapt to `AdwHeaderBar` API Changes

`AdwHeaderBar` API mostly mirrors `GtkHeaderBar`, refer to the GTK 3 to 4 migration guide for details

The `GtkHeaderBar:show-title-buttons` property has been split into `AdwHeaderBar:show-start-title-buttons` and `AdwHeaderBar:show-end-title-buttons` to simplify creating multi-pane layouts. The corresponding getter and the setter have been split as well.

The `AdwWindowTitle` widget may be useful for replacing the title and subtitle.

### Adapt to `HdyHeaderGroup` Removal

`HdyHeaderGroup` has been removed. Its behavior can be replicated by changing the `AdwHeaderBar:show-start-title-buttons` and `AdwHeaderBar:show-end-title-buttons` properties depending on the layout, for example binding them to the `AdwLeaflet:folded` property as follows:

    <object class="AdwLeaflet" id="leaflet">
      <child>
        <object class="GtkBox">
          <property name="orientation">vertical</property>
          <object class="AdwHeaderBar">
            <binding name="show-end-title-buttons">
              <lookup name="folded">leaflet</lookup>
            </binding>
          </object>
          ...
        </object>
      </child>
      ...
      <child>
        <object class="GtkBox">
           <property name="orientation">vertical</property>
          <object class="AdwHeaderBar">
            <binding name="show-start-title-buttons">
              <lookup name="folded">leaflet</lookup>
            </binding>
          </object>
          ...
        </object>
      </child>
    </object>

### Adapt to `HdyDeck` Removal

`HdyDeck` has been removed. Instead, an `AdwLeaflet` can be used the same way by setting the `AdwLeaflet:can-unfold` property to `FALSE`.

### Adapt to `AdwLeaflet` and `AdwSqueezer` API Changes

The child properties of `HdyLeaflet` and `HdySqueezer` have been converted into page objects, similarly to `GtkStack`. For example, adw_squeezer_page_set_enabled() should be used to replace `hdy_squeezer_set_child_enabled()`.

### Adapt to view switcher API Changes

`AdwViewSwitcher`, `AdwViewSwitcherBar` and `AdwViewSwitcherTitle` now use `AdwViewStack` instead of `GtkStack`.

You should stop using `GtkStack:transition-type` and `GtkStack:transition-duration` properties before switching to `AdwViewStack`.

### Adapt to `AdwAvatar` API Changes

The `HdyAvatar:loadable-icon` property has been removed along with its getter and setter. It can be replaced by `AdwAvatar:custom-image`.

The `hdy_avatar_draw_to_pixbuf_async()` function has been removed, use the regular adw_avatar_draw_to_pixbuf() instead.

### Adapt to Stylesheet Changes

Most widgets don’t have a backdrop state anymore, and the following public colors have been removed:

- `theme_unfocused_fg_color`
- `theme_unfocused_text_color`
- `theme_unfocused_bg_color`
- `theme_unfocused_base_color`
- `theme_unfocused_selected_bg_color`
- `theme_unfocused_selected_fg_color`
- `unfocused_insensitive_color`
- `unfocused_borders`

The `.list-button` style class has been renamed to the more accurate name `.outline`.

The public colors `theme_selected_bg_color` and `theme_selected_fg_color` have been renamed to `accent_bg_color` and `accent_fg_color`.

If you were using `theme_selected_bg_color` as a text color, use `accent_color` instead to make sure the text is readable. You can also use the `.accent` style class to apply the correct color.