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:
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:
- Icon-only buttons;
- Buttons with an icon and a label (using
AdapButtonContent
); - Menu buttons containing an arrow;
AdapSplitButton
;- Any other button with the
.flat
style class.
The following buttons keep default appearance:
- Text-only buttons;
- Buttons with other content;
- Buttons within widgets containing the
.linked
class; - Buttons with the
.suggested-action
,.destructive-action
or.opaque
style classes. - Buttons with the
.raised
style 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.
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.