<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
]>
<chapter id="gtk-migrating-3-to-4">
  <title>Migrating from GTK 3.x to GTK 4</title>

  <para>
    GTK 4 is a major new version of GTK that breaks both API and ABI
    compared to GTK 3.x. Thankfully, most of the changes are not hard
    to adapt to and there are a number of steps that you can take to
    prepare your GTK 3.x application for the switch to GTK 4. After
    that, there's a number of adjustments that you may have to do
    when you actually switch your application to build against GTK 4.
  </para>

  <section>
    <title>Preparation in GTK 3.x</title>

    <para>
      The steps outlined in the following sections assume that your
      application is working with GTK 3.24, which is the final stable
      release of GTK 3.x. It includes all the necessary APIs and tools
      to help you port your application to GTK 4. If you are using
      an older version of GTK 3.x, you should first get your application
      to build and work with the latest minor release in the 3.24 series.
    </para>

    <section>
      <title>Do not use deprecated symbols</title>
      <para>
        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 GTK 3 also includes an
        <ulink url="https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html">index</ulink> of all deprecated symbols.
      </para>
      <para>
        To verify that your program does not use any deprecated symbols,
        you can use defines to remove deprecated symbols from the header files,
        as follows:
        <programlisting>
        make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED"
        </programlisting>
      </para>
      <para>
        Note that some parts of our API, such as enumeration values, are
        not well covered by the deprecation warnings. In most cases, using
        them will require you to also use deprecated functions, which will
        trigger warnings.
      </para>
    </section>

    <section>
      <title>Enable diagnostic warnings</title>
      <para>
        Deprecations of properties and signals cannot be caught at compile
        time, as both properties and signals are installed and used after
        types have been instantiated. In order to catch deprecations and
        changes in the run time components, you should use the
        <envar>G_ENABLE_DIAGNOSTIC</envar> environment variable when
        running your application, e.g.:
        <programlisting>
          G_ENABLE_DIAGNOSTIC=1 ./your-app
        </programlisting>
      </para>
    </section>

    <section>
      <title>Do not use widget style properties</title>
      <para>
        Style properties do not exist in GTK 4. You should stop using them in
        your custom CSS and in your code.
      </para>
    </section>

    <section>
      <title>Review your window creation flags</title>
      <para>
        GTK 4 removes the GDK_WA_CURSOR flag. Instead, just use
        <link linkend="gdk-window-set-cursor"><function>gdk_window_set_cursor()</function></link> to set a cursor on the window after
        creating it. GTK 4 also removes the GDK_WA_VISUAL flag, and
        always uses an RGBA visual for windows. To prepare your code
         for this, use
        <literal>gdk_window_set_visual (<link linkend="gdk-screen-get-rgba-visual"><function>gdk_screen_get_rgba_visual()</function></link>)</literal>
        after creating your window.
        GTK 4 also removes the GDK_WA_WMCLASS flag. If you need this
        X11-specific functionality, use <link linkend="XSetClassHint"><function>XSetClassHint()</function></link> directly.
      </para>
    </section>

    <section>
      <title>Stop using direct access to GdkEvent structs</title>
      <para>
        In GTK 4, event structs are opaque and immutable. Many fields already
        have accessors in GTK 3, and you should use those to reduce the amount
        of porting work you have to do at the time of the switch.
      </para>
    </section>

    <section>
      <title>Stop using <link linkend="gdk-pointer-warp"><function>gdk_pointer_warp()</function></link></title>
      <para>
        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
        <function><link linkend="XWarpPointer"><function>XWarpPointer()</function></link></function> directly.
      </para>
    </section>

    <section>
      <title>Stop using non-RGBA visuals</title>
      <para>
        GTK 4 always uses RGBA visuals for its windows; you should make
        sure that your code works with such visuals. At the same time,
        you should stop using GdkVisual APIs, since this object not longer
        exists in GTK 4. Most of its APIs are deprecated already and not
        useful when dealing with RGBA visuals.
      </para>
    </section>

    <section>
      <title>Stop using GtkBox padding, fill and expand child properties</title>
      <para>
        GTK 4 removes these <link linkend="GtkBox"><type>GtkBox</type></link> child properties, so you should stop using
        them. You can replace GtkBox:padding using the <link linkend="GtkWidget--margin"><type>“margin”</type></link> properties
        on your <link linkend="GtkBox"><type>GtkBox</type></link> child widgets.
      </para>
     <para>
        The fill child property can be replaced by setting appropriate values
        for the <link linkend="GtkWidget--halign"><type>“halign”</type></link> and <link linkend="GtkWidget--valign"><type>“valign”</type></link> properties of the child
        widgets. If you previously set the fill child property to <link linkend="TRUE:CAPS"><literal>TRUE</literal></link>, you can
        achieve the same effect by setting the halign or valign properties to
        <link linkend="GTK-ALIGN-FILL:CAPS"><literal>GTK_ALIGN_FILL</literal></link>, depending on the parent box -- halign for a horizontal
        box, valign for a vertical one.
      </para>
      <para>
        <link linkend="GtkBox"><type>GtkBox</type></link> also uses the expand child property. It can be replaced by setting
        <link linkend="GtkWidget--hexpand"><type>“hexpand”</type></link> or <link linkend="GtkWidget--vexpand"><type>“vexpand”</type></link> on the child widgets. To match the
        old behavior of the <link linkend="GtkBox"><type>GtkBox</type></link>'s expand child property, you need to set
        <link linkend="GtkWidget--hexpand"><type>“hexpand”</type></link> on the child widgets of a horizontal <link linkend="GtkBox"><type>GtkBox</type></link> and
        <link linkend="GtkWidget--vexpand"><type>“vexpand”</type></link> on the child widgets of a vertical <link linkend="GtkBox"><type>GtkBox</type></link>.
      </para>
      <para>
        Note that there's a subtle but important difference between <link linkend="GtkBox"><type>GtkBox</type></link>'s
        expand and fill child properties and the ones in <link linkend="GtkWidget"><type>GtkWidget</type></link>: setting
        <link linkend="GtkWidget--hexpand"><type>“hexpand”</type></link> or <link linkend="GtkWidget--vexpand"><type>“vexpand”</type></link> to <link linkend="TRUE:CAPS"><literal>TRUE</literal></link> will propagate up
        the widget hierarchy, so a pixel-perfect port might require you to reset
        the expansion flags to <link linkend="FALSE:CAPS"><literal>FALSE</literal></link> in a parent widget higher up the hierarchy.
      </para>
    </section>

    <section>
      <title>Stop using the state argument of GtkStyleContext getters</title>
      <para>
        The getters in the GtkStyleContext API, such as
        <link linkend="gtk-style-context-get-property"><function>gtk_style_context_get_property()</function></link>, <link linkend="gtk-style-context-get"><function>gtk_style_context_get()</function></link>,
        or <link linkend="gtk-style-context-get-color"><function>gtk_style_context_get_color()</function></link> only accept the context's current
        state for their state argument. You should update all callers to pass
        the current state.
      </para>
    </section>

    <section>
      <title>Stop using <link linkend="gdk-pixbuf-get-from-window"><function>gdk_pixbuf_get_from_window()</function></link> and <link linkend="gdk-cairo-set-source-surface"><function>gdk_cairo_set_source_surface()</function></link></title>
      <para>
        These functions are not supported in GTK 4. Instead, either use
        backend-specific APIs, or render your widgets using
        <link linkend="GtkWidgetClass.snapshot"><function>GtkWidgetClass.snapshot()</function></link> (once you are using GTK 4).
      </para>
    </section>

    <section>
      <title>Stop using GtkButton's image-related API</title>
      <para>
        The functions and properties related to automatically add a GtkImage
        to a GtkButton, and using a GtkSetting to control its visibility, are
        not supported in GTK 4. Instead, you can just pack a GtkImage inside
        a GtkButton, and control its visibility like you would for any other
        widget. If you only want to add a named icon to a GtkButton, you can
        use <link linkend="gtk-button-new-from-icon-name"><function>gtk_button_new_from_icon_name()</function></link>.
      </para>
    </section>

    <section>
      <title>Stop using GtkWidget event signals</title>
      <para>
        Event controllers and <link linkend="GtkGestures"><type>GtkGestures</type></link> replace event signals in GTK 4.
        They have been backported to GTK 3.x so you can prepare for this change.
      </para>
    </section>

    <section>
      <title>Set a proper application ID</title>
      <para>
        In GTK 4 we want the application's <link linkend="GApplication"><type>GApplication</type></link> 'application-id'
        (and therefore the D-Bus name), the desktop file basename and Wayland's
        xdg-shell app_id to match. In order to achieve this with GTK 3.x call
        <link linkend="g-set-prgname"><function>g_set_prgname()</function></link> with the same application ID you passed to <link linkend="GtkApplication"><type>GtkApplication</type></link>.
        Rename your desktop files to match the application ID if needed.
      </para>
      <para>
        The call to <link linkend="g-set-prgname"><function>g_set_prgname()</function></link> can be removed once you fully migrated
        to GTK 4.
      </para>
      <para>
        You should be aware that changing the application ID makes your
        application appear as a new, different app to application installers.
        You should consult the appstream documentation for best practices
        around renaming applications.
      </para>
    </section>

    <section>
      <title>Stop using <link linkend="gtk-main"><function>gtk_main()</function></link> and related APIs</title>

      <para>
        GTK 4 removes the gtk_main_ family of APIs. The recommended replacement
        is GtkApplication, but you can also iterate the GLib mainloop directly,
        using GMainContext APIs. The replacement for <link linkend="gtk-events-pending"><function>gtk_events_pending()</function></link> is
        <link linkend="g-main-context-pending"><function>g_main_context_pending()</function></link>, the replacement for <link linkend="gtk-main-iteration"><function>gtk_main_iteration()</function></link> is
        <link linkend="g-main-context-iteration"><function>g_main_context_iteration()</function></link>.
      </para>
    </section>

    <section>
      <title>Reduce the use of <link linkend="gtk-widget-destroy"><function>gtk_widget_destroy()</function></link></title>
      <para>
        GTK 4 introduces a <link linkend="gtk-window-destroy"><function>gtk_window_destroy()</function></link> api. While that is not available
        in GTK 3, you can prepare for the switch by using <link linkend="gtk-widget-destroy"><function>gtk_widget_destroy()</function></link>
        only on toplevel windows, and replace all other uses with
        <link linkend="gtk-container-remove"><function>gtk_container_remove()</function></link> or <link linkend="g-object-unref"><function>g_object_unref()</function></link>.
      </para>
    </section>

    <section>
      <title>Reduce the use of generic container APIs</title>
      <para>
        GTK 4 removes <link linkend="gtk-container-add"><function>gtk_container_add()</function></link> and <link linkend="gtk-container-remove"><function>gtk_container_remove()</function></link>. While there
        is not always a replacement for <link linkend="gtk-container-remove"><function>gtk_container_remove()</function></link> in GTK 3, you can
        replace many uses of <link linkend="gtk-container-add"><function>gtk_container_add()</function></link> with equivalent container-specific
        APIs such as <link linkend="gtk-box-pack-start"><function>gtk_box_pack_start()</function></link> or <link linkend="gtk-grid-attach"><function>gtk_grid_attach()</function></link>, and thereby reduce
        the amount of work you have to do at the time of the switch.
      </para>
    </section>
  </section>

  <section>
    <title>Changes that need to be done at the time of the switch</title>

    <para>
      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.
    </para>

    <section>
      <title>Stop using GdkScreen</title>
      <para>
        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.
      </para>
    </section>

    <section>
      <title>Stop using the root window</title>
      <para>
        The root window is an X11-centric concept that is no longer exposed in the
        backend-neutral GDK API. If you need to interact with the X11 root window,
        you can use <link linkend="gdk-x11-display-get-xrootwindow"><function>gdk_x11_display_get_xrootwindow()</function></link> to get its XID.
      </para>
    </section>

    <section>
      <title>Stop using GdkVisual</title>
      <para>
        This object is not useful with current GTK drawing APIs and has been removed
        without replacement.
      </para>
    </section>

    <section>
      <title>Stop using GdkDeviceManager</title>
      <para>
        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.
      </para>
    </section>

    <section>
      <title>Adapt to GdkWindow API changes</title>
      <para>
        GdkWindow has been renamed to GdkSurface.
      </para>
      <para>
        In GTK 4, the two roles of a standalone toplevel window and of a popup
        that is placed relative to a parent window have been separated out into
        two interfaces, <link linkend="GdkToplevel"><type>GdkToplevel</type></link> and <link linkend="GdkPopup"><type>GdkPopup</type></link>. Surfaces implementing these
        interfaces are created with <link linkend="gdk-surface-new-toplevel"><function>gdk_surface_new_toplevel()</function></link> and
        <link linkend="gdk-surface-new-popup"><function>gdk_surface_new_popup()</function></link>, respectively, and they are presented on screen
        using <link linkend="gdk-toplevel-present"><function>gdk_toplevel_present()</function></link> and <link linkend="gdk-popup-present"><function>gdk_popup_present()</function></link>. The <link linkend="present"><function>present()</function></link>
        functions take parameters in the form of an auxiliary layout struct,
        <link linkend="GdkPopupLayout"><type>GdkPopupLayout</type></link> or <link linkend="GdkToplevelLayout"><type>GdkToplevelLayout</type></link>. If your code is dealing directly
        with surfaces, you may have to change it to call the API in these
        interfaces, depending on whether the surface you are dealing with
        is a toplevel or a popup.
      </para>
      <para>
        As part of this reorganization, X11-only concepts such as sticky or
        keep-below have been removed. If you need to use them on your X11 windows,
        you will have to set the corresponding X11 properties (as specified in the
        EWMH) yourself. Subsurfaces are only supported with the Wayland backend,
        using <link linkend="gdk-wayland-surface-new-subsurface"><function>gdk_wayland_surface_new_subsurface()</function></link>. Native and foreign subwindows
        are no longer supported. These concepts were complicating the code and
        could not be supported across backends.
      </para>
      <para>
        <link linkend="gdk-window-reparent"><function>gdk_window_reparent()</function></link> is no longer available.
      </para>
      <para>
        A number of minor API cleanups have happened in GdkSurface
        as well. For example, <link linkend="gdk-surface-input-shape-combine-region"><function>gdk_surface_input_shape_combine_region()</function></link>
        has been renamed to <link linkend="gdk-surface-set-input-region"><function>gdk_surface_set_input_region()</function></link>, and
        <link linkend="gdk-surface-begin-resize-drag"><function>gdk_surface_begin_resize_drag()</function></link> has been renamed to
        <link linkend="gdk-toplevel-begin-resize"><function>gdk_toplevel_begin_resize()</function></link>.
      </para>
    </section>

    <section>
      <title>The "iconified" window state has been renamed to "minimized"</title>
      <para>
        The <literal>GDK_SURFACE_STATE_ICONIFIED</literal> value of the
        <link linkend="GdkSurfaceState"><type>GdkSurfaceState</type></link> enumeration is now <link linkend="GDK-SURFACE-STATE-MINIMIZED:CAPS"><literal>GDK_SURFACE_STATE_MINIMIZED</literal></link>.
      </para>
      <para>
        The <link linkend="GdkWindow"><type>GdkWindow</type></link> functions <function><link linkend="gdk-window-iconify"><function>gdk_window_iconify()</function></link></function>
        and <function><link linkend="gdk-window-deiconify"><function>gdk_window_deiconify()</function></link></function> have been renamed to
        <link linkend="gdk-toplevel-minimize"><function>gdk_toplevel_minimize()</function></link> and <link linkend="gdk-toplevel-present"><function>gdk_toplevel_present()</function></link>, respectively.
      </para>
      <para>
        The behavior of the minimization and unminimization operations have
        not been changed, and they still require support from the underlying
        windowing system.
      </para>
    </section>

    <section>
      <title>Adapt to GdkEvent API changes</title>
      <para>
        Direct access to GdkEvent structs is no longer possible in GTK 4.
        GdkEvent is now a strictly read-only type, and you can no longer
        change any of its fields, or construct new events. All event fields
        have accessors that you will have to use.
      </para>
      <para>
        Event compression is always enabled in GTK 4. If you need to see
        the uncoalesced motion history, use <link linkend="gdk-motion-event-get-history"><function>gdk_motion_event_get_history()</function></link>
        on the latest motion event.
      </para>
    </section>

    <section>
      <title>Stop using grabs</title>
      <para>
        GTK 4 no longer provides the <link linkend="gdk-device-grab"><function>gdk_device_grab()</function></link> or <link linkend="gdk-seat-grab"><function>gdk_seat_grab()</function></link>
        apis. If you need to dismiss a popup when the user clicks outside
        (the most common use for grabs), you can use the GdkPopup
        <link linkend="GdkPopup--autohide"><type>“autohide”</type></link> property instead. GtkPopover also has a
        <link linkend="GtkPopover--autohide"><type>“autohide”</type></link> property for this. If you need to prevent
        the user from interacting with a window while a dialog is open,
        use the <link linkend="GtkWindow--modal"><type>“modal”</type></link> property of the dialog.
      </para>
    </section>

    <section>
      <title>Adapt to coordinate API changes</title>
      <para>
        A number of coordinate APIs in GTK 3 had _double variants: 
        <link linkend="gdk-device-get-position"><function>gdk_device_get_position()</function></link>, <link linkend="gdk-device-get-surface-at-position"><function>gdk_device_get_surface_at_position()</function></link>,
        <link linkend="gdk-surface-get-device-position"><function>gdk_surface_get_device_position()</function></link>. These have been changed to use
        doubles, and the _double variants have been removed. Update your
        code accordingly.
      </para>
      <para>
        Any APIs that deal with global (or root) coordinates have been
        removed in GTK 4, since not all backends support them. You should
        replace your use of such APIs with surface-relative equivalents.
        Examples of this are <link linkend="gdk-surface-get-origin"><function>gdk_surface_get_origin()</function></link>, <link linkend="gdk-surface-move"><function>gdk_surface_move()</function></link>
        or <link linkend="gdk-event-get-root-coords"><function>gdk_event_get_root_coords()</function></link>.
      </para>
    </section>

    <section>
      <title>Adapt to GdkKeymap API changes</title>
      <para>
        GdkKeymap no longer exists as an independent object.
      </para>
      <para>
        If you need access to keymap state, it is now exposed as properties
        on the <link linkend="GdkDevice"><type>GdkDevice</type></link> representing the keyboard: <link linkend="GdkDevice--direction"><type>“direction”</type></link>,
        <link linkend="GdkDevice--has-bidi-layouts"><type>“has-bidi-layouts”</type></link>, <link linkend="GdkDevice--caps-lock-state"><type>“caps-lock-state”</type></link>,
        <link linkend="GdkDevice--num-lock-state"><type>“num-lock-state”</type></link>, <link linkend="GdkDevice--scroll-lock-state"><type>“scroll-lock-state”</type></link> and
        <link linkend="GdkDevice--modifier-state"><type>“modifier-state”</type></link>. To obtain the keyboard device, you can use
        <literal>gdk_seat_get_keyboard (gdk_display_get_default_seat (display))</literal>.
      </para>
      <para>
        If you need access to translated keys for event handling, <link linkend="GdkEvent"><type>GdkEvent</type></link>
        now includes all of the translated key state, including consumed
        modifiers, group and shift level, so there should be no need to
        manually call <link linkend="gdk-keymap-translate-keyboard-state"><function>gdk_keymap_translate_keyboard_state()</function></link> (which has
        been removed).
      </para>
      <para>
        If you need to do forward or backward mapping between key codes
        and key values, use <link linkend="gdk-display-map-keycode"><function>gdk_display_map_keycode()</function></link> and <link linkend="gdk-display-map-keyval"><function>gdk_display_map_keyval()</function></link>,
        which are the replacements for <link linkend="gdk-keymap-get-entries-for-keycode"><function>gdk_keymap_get_entries_for_keycode()</function></link>
        and <link linkend="gdk-keymap-get-entries-for-keyval"><function>gdk_keymap_get_entries_for_keyval()</function></link>.
      </para>
    </section>

    <section>
      <title>Adapt to changes in keyboard modifier handling</title>
      <para>
        GTK 3 has the idea that use of modifiers may differ between different
        platforms, and has a <link linkend="GdkModifierIntent"><type>GdkModifierIntent</type></link> api to let platforms provide
        hint about how modifiers are expected to be used. It also promoted
        the use of &lt;Primary&gt; instead of &lt;Control&gt; to specify
        accelerators that adapt to platform conventions.
      </para>
      <para>
        In GTK 4, the meaning of modifiers has been fixed, and backends are
        expected to map the platform conventions to the existing modifiers.
        The expected use of modifiers in GTK 4 is:
        <simplelist>
          <member>GDK_CONTROL_MASK - Primary accelerators</member>
          <member>GDK_ALT_MASK - Mnemonics</member>
          <member>GDK_SHIFT_MASK - Extending selections</member>
          <member>GDK_CONTROL_MASK - Modifying selections</member>
          <member>GDK_CONTROL_MASK|GDK_ALT_MASK - Prevent text input</member>
        </simplelist>
      </para>
      <para>
        Consequently, <link linkend="GdkModifierIntent"><type>GdkModifierIntent</type></link> and related APIs have been removed,
        and &lt;Control&gt; is preferred over &lt;Primary&gt; in accelerators.
      </para>
      <para>
        A related change is that GTK 4 no longer supports the use of archaic
        X11 'real' modifiers with the names Mod1,..., Mod5, and <link linkend="GDK-MOD1-MASK:CAPS"><literal>GDK_MOD1_MASK</literal></link>
        has been renamed to <link linkend="GDK-ALT-MASK:CAPS"><literal>GDK_ALT_MASK</literal></link>.
      </para>
    </section>

    <section>
      <title>Stop using gtk_get_current_... APIs</title>
      <para>
        The function <link linkend="gtk-get-current-event"><function>gtk_get_current_event()</function></link> and its variants have been
        replaced by equivalent event controller APIs:
        <link linkend="gtk-event-controller-get-current-event"><function>gtk_event_controller_get_current_event()</function></link>, etc.
      </para>
    </section>

    <section>
      <title>Convert your ui files</title>

      <para>
        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.
      </para>
    </section>

    <section>
      <title>Adapt to event controller API changes</title>
      <para>
        A few changes to the event controller and <link linkend="GtkGesture"><type>GtkGesture</type></link> APIs
        did not make it back to GTK 3, and have to be taken into account
        when moving to GTK 4. One is that the <link linkend="GtkEventControllerMotion-enter"><type>“enter”</type></link>
        and <link linkend="GtkEventControllerMotion-leave"><type>“leave”</type></link> signals have gained new arguments.
        Another is that <link linkend="GtkGestureMultiPress"><type>GtkGestureMultiPress</type></link> has been renamed to <link linkend="GtkGestureClick"><type>GtkGestureClick</type></link>,
        and has lost its area property. A <link linkend="GtkEventControllerFocus"><type>GtkEventControllerFocus</type></link> has been
        split off from <link linkend="GtkEventcontrollerKey"><type>GtkEventcontrollerKey</type></link>.
      </para>
    </section>

    <section>
      <title>Focus handling changes</title>
      <para>
        The semantics of the <link linkend="GtkWidget--can-focus"><type>“can-focus”</type></link> property have changed.
        In GTK 3, this property only meant that the widget itself would not
        accept keyboard input, but its children still might (in the case of
        containers). In GTK 4, if :can-focus is <link linkend="FALSE:CAPS"><literal>FALSE</literal></link>, the focus cannot enter
        the widget or any of its descendents, and the default value has changed
        from <link linkend="FALSE:CAPS"><literal>FALSE</literal></link> to <link linkend="TRUE:CAPS"><literal>TRUE</literal></link>. In addition, there is a <link linkend="GtkWidget--focusable"><type>“focusable”</type></link>
        property, which controls whether an individual widget can receive
        the input focus.
      </para>
      <para>
        The feature to automatically keep the focus widget scrolled into view
        with <link linkend="gtk-container-set-focus-vadjustment"><function>gtk_container_set_focus_vadjustment()</function></link> has been removed together with
        GtkContainer, and is provided by scrollable widgets instead. In the common
        case that the scrollable is a <link linkend="GtkViewport"><type>GtkViewport</type></link>, use <link linkend="GtkViewport--scroll-to-focus"><type>“scroll-to-focus”</type></link>.
      </para>
    </section>

    <section>
      <title>Stop using GtkEventBox</title>
      <para>
        GtkEventBox is no longer needed and has been removed.
        All widgets receive all events.
      </para>
    </section>

    <section>
      <title>Stop using GtkButtonBox</title>
      <para>
        GtkButtonBox has been removed. Use a GtkBox instead.
      </para>
    </section>

    <section>
      <title>Adapt to GtkBox API changes</title>
      <para>
        The GtkBox pack-start and -end methods have been replaced by <link linkend="gtk-box-prepend"><function>gtk_box_prepend()</function></link>
        and <link linkend="gtk-box-append"><function>gtk_box_append()</function></link>. You can also reorder box children as necessary.
      </para>
    </section>

    <section>
      <title>Adapt to GtkHeaderBar and GtkActionBar API changes</title>
      <para>
        The <link linkend="gtk-header-bar-set-show-close-button"><function>gtk_header_bar_set_show_close_button()</function></link> function has been renamed to
        the more accurate name <link linkend="gtk-header-bar-set-show-title-buttons"><function>gtk_header_bar_set_show_title_buttons()</function></link>. The
        corresponding getter and the property itself have also been renamed.
      </para>
      <para>
        The <link linkend="gtk-header-bar-set-custom-title"><function>gtk_header_bar_set_custom_title()</function></link> function has been renamed to
        the more accurate name <link linkend="gtk-header-bar-set-title-widget"><function>gtk_header_bar_set_title_widget()</function></link>. The
        corresponding getter and the property itself have also been renamed.
      </para>
      <para>
        The <link linkend="gtk-header-bar-set-title"><function>gtk_header_bar_set_title()</function></link> function has been removed along with its
        corresponding getter and the property. By default <link linkend="GtkHeaderBar"><type>GtkHeaderBar</type></link> shows
        the title of the window, so if you were setting the title of the header
        bar, consider setting the window title instead. If you need to show a
        title that's different from the window title, use the
        <link linkend="GtkHeaderBar--title-widget"><type>“title-widget”</type></link> property to add a <link linkend="GtkLabel"><type>GtkLabel</type></link> as shown in the
        example in <link linkend="GtkHeaderBar"><type>GtkHeaderBar</type></link> documentation.
      </para>
      <para>
        The <link linkend="gtk-header-bar-set-subtitle"><function>gtk_header_bar_set_subtitle()</function></link> function has been removed along with
        its corresponding getter and the property. The old "subtitle" behavior
        can be replicated by setting the <link linkend="GtkHeaderBar--title-widget"><type>“title-widget”</type></link> property to
        a <link linkend="GtkBox"><type>GtkBox</type></link> with two labels inside, with the title label matching the
        example in <link linkend="GtkHeaderBar"><type>GtkHeaderBar</type></link> documentation, and the subtitle label being
        similar, but with "subtitle" style class instead of "title".
      </para>
      <para>
        The <link linkend="gtk-header-bar-set-has-subtitle"><function>gtk_header_bar_set_has_subtitle()</function></link> function has been removed along
        with its corresponding getter and the property. Its behavior can be
        replicated by setting the <link linkend="GtkHeaderBar--title-widget"><type>“title-widget”</type></link> property to a
        <link linkend="GtkStack"><type>GtkStack</type></link> with <link linkend="GtkStack--vhomogeneous"><type>“vhomogeneous”</type></link> property set to <link linkend="TRUE:CAPS"><literal>TRUE</literal></link> and two
        pages, each with a <link linkend="GtkBox"><type>GtkBox</type></link> with title and subtitle as described above.
      </para>
      <para>
        The ::pack-type child properties of GtkHeaderBar and GtkActionBar have
        been removed. If you need to programmatically place children, use the
        <link linkend="pack-start"><function>pack_start()</function></link> and <link linkend="pack-end"><function>pack_end()</function></link> APIs. In ui files, use the type attribute
        on the child element.
      </para>
      <para>
        gtk4-builder-tool can help with this conversion, with the --3to4 option
        of the simplify command.
      </para>
    </section>

    <section>
      <title>Adapt to GtkStack, GtkAssistant and GtkNotebook API changes</title>
      <para>
        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.
      </para>
      <para>
        gtk4-builder-tool can help with this conversion, with the --3to4 option
        of the simplify command.
      </para>
    </section>

    <section>
      <title>Adapt to GtkBin removal</title>
      <para>
        The abstract base class GtkBin for single-child containers has been
        removed. The former subclasses are now derived directly from GtkWidget,
        and have a "child" property for their child widget. To add a child, use
        the setter for the "child" property (e.g. <link linkend="gtk-frame-set-child"><function>gtk_frame_set_child()</function></link>) instead
        of <link linkend="gtk-container-add"><function>gtk_container_add()</function></link>. Adding a child in a ui file with
        <tag class="starttag">child</tag> still works.
        The affected classes are:
      </para>
      <simplelist>
        <member>GtkAspectFrame</member>
        <member>GtkButton (and subclasses)</member>
        <member>GtkComboBox</member>
        <member>GtkFlowBoxChild</member>
        <member>GtkFrame</member>
        <member>GtkListBoxRow</member>
        <member>GtkOverlay</member>
        <member>GtkPopover</member>
        <member>GtkRevealer</member>
        <member>GtkScrolledWindow</member>
        <member>GtkSearchBar</member>
        <member>GtkViewport</member>
        <member>GtkWindow (and subclasses)</member>
      </simplelist>
      <para>
        If you have custom widgets that were derived from GtkBin, you should
        port them to derive from GtkWidget. Notable vfuncs that you will have
        to implement include <link linkend="dispose"><function>dispose()</function></link> (to unparent your child), <link linkend="compute-expand"><function>compute_expand()</function></link>
        (if you want your container to propagate expand flags) and
        <link linkend="get-request-mode"><function>get_request_mode()</function></link> (if you want your container to support height-for-width.
      </para>
      <para>
        You may also want to implement the GtkBuildable interface, to support
        adding children with <tag class="starttag">child</tag> in ui files.
      </para>
    </section>

    <section>
      <title>Adapt to GtkContainer removal</title>
      <para>
        The abstract base class GtkContainer for general containers has been
        removed. The former subclasses are now derived directly from GtkWidget,
        and have class-specific <link linkend="add"><function>add()</function></link> and <link linkend="remove"><function>remove()</function></link> functions.
        The most noticable change is the use of <link linkend="gtk-box-append"><function>gtk_box_append()</function></link> or <link linkend="gtk-box-prepend"><function>gtk_box_prepend()</function></link>
        instead of <link linkend="gtk-container-add"><function>gtk_container_add()</function></link> for adding children to GtkBox, and the change
        to use container-specific remove functions, such as <link linkend="gtk-stack-remove"><function>gtk_stack_remove()</function></link> instead
        of <link linkend="gtk-container-remove"><function>gtk_container_remove()</function></link>. Adding a child in a ui file with
        <tag class="starttag">child</tag> still works.
        The affected classes are:
      </para>
      <simplelist>
        <member>GtkActionBar</member>
        <member>GtkBox (and subclasses)</member>
        <member>GtkExpander</member>
        <member>GtkFixed</member>
        <member>GtkFlowBox</member>
        <member>GtkGrid</member>
        <member>GtkHeaderBar</member>
        <member>GtkIconView</member>
        <member>GtkInfoBar</member>
        <member>GtkListBox</member>
        <member>GtkNotebook</member>
        <member>GtkPaned</member>
        <member>GtkStack</member>
        <member>GtkTextView</member>
        <member>GtkTreeView</member>
      </simplelist>
      <para>
        Without GtkContainer, there are no longer 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.
      </para>
    </section>

    <section>
      <title>Stop using GtkContainer::border-width</title>
      <para>
        GTK 4 has removed the <link linkend="GtkContainer-border-width"><type>“border-width”</type></link> property (together
        with the rest of GtkContainer). Use other means to influence the spacing
        of your containers, such as the CSS margin and padding properties on child
        widgets.
      </para>
    </section>

    <section>
      <title>Adapt to <link linkend="gtk-widget-destroy"><function>gtk_widget_destroy()</function></link> removal</title>
      <para>
        The function <link linkend="gtk-widget-destroy"><function>gtk_widget_destroy()</function></link> has been removed. To explicitly destroy
        a toplevel window, use <link linkend="gtk-window-destroy"><function>gtk_window_destroy()</function></link>. To destroy a widget that is
        part of a hierarchy, remove it from its parent using a container-specific
        remove api, such as <link linkend="gtk-box-remove"><function>gtk_box_remove()</function></link> or <link linkend="gtk-stack-remove"><function>gtk_stack_remove()</function></link>. To destroy
        a freestanding non-toplevel widget, use <link linkend="g-object-unref"><function>g_object_unref()</function></link> to drop your
        reference.
      </para>
    </section>

    <section>
      <title>Adapt to GtkStyleContext API changes</title>
      <para>
        The getters in the GtkStyleContext API, such as
        <link linkend="gtk-style-context-get-property"><function>gtk_style_context_get_property()</function></link>, <link linkend="gtk-style-context-get"><function>gtk_style_context_get()</function></link>,
        or <link linkend="gtk-style-context-get-color"><function>gtk_style_context_get_color()</function></link> have lost their state argument,
        and always use the context's current state. Update all callers
        to omit the state argument.
      </para>
      <para>
        The most commonly used GtkStyleContext API, <link linkend="gtk-style-context-add-class"><function>gtk_style_context_add_class()</function></link>,
        has been moved to GtkWidget as <link linkend="gtk-widget-add-css-class"><function>gtk_widget_add_css_class()</function></link>, as have the
        corresponding <link linkend="gtk-style-context-remove-class"><function>gtk_style_context_remove_class()</function></link> and
        <link linkend="gtk-style-context-has-class"><function>gtk_style_context_has_class()</function></link> APIs.
      </para>
    </section>

    <section>
      <title>Adapt to GtkCssProvider API changes</title>
      <para>
        In GTK 4, the various <link linkend="GtkCssProvider"><type>GtkCssProvider</type></link> load functions have lost their
        <link linkend="GError"><type>GError</type></link> argument. If you want to handle CSS loading errors, use the
        <link linkend="GtkCssProvider-parsing-error"><type>“parsing-error”</type></link> signal instead. <link linkend="gtk-css-provider-get-named"><function>gtk_css_provider_get_named()</function></link>
        has been replaced by <link linkend="gtk-css-provider-load-named"><function>gtk_css_provider_load_named()</function></link>.
      </para>
    </section>

    <section>
      <title>Stop using GtkShadowType and GtkRelief properties</title>
      <para>
        The shadow-type properties in GtkScrolledWindow, GtkViewport,
        and GtkFrame, as well as the relief properties in GtkButton
        and its subclasses have been removed. GtkScrolledWindow, GtkButton
        and GtkMenuButton have instead gained a boolean has-frame
        property.
      </para>
    </section>

    <section>
      <title>Adapt to GtkWidget's size request changes</title>
      <para>
        GTK 3 used five different virtual functions in GtkWidget to
        implement size requisition, namely the <link linkend="gtk-widget-get-preferred-width"><function>gtk_widget_get_preferred_width()</function></link>
        family of functions. To simplify widget implementations, GTK 4 uses
        only one virtual function, GtkWidgetClass::<link linkend="measure"><function>measure()</function></link> that widgets
        have to implement. <link linkend="gtk-widget-measure"><function>gtk_widget_measure()</function></link> replaces the various
        gtk_widget_get_preferred_ functions for querying sizes.
      </para>
    </section>

    <section>
      <title>Adapt to GtkWidget's size allocation changes</title>
      <para>
        The <link linkend="GtkWidget.size-allocate"><function>GtkWidget.size_allocate()</function></link> vfunc takes the baseline as an argument
        now, so you no longer need to call <link linkend="gtk-widget-get-allocated-baseline"><function>gtk_widget_get_allocated_baseline()</function></link>
        to get it.
      </para>
      <para>
        The ::size-allocate signal has been removed, since it is easy
        to misuse. If you need to learn about sizing changes of custom
        drawing widgets, use the <link linkend="GtkDrawingArea-resize"><type>“resize”</type></link> or <link linkend="GtkGLArea-resize"><type>“resize”</type></link>
        signals.
      </para>
    </section>

    <section>
      <title>Switch to GtkWidget's children APIs</title>
      <para>
        In GTK 4, any widget can have children (and GtkContainer is gone).
        There is new API to navigate the widget tree, for use in widget
        implementations: <link linkend="gtk-widget-get-first-child"><function>gtk_widget_get_first_child()</function></link>, <link linkend="gtk-widget-get-last-child"><function>gtk_widget_get_last_child()</function></link>,
        <link linkend="gtk-widget-get-next-sibling"><function>gtk_widget_get_next_sibling()</function></link>, <link linkend="gtk-widget-get-prev-sibling"><function>gtk_widget_get_prev_sibling()</function></link>.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-gradient in your CSS</title>
      <para>
        GTK now supports standard CSS syntax for both linear and radial
        gradients, just use those.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-icon-effect in your CSS</title>
      <para>
        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);.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-icon-theme in your CSS</title>
      <para>
        GTK now uses the current icon theme, without a way to change this.
      </para>
    </section>

    <section>
      <title>Don't use -gtk-outline-...-radius in your CSS</title>
      <para>
        These non-standard properties have been removed from GTK
        CSS. Just use regular border radius.
      </para>
    </section>

    <section>
      <title>Adapt to drawing model changes</title>
      <para>
        This area has seen the most radical changes in the transition from GTK 3
        to GTK 4. Widgets no longer use a <link linkend="draw"><function>draw()</function></link> function to render their contents
        to a cairo surface. Instead, they have a <link linkend="snapshot"><function>snapshot()</function></link> function that creates
        one or more GskRenderNodes to represent their content. Third-party widgets
        that use a <link linkend="draw"><function>draw()</function></link> function or a <link linkend="GtkWidget-draw"><type>“draw”</type></link> signal handler for custom
        drawing will need to be converted to use <link linkend="gtk-snapshot-append-cairo"><function>gtk_snapshot_append_cairo()</function></link>.
      </para>
      <para>
        The auxiliary <link linkend="GtkSnapshot"><type>GtkSnapshot</type></link> object has APIs to help with creating render
        nodes.
      </para>
      <para>
        If you are using a <link linkend="GtkDrawingArea"><type>GtkDrawingArea</type></link> for custom drawing, you need to switch
        to using <link linkend="gtk-drawing-area-set-draw-func"><function>gtk_drawing_area_set_draw_func()</function></link> to set a draw function instead
        of connnecting a handler to the <link linkend="GtkWidget-draw"><type>“draw”</type></link> signal.
      </para>
    </section>

    <section>
      <title>Stop using APIs to query GdkSurfaces</title>
      <para>
        A number of APIs for querying special-purpose windows have been removed,
        since these windows are no longer publically available:
        <link linkend="gtk-tree-view-get-bin-window"><function>gtk_tree_view_get_bin_window()</function></link>, <link linkend="gtk-viewport-get-bin-window"><function>gtk_viewport_get_bin_window()</function></link>,
        <link linkend="gtk-viewport-get-view-window"><function>gtk_viewport_get_view_window()</function></link>.
      </para>
    </section>

    <section>
      <title>Widgets are now visible by default</title>
      <para>
        The default value of <link linkend="GtkWidget--visible"><type>“visible”</type></link> in GTK 4 is <link linkend="TRUE:CAPS"><literal>TRUE</literal></link>, 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.
        The only widgets that still need to be explicitly shown are toplevel
        windows, dialogs and popovers.
      </para>
      <para>
        A convenient way to remove unnecessary property assignments like this
        from ui files it run the command <command>gtk4-builder-tool simplify --replace</command>
        on them.
      </para>
      <para>
        The function <link linkend="gtk-widget-show-all"><function>gtk_widget_show_all()</function></link>, the <link linkend="GtkWidget--no-show-all"><type>“no-show-all”</type></link> property
        and its getter and setter have been removed in  GTK 4, so you should stop
        using them.
      </para>
    </section>

    <section>
      <title>Adapt to changes in animated hiding and showing of widgets</title>
      <para>
        Widgets that appear and disappear with an animation, such as GtkPopover,
        GtkInfoBar, GtkRevealer no longer use <link linkend="gtk-widget-show"><function>gtk_widget_show()</function></link> and <link linkend="gtk-widget-hide"><function>gtk_widget_hide()</function></link>
        for this, but have gained dedicated APIs for this purpose that you should
        use.
      </para>
    </section>

    <section>
      <title>Stop passing commandline arguments to gtk_init</title>
      <para>
        The <link linkend="gtk-init"><function>gtk_init()</function></link> and <link linkend="gtk-init-check"><function>gtk_init_check()</function></link> functions no longer accept commandline
        arguments. Just call them without arguments. Other initialization functions
        that were purely related to commandline argument handling, such as
        <link linkend="gtk-parse-args"><function>gtk_parse_args()</function></link> and <link linkend="gtk-get-option-group"><function>gtk_get_option_group()</function></link>, are gone. The APIs to
        initialize GDK separately are also gone, but it is very unlikely
        that you are affected by that.
      </para>
    </section>

    <section>
      <title>GdkPixbuf is deemphasized</title>
      <para>
        A number of <link linkend="GdkPixbuf-based"><type>GdkPixbuf-based</type></link> APIs have been removed. The available replacements
        are either using <link linkend="GIcon"><type>GIcon</type></link>, or the newly introduced <link linkend="GdkTexture"><type>GdkTexture</type></link> or <link linkend="GdkPaintable"><type>GdkPaintable</type></link>
        classes instead. If you are dealing with pixbufs, you can use
        <link linkend="gdk-texture-new-for-pixbuf"><function>gdk_texture_new_for_pixbuf()</function></link> to convert them to texture objects where needed.
      </para>
    </section>

    <section>
      <title>GtkWidget event signals are removed</title>
      <para>
        Event controllers and <link linkend="GtkGestures"><type>GtkGestures</type></link> 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 <link linkend="GtkWidget-motion-event"><type>“motion-event”</type></link> or <link linkend="GtkWidget-event"><type>“event”</type></link> have been removed.
      </para>
    </section>

    <section>
      <title>Invalidation handling has changed</title>
      <para>
        Only <link linkend="gtk-widget-queue-draw"><function>gtk_widget_queue_draw()</function></link> is left to mark a widget as needing redraw.
        Variations like <link linkend="gtk-widget-queue-draw-rectangle"><function>gtk_widget_queue_draw_rectangle()</function></link> or <link linkend="gtk-widget-queue-draw-region"><function>gtk_widget_queue_draw_region()</function></link>
        are no longer available.
      </para>
    </section>

    <section>
      <title>Stop using GtkWidget::draw</title>
      <para>
        The <link linkend="GtkWidget-draw"><type>“draw”</type></link> signal has been removed. Widgets need to implement the
        <link linkend="GtkWidgetClass.snapshot"><function>GtkWidgetClass.snapshot()</function></link> function now. Connecting draw signal handlers is
        no longer possible. If you want to keep using cairo for drawing, use
        <link linkend="gtk-snaphot-append-cairo"><function>gtk_snaphot_append_cairo()</function></link>.
      </para>
    </section>

    <section>
      <title>Window content observation has changed</title>
      <para>
        Observing widget contents and widget size is now done by using the
        <link linkend="GtkWidgetPaintable"><type>GtkWidgetPaintable</type></link> object instead of connecting to widget signals.
      </para>
    </section>

    <section>
      <title>Monitor handling has changed</title>
      <para>
        Instead of a monitor number, <link linkend="GdkMonitor"><type>GdkMonitor</type></link> is now used throughout. 
        <link linkend="gdk-display-get-monitors"><function>gdk_display_get_monitors()</function></link> returns the list of monitors that can be queried
        or observed for monitors to pass to APIs like <link linkend="gtk-window-fullscreen-on-monitor"><function>gtk_window_fullscreen_on_monitor()</function></link>.
      </para>
    </section>

    <section>
      <title>Adapt to cursor API changes</title>
      <para>
        Use the new <link linkend="gtk-widget-set-cursor"><function>gtk_widget_set_cursor()</function></link> 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.
      </para>
      <para>
        For creating standard cursors, <link linkend="gdk-cursor-new-for-display"><function>gdk_cursor_new_for_display()</function></link> has been removed,
        you have to use cursor names instead of GdkCursorType. For creating custom cursors,
        use <link linkend="gdk-cursor-new-from-texture"><function>gdk_cursor_new_from_texture()</function></link>. The ability to get cursor images has been removed.
      </para>
    </section>

    <section>
      <title>Adapt to icon size API changes</title>
      <para>
        Instead of the existing extensible set of symbolic icon sizes, GTK now only
        supports normal and large icons with the <link linkend="GtkIconSize"><type>GtkIconSize</type></link> enumeration. The actual sizes
        can be defined by themes via the CSS property -gtk-icon-size.
      </para>
      <para>
        GtkImage setters like <link linkend="gtk-image-set-from-icon-name"><function>gtk_image_set_from_icon_name()</function></link> no longer take a <link linkend="GtkIconSize"><type>GtkIconSize</type></link>
        argument. You can use the separate <link linkend="gtk-image-set-icon-size"><function>gtk_image_set_icon_size()</function></link> setter if you need
        to override the icon size.
      </para>
      <para>
        The :stock-size property of GtkCellRendererPixbuf has been renamed to
        <link linkend="GtkCellRendererPixbuf--icon-size"><type>“icon-size”</type></link>.
      </para>
    </section>

    <section>
      <title>Adapt to changes in the GtkAssistant API</title>
      <para>
        The :has-padding property is gone, and GtkAssistant no longer adds padding
        to pages. You can easily do that yourself.
      </para>
    </section>

    <section>
      <title>Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton</title>
      <para>
        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 <link linkend="gtk-entry-grab-focus-without-selecting"><function>gtk_entry_grab_focus_without_selecting()</function></link>
        on a search entry.
      </para>
      <para>
        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, <link linkend="gtk-spin-button-set-max-width-chars"><function>gtk_spin_button_set_max_width_chars()</function></link>
        has been removed in favor of <link linkend="gtk-editable-set-max-width-chars"><function>gtk_editable_set_max_width_chars()</function></link>.
      </para>
    </section>

    <section>
      <title>Adapt to changes in GtkOverlay API</title>
      <para>
        The GtkOverlay :pass-through child property has been replaced by the
        <link linkend="GtkWidget--can-target"><type>“can-target”</type></link> property. Note that they have the opposite sense:
        pass-through == !can-target.
      </para>
    </section>

    <section>
      <title>Use GtkFixed instead of GtkLayout</title>
      <para>
        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.
      </para>
    </section>

    <section>
      <title>Adapt to search entry changes</title>
      <para>
        The way search entries are connected to global events has changed;
        <link linkend="gtk-search-entry-handle-event"><function>gtk_search_entry_handle_event()</function></link> has been dropped and replaced by
        <link linkend="gtk-search-entry-set-key-capture-widget"><function>gtk_search_entry_set_key_capture_widget()</function></link> and
        <link linkend="gtk-event-controller-key-forward"><function>gtk_event_controller_key_forward()</function></link>.
      </para>
    </section>

    <section>
      <title>Stop using <link linkend="gtk-window-activate-default"><function>gtk_window_activate_default()</function></link></title>
      <para>
        The handling of default widgets has been changed, and activating
        the default now works by calling <link linkend="gtk-widget-activate-default"><function>gtk_widget_activate_default()</function></link>
        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.
      </para>
    </section>

    <section>
      <title>Stop setting ::has-default and ::has-focus in .ui files</title>
      <para>
        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.
      </para>
    </section>

    <section>
      <title>Stop using the GtkWidget::display-changed signal</title>
      <para>
        To track the current display, use the <link linkend="GtkWidget-root"><type>“root”</type></link> property
        instead.
      </para>
    </section>

    <section>
      <title>GtkPopover::modal has been renamed to autohide</title>
      <para>
        The modal property has been renamed to autohide.
        gtk-builder-tool can assist with the rename in ui files.
      </para>
    </section>

    <section>
      <title>gtk_widget_get_surface has been removed</title>
      <para>
        <link linkend="gtk-widget-get-surface"><function>gtk_widget_get_surface()</function></link> has been removed.
        Use <link linkend="gtk-native-get-surface"><function>gtk_native_get_surface()</function></link> in combination with
        <link linkend="gtk-widget-get-native"><function>gtk_widget_get_native()</function></link> instead.
      </para>
    </section>

    <section>
      <title>gtk_widget_is_toplevel has been removed</title>
      <para>
        <link linkend="gtk-widget-is-toplevel"><function>gtk_widget_is_toplevel()</function></link> has been removed.
        Use GTK_IS_ROOT, GTK_IS_NATIVE or GTK_IS_WINDOW
        instead, as appropriate.
      </para>
    </section>

    <section>
      <title>gtk_widget_get_toplevel has been removed</title>
      <para>
        <link linkend="gtk-widget-get-toplevel"><function>gtk_widget_get_toplevel()</function></link> has been removed.
        Use <link linkend="gtk-widget-get-root"><function>gtk_widget_get_root()</function></link> or <link linkend="gtk-widget-get-native"><function>gtk_widget_get_native()</function></link>
        instead, as appropriate.
      </para>
    </section>

    <section>
      <title>GtkEntryBuffer ::deleted-text has changed</title>
      <para>
        To allow signal handlers to access the deleted text before it
        has been deleted <link linkend="GtkEntryBuffer-deleted-text"><type>“deleted-text”</type></link> has changed from
        <link linkend="G-SIGNAL-RUN-FIRST:CAPS"><literal>G_SIGNAL_RUN_FIRST</literal></link> to <link linkend="G-SIGNAL-RUN-LAST:CAPS"><literal>G_SIGNAL_RUN_LAST</literal></link>. The default handler
        removes the text from the <link linkend="GtkEntryBuffer"><type>GtkEntryBuffer</type></link>.
      </para>
      <para>
        To adapt existing code, use <link linkend="g-signal-connect-after"><function>g_signal_connect_after()</function></link> or
        <link linkend="G-CONNECT-AFTER:CAPS"><literal>G_CONNECT_AFTER</literal></link> when using <link linkend="g-signal-connect-data"><function>g_signal_connect_data()</function></link> or
        <link linkend="g-signal-connect-object"><function>g_signal_connect_object()</function></link>.
      </para>
    </section>

    <section>
      <title>GtkMenu, GtkMenuBar and GtkMenuItem are gone</title>
      <para>
        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.
      </para>
      <para>
        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.
      </para>
      <para>
        Tabular menus were rarely used and complicated the menu code,
        so they have not been brought over to <link linkend="GtkPopoverMenu"><type>GtkPopoverMenu</type></link>. If you need
        complex layout in menu-like popups, consider directly using a
        <link linkend="GtkPopover"><type>GtkPopover</type></link> instead.
      </para>
      <para>
        Since menus are gone, GtkMenuButton also lost its ability to show menus,
        and needs to be used with popovers in GTK 4.
      </para>
    </section>

    <section>
      <title>GtkToolbar has been removed</title>
      <para>
        Toolbars were using outdated concepts such as requiring special toolitem
        widgets. Toolbars should be replaced by using a GtkBox with regular widgets
        instead and the "toolbar" style class.
      </para>
    </section>

    <section>
      <title>GtkAspectFrame is no longer a frame</title>
      <para>
        GtkAspectFrame is no longer derived from GtkFrame and does not
        place a label and frame around its child anymore. It still lets
        you control the aspect ratio of its child.
      </para>
    </section>

    <section>
      <title>Stop using custom tooltip windows</title>
      <para>
        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
        <link linkend="gtk-tooltip-set-custom"><function>gtk_tooltip_set_custom()</function></link>.
      </para>
    </section>

    <section>
      <title>Switch to the new Drag-and-Drop api</title>
      <para>
        The source-side Drag-and-Drop apis in GTK 4 have been changed to use an event
        controller, <link linkend="GtkDragSource"><type>GtkDragSource</type></link>. Instead of calling <link linkend="gtk-drag-source-set"><function>gtk_drag_source_set()</function></link>
        and connecting to <link linkend="GtkWidget"><type>GtkWidget</type></link> signals, you create a <link linkend="GtkDragSource"><type>GtkDragSource</type></link> object,
        attach it to the widget with <link linkend="gtk-widget-add-controller"><function>gtk_widget_add_controller()</function></link>, and connect
        to <link linkend="GtkDragSource"><type>GtkDragSource</type></link> signals. Instead of calling <link linkend="gtk-drag-begin"><function>gtk_drag_begin()</function></link> on a widget
        to start a drag manually, call <link linkend="gdk-drag-begin"><function>gdk_drag_begin()</function></link>.
        The ::drag-data-get signal has been replaced by the <link linkend="GtkDragSource-prepare"><type>“prepare”</type></link>
        signal, which returns a <link linkend="GdkContentProvider"><type>GdkContentProvider</type></link> for the drag operation.
      </para>
      <para>
        The destination-side Drag-and-Drop  apis in GTK 4 have also been changed
        to use an event controller, <link linkend="GtkDropTarget"><type>GtkDropTarget</type></link>. Instead of calling
        <link linkend="gtk-drag-dest-set"><function>gtk_drag_dest_set()</function></link> and connecting to <link linkend="GtkWidget"><type>GtkWidget</type></link> signals, you create
        a <link linkend="GtkDropTarget"><type>GtkDropTarget</type></link> object, attach it to the widget with
        <link linkend="gtk-widget-add-controller"><function>gtk_widget_add_controller()</function></link>, and connect to <link linkend="GtkDropTarget"><type>GtkDropTarget</type></link> signals.
        The ::drag-motion signal has been renamed to <link linkend="GtkDropTarget-accept"><type>“accept”</type></link>, and
        instead of ::drag-data-received, you need to use async read methods on the
        <link linkend="GdkDrop"><type>GdkDrop</type></link> object, such as <link linkend="gdk-drop-read-async"><function>gdk_drop_read_async()</function></link> or <link linkend="gdk-drop-read-value-async"><function>gdk_drop_read_value_async()</function></link>.
      </para>
    </section>

    <section>
      <title>Adapt to GtkIconTheme API changes</title>
      <para>
        <link linkend="gtk-icon-theme-lookup-icon"><function>gtk_icon_theme_lookup_icon()</function></link> returns a <link linkend="GtkIconPaintable"><type>GtkIconPaintable</type></link> object now, instead
        of a <link linkend="GtkIconInfo"><type>GtkIconInfo</type></link>. It always returns a paintable in the requested size, and
        never fails. A number of no-longer-relevant lookup flags and API variants
        have been removed.
      </para>
    </section>

    <section>
      <title>Update to GtkFileChooser API changes</title>
      <para>
        GtkFileChooser moved to a GFile-based API. If you need to convert a
        path or a URI, use <link linkend="g-file-new-for-path"><function>g_file_new_for_path()</function></link>, <link linkend="g-file-new-for-commandline-arg"><function>g_file_new_for_commandline_arg()</function></link>,
        or <link linkend="g-file-new-for-uri"><function>g_file_new_for_uri()</function></link>; similarly, if you need to get a path or a URI
        from a GFile, use <link linkend="g-file-get-path"><function>g_file_get_path()</function></link>, or <link linkend="g-file-get-uri"><function>g_file_get_uri()</function></link>. With the
        removal or path and URI-based functions, the "local-only" property has
        been removed; GFile can be used to access non-local as well as local
        resources.
      </para>
      <para>
        The GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER action has been removed. Use
        <link linkend="GTK-FILE-CHOOSER-ACTION-SELECT-FOLDER:CAPS"><literal>GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</literal></link>, instead. If a new folder is needed,
        the user can create one.
      </para>
      <para>
        The "confirm-overwrite" signal, and the "do-overwrite-confirmation"
        property have been removed from GtkFileChooser. The file chooser widgets
        will automatically handle the confirmation of overwriting a file when
        using GTK_FILE_CHOOSER_ACTION_SAVE.
      </para>
      <para>
        GtkFileChooser does not support a custom extra widget any more. If you
        need to add extra widgets, use <link linkend="gtk-file-chooser-add-choice"><function>gtk_file_chooser_add_choice()</function></link> instead.
      </para>
      <para>
        GtkFileChooser does not support a custom preview widget any more. If
        you need to show a custom preview, you can create your own GtkDialog
        with a GtkFileChooserWidget and your own preview widget that you
        update whenever the <link linkend="GtkFileChooser-selection-changed"><type>“selection-changed”</type></link> signal is
        emitted.
      </para>
    </section>

    <section>
      <title>Stop using blocking dialog functions</title>
      <para>
        GtkDialog, GtkNativeDialog, and GtkPrintOperation removed their
        blocking API using nested main loops. Nested main loops present
        re-entrancy issues and other hard to debug issues when coupled
        with other event sources (IPC, accessibility, network operations)
        that are not under the toolkit or the application developer's
        control. Additionally, "stop-the-world" functions do not fit
        the event-driven programming model of GTK.
      </para>
      <para>
        You can replace calls to <function><link linkend="gtk-dialog-run"><function>gtk_dialog_run()</function></link></function>
        by specifying that the <link linkend="GtkDialog"><type>GtkDialog</type></link> must be modal using
        <link linkend="gtk-window-set-modal"><function>gtk_window_set_modal()</function></link> or the <link linkend="GTK-DIALOG-MODAL:CAPS"><literal>GTK_DIALOG_MODAL</literal></link> flag, and
        connecting to the <link linkend="GtkDialog-response"><type>“response”</type></link> signal.
      </para>
    </section>
  </section>
</chapter>
