![]() |
![]() |
![]() |
![]() |
This section outlines porting tasks that you need to tackle when you get to the point that you actually build your application against GTK 4. Making it possible to prepare for these in GTK 3 would have been either impossible or impractical.
A number of the changes outlined below affect .ui files. The gtk4-builder-tool simplify command can perform many of the necessary changes automatically, when called with the --3to4 option. You should always review the resulting changes.
The GdkScreen object has been removed in GTK 4. Most of its APIs already had replacements in GTK 3 and were deprecated, a few remaining replacements have been added to GdkDisplay.
The root window is an X11-centric concept that is no longer exposed in the
backend-neutral GDK API. gdk_surface_get_parent()
will return NULL
for toplevel
windows. If you need to interact with the X11 root window, you can use
gdk_x11_display_get_xrootwindow()
to get its XID.
This object is not useful with current GTK drawing APIs and has been removed without replacement.
The GdkDeviceManager object has been removed in GTK 4. Most of its APIs already had replacements in GTK 3 and were deprecated in favor of GdkSeat.
GdkWindow has been renamed to GdkSurface.
The gdk_window_new()
function has been replaced by a number of more
specialized constructors: gdk_surface_new_toplevel()
, gdk_surface_new_popup()
,
gdk_surface_new_temp()
, gdk_wayland_surface_new_subsurface()
.
Use the appropriate ones to create your windows.
Native and foreign subwindows are no longer supported. These concepts were complicating the code and could not be supported across backends.
gdk_window_reparent()
is no longer available.
Direct access to GdkEvent structs is no longer possible in GTK 4. Some frequently-used fields already had accessors in GTK 3, and the remaining fields have gained accessors in GTK 4.
Event compression is now always enabled. If you need to see the uncoalesced
motion history, use gdk_event_get_motion_history()
.
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.
GTK 4 no longer provides the gdk_device_grab()
or gdk_seat_grab()
apis.
If you need to dismiss a popup when the user clicks outside (a common use for grabs), you can use the GdkSurface “autohide” property instead. GtkPopover also has a “autohide” property.
A number of coordinate APIs in GTK 3 had _double variants:
gdk_device_get_position()
, gdk_device_get_surface_at_position()
,
gdk_surface_get_device_position()
. These have been changed to use
doubles, and the _double variants have been removed. Update your
code accordingly.
Any APIs that deal with global (or root) coordinates have been
removed in GTK4, since not all backends support them. You should
replace your use of such APIs with surface-relative equivalents.
Examples of this are gdk_surfae_get_origin()
, gdk_surface_move()
or gdk_event_get_root_coords()
.
The way to get a keymap has changed slightly. gdk_keymap_get_for_display()
has
been renamed to gdk_display_get_keymap()
.
A few changes to the event controller and GtkGesture APIs did not make it back to GTK3, and have to be taken into account when moving to GTK4. One is that the “enter”, “leave”, “focus-in” and “focus-out” signals have gained new arguments. Another is that GtkGestureMultiPress has been renamed to GtkGestureClick.
GtkEventBox is no longer needed and has been removed. All widgets receive all events.
GtkBox no longer has pack-start and -end. Pack your widgets in the correct order, or reorder them as necessary.
The gtk_header_bar_set_show_close_button()
function has been renamed to
the more accurate name gtk_header_bar_set_show_title_buttons()
. The corresponding
getter and the property itself have also been renamed.
The ::pack-type child properties of GtkHeaderBar and GtkActionBar have
been removed. If you need to programmatically place children, use the
pack_start()
and pack_end()
APIs. In ui files, use the type attribute
on the child element.
gtk4-builder-tool can help with this conversion, with the --3to4 option of the simplify command.
The child properties of GtkStack, GtkAssistant and GtkNotebook have been converted into child meta objects. Instead of gtk_container_child_set (stack, child, …), you can now use g_object_set (gtk_stack_get_page (stack, child), …). In .ui files, the GtkStackPage objects must be created explicitly, and take the child widget as property. GtkNotebook and GtkAssistant are similar.
gtk4-builder-tool can help with this conversion, with the --3to4 option of the simplify command.
The getters in the GtkStyleContext API, such as
gtk_style_context_get_property()
, gtk_style_context_get()
,
or gtk_style_context_get_color()
have lost their state argument,
and always use the context's current state. Update all callers
to omit the state argument.
In GTK 4, the various GtkCssProvider load functions have lost their GError argument. If you want to handle CSS loading errors, use the “parsing-error” signal instead.
gtk_css_provider_get_named()
has been replaced by
gtk_css_provider_load_named()
.
GTK 4 has removed the “border-width” property. Use other means to influence the spacing of your containers, such as the CSS margin and padding properties on child widgets.
GTK 3 used five different virtual functions in GtkWidget to
implement size requisition, namely the gtk_widget_get_preferred_width()
family of functions. To simplify widget implementations, GTK 4 uses
only one virtual function, GtkWidgetClass::measure()
that widgets
have to implement.
The “size-allocate” signal now takes the baseline as an
argument, so you no longer need to call gtk_widget_get_allocated_baseline()
to get it.
Instead of the GtkContainer subclass, in GTK 4, any widget can
have children, and there is new API to navigate the widget tree:
gtk_widget_get_first_child()
, gtk_widget_get_last_child()
,
gtk_widget_get_next_sibling()
, gtk_widget_get_prev_sibling()
.
The GtkContainer API still works, but if you are implementing
your own widgets, you should consider using the new APIs.
GTK now supports standard CSS syntax for both linear and radial gradients, just use those.
GTK now supports a more versatile -gtk-icon-filter instead. Replace -gtk-icon-effect: dim; with -gtk-icon-filter: opacity(0.5); and -gtk-icon-effect: hilight; with -gtk-icon-filter: brightness(1.2);.
gtk_widget_measure()
replaces the various gtk_widget_get_preferred_ functions
for querying sizes.
This area has seen the most radical changes in the transition from GTK 3
to GTK 4. Widgets no longer use a draw()
function to render their contents
to a cairo surface. Instead, they have a snapshot()
function that creates
one or more GskRenderNodes to represent their content. Third-party widgets
that use a draw()
function or a “draw” signal handler for custom
drawing will need to be converted to use gtk_snapshot_append_cairo()
.
The auxiliary GtkSnapshot object has APIs to help with creating render nodes.
If you are using a GtkDrawingArea for custom drawing, you need to switch
to using gtk_drawing_area_set_draw_func()
to set a draw function instead
of connnecting a handler to the “draw” signal.
A number of APIs for querying special-purpose windows have been removed,
since these windows are no longer publically available:
gtk_tree_view_get_bin_window()
, gtk_viewport_get_bin_window()
,
gtk_viewport_get_view_window()
.
The default value of “visible” in GTK 4 is TRUE
, so you no
longer need to explicitly show all your widgets. On the flip side, you
need to hide widgets that are not meant to be visible from the start.
A convenient way to remove unnecessary property assignments like this from ui files it run the command gtk4-builder-tool simplify --replace on them.
The function gtk_widget_show_all()
, the “no-show-all” property
and its getter and setter have been removed in GTK 4, so you should stop using them.
Widgets that appear and disappear with an animation, such as GtkPopover,
GtkInfoBar, GtkRevealer no longer use gtk_widget_show()
and gtk_widget_hide()
for this, but have gained dedicated APIs for this purpose that you should
use.
The gtk_init()
and gtk_init_check()
functions no longer accept commandline
arguments. Just call them without arguments. Other initialization functions
that were purely related to commandline argument handling, such as
gtk_parse_args()
and gtk_get_option_group()
, are gone. The APIs to
initialize GDK separately are also gone, but it is very unlikely
that you are affected by that.
A number of GdkPixbuf-based APIs have been removed. The available replacements are either using GIcon, or the newly introduced GdkTexture or GdkPaintable classes instead.
If you are dealing with pixbufs, you can use gdk_texture_new_for_pixbuf()
to convert them to texture objects where needed.
Event controllers and GtkGestures have already been introduced in GTK 3 to handle input for many cases. In GTK 4, the traditional widget signals for handling input, such as “motion-event” or “event” have been removed.
Only gtk_widget_queue_draw()
is left to mark a widget as needing redraw.
Variations like gtk_widget_queue_draw_rectangle()
or gtk_widget_queue_draw_region()
are no longer available.
The “draw” signal has been removed. Widgets need to implement the “snapshot” function now. Connecting draw signal handlers is no longer possible.
Observing widget contents and widget size is now done by using the GtkWidgetPaintable object instead of connecting to widget signals.
Instead of a monitor number, gtk_window_fullscreen_on_monitor()
now takes a
GdkMonitor argument.
Use the new gtk_widget_set_cursor()
function to set cursors, instead of
setting the cursor on the underlying window directly. This is necessary
because most widgets don't have their own window anymore, turning any
such calls into global cursor changes.
For creating standard cursors, gdk_cursor_new_for_display()
has been removed,
you have to use cursor names instead of GdkCursorType. For creating custom cursors,
use gdk_cursor_new_from_texture()
. The ability to get cursor images has been removed.
Instead of the existing extensible set of symbolic icon sizes, GTK now only supports normal and large icons with the GtkIconSize enumeration. The actual sizes can be defined by themes via the CSS property -gtk-icon-size.
GtkImage setters like gtk_image_set_from_icon_name()
no longer take a GtkIconSize
argument. You can use the separate gtk_image_set_icon_size()
setter if you need
to override the icon size.
The ::stock-size property of GtkCellRendererPixbuf has been renamed to “icon-size”.
The simplify command of gtk4-builder-tool has gained a --3to4 option, which can help with some of the required changes in .ui files, such as converting child properties to child meta objects.
The ::has-padding property is gone, and GtkAssistant no longer adds padding to pages. You can easily do that yourself.
The GtkEditable interface has been made more useful, and the core functionality of
GtkEntry has been broken out as a GtkText widget. GtkEntry, GtkSearchEntry,
GtkSpinButton and the new GtkPasswordEntry now use a GtkText widget internally
and implement GtkEditable. In particular, this means that it is no longer
possible to use GtkEntry API such as gtk_entry_grab_focus_without_selecting()
on a search entry.
Use GtkEditable API for editable functionality, and widget-specific APIs for
things that go beyond the common interface. For password entries, use
GtkPasswordEntry. As an example, gtk_spin_button_set_max_width_chars()
has been removed in favor of gtk_editable_set_max_width_chars()
.
The GtkOverlay::pass-through child property has been replaced by the GtkWidget::can-pick property. Note that they have the opposite sense: pass-through == !can-pick.
Since GtkScrolledWindow can deal with widgets that do not implement the GtkScrollable interface by automatically wrapping them into a GtkViewport, GtkLayout is redundant, and has been removed in favor of the existing GtkFixed container widget.
The way search entries are connected to global events has changed;
gtk_search_entry_handle_event()
has been dropped and replaced by
gtk_search_entry_set_key_capture_widget()
and
gtk_event_controller_key_forward()
.
GtkContainer no longer provides facilities for defining and using child properties. If you have custom widgets using child properties, they will have to be converted either to layout properties provided by a layout manager (if they are layout-related), or handled in some other way. One possibility is to use child meta objects, as seen with GtkAssistantPage, GtkStackPage and the like.
Tabular menus were rarely used and complicated the menu code, so they have been removed. If you need complex layout in menu-like popups, consider using a GtkPopover instead.
This function has been removed. Menus should always be attached to a widget and get their display that way.
The handling of default widgets has been changed, and activating
the default now works by calling gtk_widget_activate_default()
on the widget that caused the activation.
If you have a custom widget that wants to override the default handling, you can provide an implementation of the default.activate action in your widgets' action groups.
The special handling for the ::has-default and ::has-focus properties has been removed. If you want to define the initial focus or the the default widget in a .ui file, set the ::default-widget or ::focus-widget properties of the toplevel window.
To track the current display, use the GtkWidget::root property instead.
The modal property has been renamed to autohide. gtk-builder-tool can assist with the rename in ui files.
gtk_widget_get_surface()
has been removed.
Use gtk_native_get_surface()
in combination with
gtk_widget_get_native()
instead.
gtk_widget_is_toplevel()
has been removed.
Use GTK_IS_ROOT, GTK_IS_NATIVE or GTK_IS_WINDOW
instead, as appropriate.
gtk_widget_get_toplevel()
has been removed.
Use gtk_widget_get_root()
or gtk_widget_get_native()
instead, as appropriate.
To allow signal handlers to access the deleted text before it
has been deleted “deleted-text” has changed from
G_SIGNAL_RUN_FIRST
to G_SIGNAL_RUN_LAST
. The default handler
removes the text from the GtkEntryBuffer.
To adapt existing code, use g_signal_connect_after()
or
G_CONNECT_AFTER
when using g_signal_connect_data()
or
g_signal_connect_object()
.
The GDK_SURFACE_STATE_ICONIFIED
value of the
GdkSurfaceState enumeration is now GDK_SURFACE_STATE_MINIMIZED
.
The GdkSurface functions
and gdk_surface_iconify()
have been renamed to
gdk_surface_deiconify()
gdk_surface_minimize()
and gdk_surface_unminimize()
, respectively.
The corresponding GtkWindow functions
and gtk_window_iconify()
have been renamed
to gtk_window_deiconify()
gtk_window_minimize()
and gtk_window_unminimize()
, respectively.
The behavior of the minimization and unminimization operations have not been changed, and they still require support from the underlying windowing system.
These widgets were heavily relying on X11-centric concepts such as override-redirect windows and grabs, and were hard to adjust to other windowing systems.
Menus can already be replaced using GtkPopoverMenu in GTK 3. Additionally, GTK 4 introduces GtkPopoverMenuBar to replace menubars. These new widgets can only be constructed from menu models, so the porting effort involves switching to menu models and actions.
Since menus are gone, GtkMenuButton also lost its ability to show menus, and needs to be used with popovers in GTK 4.
Toolbars were using outdated concepts such as requiring special toolitem widgets.
Toolbars should be replaced by using a GtkBox with regular widgets instead.
Tooltips no longer use GtkWindows in GTK 4, and it is no longer
possible to provide a custom window for tooltips. Replacing the content
of the tooltip with a custom widget is still possible, with
gtk_tooltip_set_custom()
.
The source-side DND apis in GTK 4 have been changed to use an event controller, GtkDragSource.
Instead of calling gtk_drag_source_set()
and connecting to GtkWidget signals, you create
a GtkDragSource object, attach it to the widget with gtk_widget_add_controller()
, and connect
to GtkDragSource signals. Instead of calling gtk_drag_begin()
on a widget to start a drag
manually, call gdk_drag_begin()
.
The ::drag-data-get signal has been replaced by the “prepare” signal, which returns a GdkContentProvider for the drag operation.
The destination-side DND apis in GTK 4 have also been changed to use and event controller, GTkDropTarget.
Instead of calling gtk_drag_dest_set()
and connecting to GtkWidget signals, you create
a GtkDropTarget object, attach it to the widget with gtk_widget_add_controller()
, and
connect to GtkDropTarget signals.
The ::drag-motion signal has been renamed to “accept”, and instead of
::drag-data-received, you need to use async read methods on the GdkDrop object, such
as gdk_drop_read_value_async()
or gdk_drop_read_text_async()
.