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_titlewm_unfocused_titlewm_highlightwm_borders_edgewm_bg_awm_bg_bwm_shadowwm_borderwm_button_hover_color_awm_button_hover_color_bwm_button_active_color_awm_button_active_color_bwm_button_active_color_c
Applications should not use them.
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.
Stop Using HdyValueObject with non-string values
HdyValueObject has been removed. While it’s not practical to replace the cases
where it’s storing strings in GTK3, as the preferred replacement only exists in
4, it can also be used with any other GValue. That use has no
replacement and you can instead create your own objects to store those values.
Use HdyStyleManager instead of GtkSettings:gtk-application-prefer-dark-theme
If your application is setting GtkSettings:gtk-application-prefer-dark-theme
to TRUE to request dark appearance, consider setting HdyStyleManager:color-scheme
to HDY_COLOR_SCHEME_PREFER_DARK and making sure the application can work with
light appearance as well. If that’s not possible, set it to
HDY_COLOR_SCHEME_FORCE_DARK instead.
If your application is using light appearance, consider setting the color scheme
to HDY_COLOR_SCHEME_PREFER_LIGHT and support dark appearance.
In libadwaita color schemes will be the only way to request dark appearance.
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:
AdwWindow and AdwApplicationWindow have a “content” property instead.
For other widgets use the following replacements:
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_LIST_ITEM, 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.
Adapt to AdwPreferencesGroup API Changes
HdyPreferencesGroup:use-markup has been removed, the labels always use markup now.
Adapt to HdyEnumValueObject API Changes
HdyEnumValueObject has been renamed to AdwEnumListItem and can no
longer be manually created. It’s only intended to be used with
AdwEnumListModel.
Stop Using HdyValueObject
HdyValueObject has been removed. The typical use for storing strings in
combination with GListStore can be replaced by using
GtkStringList.
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().
The hhomogeneous-folded, vhomogeneous-folded, hhomogeneous-unfolded,
and vhomogeneous-unfolded properties have been replaced by a single
AdwLeaflet:homogeneous property, set to TRUE by default,
applied when the leaflet is folded for the opposite orientation.
When unfolded, children are never homogeneous. Use GtkSizeGroup
to make them homogeneous if needed.
The interpolate-size property has been removed with no replacement, it’s
always enabled when AdwLeaflet:homogeneous is set to FALSE.
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.
The auto view switcher policy has been removed. AdwViewSwitcher only
has narrow and wide policies; if you had used the auto policy, use an
AdwSqueezer with two view switchers inside.
Adapt to AdwViewSwitcher API Changes
The “narrow-ellipsize” property has been removed. Narrow view switchers always ellipsize their labels, wide switchers never do.
Adapt to AdwViewSwitcherBar API Changes
The “policy” property has been removed. If you had used it, use a plain
AdwViewSwitcher in a GtkActionBar instead.
Adapt to AdwViewSwitcherTitle API Changes
The “policy” property has been removed, the behavior is similar to the removed
auto policy. If you had used wide or narrow policies, use an
AdwSqueezer with an AdwViewSwitcher and an
AdwWindowTitle inside, with the switcher having the desired policy.
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() and hdy_avatar_draw_to_pixbuf_async()
functions have been removed, use the newly added
adw_avatar_draw_to_texture() instead. GdkTexture implements
GIcon, so it should just work for that case.
adw_avatar_draw_to_texture() does not have the size parameter. Instead,
it uses the avatar’s current size, with no replacement.
Adapt to AdwStyleManager API Changes
When used with the default style manager, ADW_COLOR_SCHEME_DEFAULT is now
equivalent to ADW_COLOR_SCHEME_PREFER_LIGHT instead of
HDY_COLOR_SCHEME_FORCE_LIGHT, following the system dark style preference by
default. Make sure your application works with it, or otherwise set the
ADW_COLOR_SCHEME_FORCE_LIGHT color scheme manually.
Adapt to Stylesheet Changes
Most widgets don’t have a backdrop state anymore, and the following public colors have been removed:
theme_unfocused_fg_colortheme_unfocused_text_colortheme_unfocused_bg_colortheme_unfocused_base_colortheme_unfocused_selected_bg_colortheme_unfocused_selected_fg_colorunfocused_insensitive_colorunfocused_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.
Adapt to Header Bar, Action Bar and Toolbar Style Changes
When possible, buttons in GtkHeaderBar and GtkActionBar will
use flat appearance by default.
The following rules are used when deciding when to make buttons flat or not:
The following buttons get flat appearance:
- Icon-only buttons;
- Buttons with an icon and a label (using
AdwButtonContent); - Menu buttons containing an arrow;
AdwSplitButton;- Any other button with the
.flatstyle class.
The following buttons keep default appearance:
- Text-only buttons;
- Buttons with other content;
- Buttons within widgets containing the
.linkedstyle class; - Buttons with the
.suggested-actionor.destructive-actionstyle classes. - Buttons with the
.raisedstyle class.
It’s important to avoid ambiguous layouts, for example text-only buttons with no icon, since such a button would be indistinguishable from the window title without hovering it.
In rare cases, the existing layout may need a redesign to work with the new style.
The same rules are also used for the .toolbar style class now, instead of
making every button appear flat.
Adjusting Icon+Arrow Menu Buttons
If you had menu buttons containing an icon and a dropdown arrow, switch to
GtkMenuButton:icon-name and set the
GtkMenuButton:always-show-arrow property to TRUE.
Adjusting Text-only Buttons
If you had text-only buttons, consider using AdwButtonContent. For
example, the following button:
<object class="GtkButton">
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">True</property>
</object>
can be changed into:
<object class="GtkButton">
<property name="child">
<object class="AdwButtonContent">
<property name="icon-name">document-open-symbolic</property>
<property name="label" translatable="yes">_Open</property>
<property name="use-underline">True</property>
</object>
</property>
</object>
One exception are the two primary buttons in a dialog, for example, “Cancel” and “Open”. Those buttons should retain their default appearance.
Adjusting Split Buttons
If you had split buttons implemented via a GtkBox with the .linked style
class and two buttons packed inside, use AdwSplitButton as follows:
<object class="AdwSplitButton">
<property name="menu-model">some_menu</property>
<property name="icon-name">view-list-symbolic</property>
</object>
Adjusting Linked Buttons
For other linked together buttons, simply stop linking them.
If multiple linked groups were used to separate different groups of actions, insert extra spacing as follows:
<object class="GtkSeparator">
<style>
<class name="spacer"/>
</style>
</object>
Custom adjustments
The .flat and .raised style classes can always be used to override the
default appearance.
Important: the GtkButton:has-frame property will not be set to
FALSE when a button gets the flat appearance automatically. It also cannot be
set to TRUE to make a button raised, the style class should be used directly instead.