Migrating from Libhandy 1.4 to Libadapta

Migrating from Libhandy 1.4 to Libadapta

Libadapta 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 Libadapta implies migrating from GTK 3 to 4. This guide only focuses on on Libhandy and Libadapta, and is designed to be used together with the GTK 3 to 4 migration guide.

If you notice that some differences between Libhandy and Libadapta 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 Libadapta. 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, AdapLeaflet and AdapHeaderBar 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 Libadapta. 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 Libadapta:

  • @content_view_bg
  • @text_view_bg
  • @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.

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 Libadapta AdapFlap:content, AdapFlap:flap and AdapFlap:separator are the only way to manage AdapFlap 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 libadapta 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 Libadapta 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:

AdapWindow and AdapApplicationWindow have a content property instead.

For other widgets use the following replacements:

Widget gtk_container_add() replacement gtk_container_remove() replacement
AdapActionRow adap_action_row_add_suffix() adap_action_row_remove()
AdapCarousel adap_carousel_append() adap_carousel_remove()
AdapExpanderRow adap_expander_row_add_row() adap_expander_row_remove()
AdapLeaflet adap_leaflet_append() adap_leaflet_remove()
AdapPreferencesGroup adap_preferences_group_add() adap_preferences_group_remove()
AdapPreferencesPage adap_preferences_page_add() adap_preferences_page_remove()
AdapPreferencesWindow adap_preferences_window_add() adap_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 AdapActionRow and AdapExpanderRow API Changes

The use-underline property and its accessors have been removed. Use AdapPreferencesRow:use-underline and its accessors instead.

The title and subtitle have markup enabled, make sure to escape it with g_markup_escape_text() if this is unwanted.

Adapt to AdapClamp 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 AdapComboRow API Changes

AdapComboRow 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 AdapComboRow:model property in conjunction with AdapComboRow:expression.

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

hdy_combo_row_set_for_enum() can be replaced with an AdapEnumListModel in conjunction with the AdapComboRow:expression property, for example:

expr = gtk_property_expression_new (ADAP_TYPE_ENUM_LIST_ITEM, NULL, "nick");
model = G_LIST_MODEL (adap_enum_list_model_new (GTK_TYPE_ORIENTATION));

adap_combo_row_set_expression (row, expr);
adap_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 AdapComboRow:selected and its type changed from gint to guint, matching GtkDropDown.

Adapt to AdapPreferencesGroup API Changes

HdyPreferencesGroup:use-markup has been removed, the labels always use markup now.

Adapt to HdyEnumValueObject API Changes

HdyEnumValueObject has been renamed to AdapEnumListItem and can no longer be manually created. It’s only intended to be used with AdapEnumListModel.

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 AdapHeaderBar API Changes

AdapHeaderBar 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 AdapHeaderBar:show-start-title-buttons and AdapHeaderBar:show-end-title-buttons to simplify creating multi-pane layouts. The corresponding getter and the setter have been split as well.

The AdapWindowTitle 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 AdapHeaderBar:show-start-title-buttons and AdapHeaderBar:show-end-title-buttons properties depending on the layout, for example binding them to the AdapLeaflet:folded property as follows:

<object class="AdapLeaflet" id="leaflet">
  <child>
    <object class="GtkBox">
      <property name="orientation">vertical</property>
      <object class="AdapHeaderBar">
        <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="AdapHeaderBar">
        <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 AdapLeaflet can be used the same way by setting the AdapLeaflet:can-unfold property to FALSE.

Adapt to AdapLeaflet and AdapSqueezer API Changes

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

The can-swipe-back and can-swipe-forward properties have been renamed to AdapLeaflet:can-navigate-back and AdapLeaflet:can-navigate-forward, along with their accessors. The new properties also handle keyboard and mouse shortcuts in addition to swipes.

The hhomogeneous-folded, vhomogeneous-folded, hhomogeneous-unfolded, and vhomogeneous-unfolded properties have been replaced by a single AdapLeaflet: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 AdapLeaflet:homogeneous is set to FALSE.

AdapLeaflet now uses spring animations instead of timed animations for child transitions. As such, the child-transition-duration property has been replaced with AdapLeaflet:child-transition-params, allowing to customize the animation. Unlike the duration, spring parameters are also used for animation triggered by swipe gestures.

Adapt to AdapFlap API Changes

AdapFlap now uses spring animations instead of timed animations for reveal animations. As such, the reveal-duration property has been replaced with AdapFlap:reveal-params, allowing to customize the animation. Unlike the duration, spring parameters are also used for transitions triggered by swipe gestures.

Adapt to AdapCarousel API changes

AdapCarousel now uses spring animations instead of timed animations for scrolling. As such, the animation-duration property has been replaced with AdapCarousel:scroll-params, allowing to customize the animation. Unlike the duration, spring parameters are also used for animation triggered by swipe gestures.

The adap_carousel_scroll_to_full() method has been removed. Instead, adap_carousel_scroll_to() has got an additional parameter animate.

Adapt to View Switcher API Changes

AdapViewSwitcher, AdapViewSwitcherBar and AdapViewSwitcherTitle now use AdapViewStack instead of GtkStack.

You should stop using GtkStack:transition-type, GtkStack:transition-duration, GtkStack:transition-running and GtkStack:interpolate-size properties before switching to AdapViewStack.

The auto view switcher policy has been removed. AdapViewSwitcher only has narrow and wide policies; if you had used the auto policy, use an AdapSqueezer with two view switchers inside.

Adapt to AdapViewSwitcher API Changes

The narrow-ellipsize property has been removed. Narrow view switchers always ellipsize their labels, wide switchers never do.

Adapt to AdapViewSwitcherBar API Changes

The policy property has been removed. If you had used it, use a plain AdapViewSwitcher in a GtkActionBar instead.

Adapt to AdapViewSwitcherTitle 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 AdapSqueezer with an AdapViewSwitcher and an AdapWindowTitle inside, with the switcher having the desired policy.

Adapt to AdapAvatar API Changes

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

The hdy_avatar_draw_to_pixbuf() and hdy_avatar_draw_to_pixbuf_async() functions have been removed, use the newly added adap_avatar_draw_to_texture() instead. GdkTexture implements GIcon, so it should just work for that case.

adap_avatar_draw_to_texture() does not have the size parameter. Instead, it uses the avatar’s current size, with no replacement.

Adapt to AdapStyleManager API Changes

When used with the default style manager, ADAP_COLOR_SCHEME_DEFAULT is now equivalent to ADAP_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 ADAP_COLOR_SCHEME_FORCE_LIGHT color scheme manually.

Adapt to AdapSwipeTracker API Changes

The AdapSwipeTracker::begin-swipe signal is now emitted immediately before the swipe starts, after the drag threshold has been reached, and it has lost its direction parameter. The new AdapSwipeTracker::prepare signal behaves exactly like begin-swipe did, and can be used instead of it.

The type of the duration parameter in AdapSwipeTracker::end-swipe has changed from gint64 to guint.

Adapt to AdapTabView API Changes

The HdyTabView:shortcut-widget property has been removed with no replacement; AdapTabView automatically installs shortcuts with the GTK_SHORTCUT_SCOPE_MANAGED scope, so they are automatically available throughout the window without the need to set shortcut widget.

If some of these shortcuts conflict with another widget, the latter has priority, and it should work automatically if the widget correctly stops event propagation.

Adapt to AdapPreferencesWindow API Changes

The can-swipe-back property have been renamed to AdapPreferencesWindow:can-navigate-back, along with its accessors. The new properties also handle keyboard and mouse shortcuts in addition to swipes.

Adapt to Miscellaneous Changes

The hdy_ease_out_cubic() function has been removed. Instead, adap_easing_ease() can be used with the ADAP_EASE_OUT_CUBIC parameter.

Adapt to Stylesheet Changes

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.

Stop Using the .sidebar Style Class

The .sidebar style class is now deprecated, although still works for compatibility reasons. The main use case - adjusting the background color of GtkListBox and GtkListView - can now be done with the .navigation-sidebar style class on those widgets instead, along with adjusting the item selection style. The border can be replicated by manually adding a GtkSeparator.

Adapt to the popover.combo Style Removal

The .combo popover style class has been removed. Use .menu instead. You may need to remove manually added margins, padding or minimum height from the list items inside while doing it.

Adapt to the button.list-button Style Removal

The .list-button style class has been removed with no replacement. The regular button style should be used instead.

Adapt to the content-view Style Removal

The .content-view style class has been removed. The selection mode GtkCheckButton style had inside content views has been split out into a separate style class .selection-mode that can be applied directly onto check buttons instead of the view. The unique background color has no replacement and the default background should be used instead.

Adapt to Header Bar, Action Bar, Search Bar and Toolbar Style Changes

When possible, buttons in GtkHeaderBar, GtkActionBar and GtkSearchBar 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:

The following buttons keep default appearance:

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.

Adapt to List Style Changes

For boxed lists we now have the .boxed-list style class that matches the name of the design pattern. If you were using the .content style class, you should use .boxed-list instead.

The .content style class currently remains for compatibility purposes.

Neither the .content style class nor the .boxed-list style class work for GtkListView, as the widget cannot currently be used for the boxed list pattern.

Adjusting Icons

If you’re bundling icons from the icon library with your application, make sure to update them. Many icons have been redrawn to be larger to work better without button frames.

If you’re using the object-select-symbolic icon in a header bar button (typically for selection mode), use selection-mode-symbolic instead.

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 AdapButtonContent. 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="AdapButtonContent">
      <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 AdapSplitButton as follows:

<object class="AdapSplitButton">
  <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.