1Title: Migrating from GTK 3.x to GTK 4 2Slug: gtk-migrating-3-to-4 3 4GTK 4 is a major new version of GTK that breaks both API and ABI 5compared to GTK 3.x. Thankfully, most of the changes are not hard 6to adapt to and there are a number of steps that you can take to 7prepare your GTK 3.x application for the switch to GTK 4. After 8that, there's a number of adjustments that you may have to do 9when you actually switch your application to build against GTK 4. 10 11## Preparation in GTK 3.x 12 13The steps outlined in the following sections assume that your 14application is working with GTK 3.24, which is the final stable 15release of GTK 3.x. It includes all the necessary APIs and tools 16to help you port your application to GTK 4. If you are using 17an older version of GTK 3.x, you should first get your application 18to build and work with the latest minor release in the 3.24 series. 19 20### Do not use deprecated symbols 21 22Over the years, a number of functions, and in some cases, entire 23widgets have been deprecated. These deprecations are clearly spelled 24out in the API reference, with hints about the recommended replacements. 25The API reference for GTK 3 also includes an 26[index](https://developer.gnome.org/gtk3/3.24/api-index-deprecated.html) 27of all deprecated symbols. 28 29To verify that your program does not use any deprecated symbols, 30you can use defines to remove deprecated symbols from the header files, 31as follows: 32 33``` 34make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" 35``` 36 37Note that some parts of our API, such as enumeration values, are 38not well covered by the deprecation warnings. In most cases, using 39them will require you to also use deprecated functions, which will 40trigger warnings. 41 42### Enable diagnostic warnings 43 44Deprecations of properties and signals cannot be caught at compile 45time, as both properties and signals are installed and used after 46types have been instantiated. In order to catch deprecations and 47changes in the run time components, you should use the 48`G_ENABLE_DIAGNOSTIC` environment variable when running your 49application, e.g.: 50 51``` 52G_ENABLE_DIAGNOSTIC=1 ./your-app 53``` 54 55### Do not use GTK-specific command line arguments 56 57GTK 4 does not parse command line arguments any more. If you are using 58command line arguments like `--gtk-debug` you should use the `GTK_DEBUG` 59environment variable instead. If you are using `--g-fatal-warnings` for 60debugging purposes, you should use the `G_DEBUG` environment variable, as 61specified by the 62[GLib documentation](https://developer.gnome.org/glib/stable/glib-running.html). 63 64### Do not use widget style properties 65 66Style properties do not exist in GTK 4. You should stop using them in 67your custom CSS and in your code. 68 69### Review your window creation flags 70 71GTK 4 removes the `GDK_WA_CURSOR` flag. Instead, just use 72`gdk_window_set_cursor()` to set a cursor on the window after 73creating it. GTK 4 also removes the `GDK_WA_VISUAL` flag, and 74always uses an RGBA visual for windows. To prepare your code for 75this, use `gdk_window_set_visual (gdk_screen_get_rgba_visual ())` 76after creating your window. GTK 4 also removes the `GDK_WA_WMCLASS` 77flag. If you need this X11-specific functionality, use `XSetClassHint()` 78directly. 79 80### Stop using direct access to GdkEvent structs 81 82In GTK 4, event structs are opaque and immutable. Many fields already 83have accessors in GTK 3, and you should use those to reduce the amount 84of porting work you have to do at the time of the switch. 85 86### Stop using `gdk_pointer_warp()` 87 88Warping the pointer is disorienting and unfriendly to users. 89GTK 4 does not support it. In special circumstances (such as when 90implementing remote connection UIs) it can be necessary to 91warp the pointer; in this case, use platform APIs such as 92`XWarpPointer()` directly. 93 94### Stop using non-RGBA visuals 95 96GTK 4 always uses RGBA visuals for its windows; you should make 97sure that your code works with such visuals. At the same time, 98you should stop using `GdkVisual` APIs, since this object not longer 99exists in GTK 4. Most of its APIs are deprecated already and not 100useful when dealing with RGBA visuals. 101 102### Stop using `gtk_widget_set_app_paintable` 103 104This is gone in GTK4 with no direct replacement. But for some usecases there 105are alternatives. If you want to make the background transparent, you can set 106the background color to, for example, `rgba(255, 255, 255, 0)` using CSS instead. 107 108### Stop using `GtkBox` padding, fill and expand child properties 109 110GTK 4 removes these [class@Gtk.Box] child properties, so you should stop using 111them. You can replace `GtkBox:padding` using `GtkWidget`'s `margin-*` properties 112on your child widgets. 113 114The fill child property can be replaced by setting appropriate values for 115the [property@Gtk.Widget:halign] and [property@Gtk.Widget:valign] properties 116of the child widgets. If you previously set the `fill` child property to 117`TRUE`, you can achieve the same effect by setting the `halign` or `valign` 118properties to `GTK_ALIGN_FILL`, depending on the parent box -- `halign` for a 119horizontal box, `valign` for a vertical one. 120 121[class@Gtk.Box] also uses the expand child property. It can be replaced by 122setting [property@Gtk.Widget:hexpand] or [property@Gtk.Widget:vexpand] on 123the child widgets. To match the old behavior of the `GtkBox`'s expand child 124property, you need to set `hexpand` on the child widgets of a horizontal 125`GtkBox` and `vexpand` on the child widgets of a vertical `GtkBox`. 126 127Note that there's a subtle but important difference between `GtkBox`'s 128`expand` and `fill` child properties and the ones in `GtkWidget`: setting 129[property@Gtk.Widget:hexpand] or [property@Gtk.Widget:vexpand] to `TRUE` 130will propagate up the widget hierarchy, so a pixel-perfect port might 131require you to reset the expansion flags to `FALSE` in a parent widget higher 132up the hierarchy. 133 134### Stop using the state argument of `GtkStyleContext` getters 135 136The getters in the [class@Gtk.StyleContext] API, such as 137`gtk_style_context_get_property()`, `gtk_style_context_get()`, 138or `gtk_style_context_get_color()` only accept the context's current 139state for their state argument. You should update all callers to pass 140the current state. 141 142### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_window()` 143 144These functions are not supported in GTK 4. Instead, either use 145backend-specific APIs, or render your widgets using 146[vfunc@Gtk.Widget.snapshot], once you are using GTK 4. 147 148### Stop using `GtkButton`'s image-related API 149 150The functions and properties related to automatically add a 151[class@Gtk.Image] to a [class@Gtk.Button], and using a `GtkSetting` to 152control its visibility, are not supported in GTK 4. Instead, you can just 153pack a GtkImage inside a GtkButton, and control its visibility like you 154would for any other widget. If you only want to add a named icon to a 155GtkButton, you can use [ctor@Gtk.Button.new_from_icon_name]. 156 157### Stop using `GtkWidget` event signals 158 159Event controllers and gestures replace event signals in GTK 4. 160 161Most of them have been backported to GTK 3.x so you can prepare 162for this change. 163 164| Signal | Event controller | 165| --- | --- | 166| ::event | [class@Gtk.EventControllerLegacy] | 167| ::event-after | [class@Gtk.EventControllerLegacy] | 168| ::button-press-event | [class@Gtk.GestureClick] | 169| ::button-release-event | [class@Gtk.GestureClick] | 170| ::touch-event | various touch gestures | 171| ::scroll-event | [class@Gtk.EventControllerScroll] | 172| ::motion-notify-event | [class@Gtk.EventControllerMotion] | 173| ::delete-event | - | 174| ::key-press-event | [class@Gtk.EventControllerKey] | 175| ::key-release-event | [class@Gtk.EventControllerKey] | 176| ::enter-notify-event | [class@Gtk.EventControllerMotion] | 177| ::leave-notify-event | [class@Gtk.EventControllerMotion] | 178| ::configure-event | - | 179| ::focus-in-event | [class@Gtk.EventControllerFocus] | 180| ::focus-out-event | [class@Gtk.EventControllerFocus] | 181| ::map-event | - | 182| ::unmap-event | - | 183| ::property-notify-event | replaced by [class@Gdk.Clipboard] | 184| ::selection-clear-event | replaced by [class@Gdk.Clipboard] | 185| ::selection-request-event | replaced by [class@Gdk.Clipboard] | 186| ::selection-notify-event | replaced by [class@Gdk.Clipboard] | 187| Drag-and-Drop signals | [class@Gtk.DragSource], [class@Gtk.DropTarget] | 188| ::proximity-in-event | [class@Gtk.GestureStylus] | 189| ::proximity-out-event | [class@Gtk.GestureStylus] | 190| ::visibility-notify-event | - | 191| ::window-state-event | - | 192| ::damage-event | - | 193| ::grab-broken-event | - | 194 195Event signals which are not directly related to input have to be dealt with 196on a one-by-one basis: 197 198 - If you were using `::configure-event` and `::window-state-event` to save 199 window state, you should use property notification for corresponding 200 [class@Gtk.Window] properties, such as [property@Gtk.Window:default-width], 201 [property@Gtk.Window:default-height], [property@Gtk.Window:maximized] or 202 [property@Gtk.Window:fullscreened]. 203 - If you were using `::delete-event` to present a confirmation when using 204 the close button of a window, you should use the 205 [signal@Gtk.Window::close-request] signal. 206 - If you were using `::map-event` and `::unmap-event` to track a window 207 being mapped, you should use property notification for the 208 [property@Gdk.Surface:mapped] property instead. 209 - The `::damage-event` signal has no replacement, as the only consumer 210 of damage events were the offscreen GDK surfaces, which have no 211 replacement in GTK 4.x. 212 213### Set a proper application ID 214 215In GTK 4 we want the application's `GApplication` 'application-id' (and 216therefore the D-Bus name), the desktop file basename and Wayland's xdg-shell 217`app_id` to match. In order to achieve this with GTK 3.x call 218`g_set_prgname()` with the same application ID you passed to 219[class@Gtk.Application]. Rename your desktop files to match the application 220ID if needed. 221 222The call to `g_set_prgname()` can be removed once you fully migrated to GTK 4. 223 224You should be aware that changing the application ID makes your 225application appear as a new, different app to application installers. 226You should consult the appstream documentation for best practices 227around renaming applications. 228 229### Stop using `gtk_main()` and related APIs 230 231GTK 4 removes the `gtk_main_*` family of APIs. The recommended replacement 232is [class@Gtk.Application], but you can also iterate the GLib main loop directly, 233using `GMainContext` APIs. The replacement for `gtk_events_pending()` is 234`g_main_context_pending()`, the replacement for `gtk_main_iteration()` is 235`g_main_context_iteration()`. 236 237In GTK 4, you can use this replacement that will iterate the default main loop 238until all windows have been closed: 239 240``` 241while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0) 242 g_main_context_iteration (NULL, TRUE); 243``` 244 245### Reduce the use of `gtk_widget_destroy()` 246 247GTK 4 introduces a [method@Gtk.Window.destroy] api. While that is not available 248in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()` 249only on toplevel windows, and replace all other uses with 250`gtk_container_remove()` or `g_object_unref()`. 251 252### Stop using the GtkWidget.destroy vfunc 253 254Instead of implementing GtkWidget.destroy, you can implement GObject.dispose. 255 256### Reduce the use of generic container APIs 257 258GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there 259is not always a replacement for `gtk_container_remove()` in GTK 3, you can 260replace many uses of `gtk_container_add()` with equivalent container-specific 261APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce 262the amount of work you have to do at the time of the switch. 263 264### Review your use of icon resources 265 266When using icons as resources, the behavior of GTK 4 is different in one 267respect: Icons that are directly in `$APP_ID/icons/` are treated as unthemed 268icons, which also means that symbolic icons are not recolored. If you want 269your icon resources to have icon theme semantics, they need to be placed 270into theme subdirectories such as `$APP_ID/icons/16x16/actions` or 271`$APP_ID/icons/scalable/status`. 272 273This location works fine in GTK 3 too, so you can prepare for this change 274before switching to GTK 4. 275 276## Changes that need to be done at the time of the switch 277 278This section outlines porting tasks that you need to tackle when 279you get to the point that you actually build your application against 280GTK 4. Making it possible to prepare for these in GTK 3 would 281have been either impossible or impractical. 282 283### Larger changes 284 285Some of the larger themes of GTK 4 development are hard to cover in the form 286of checklist items, so we mention them separately up-front. 287 288#### Subclassing 289 290Compared to previous versions, GTK 4 emphasizes composition and delegation 291over subclassing. As a consequence, many widgets can no longer be subclassed. 292In most cases, you should look deriving your widget directly from GtkWidget 293and use complex widgets as child widgets instead of deriving from them. 294 295#### Life-cycle handling 296 297Widgets in GTK 4 are treated like any other objects - their parent widget 298holds a reference on them, and GTK holds a reference on toplevel windows. 299[method@Gtk.Window.destroy] will drop the reference on the toplevel window, 300and cause the whole widget hierarchy to be finalized unless there are other 301references that keep widgets alive. 302 303The [signal@Gtk.Widget::destroy] signal is emitted when a widget is 304disposed, and therefore can no longer be used to break reference cycles. 305A typical sign of a reference cycle involving a toplevel window is when 306closing the window does not make the application quit. 307 308### Stop using GdkScreen 309 310The `GdkScreen` object has been removed in GTK 4. Most of its APIs already 311had replacements in GTK 3 and were deprecated, a few remaining replacements 312have been added to `GdkDisplay`. 313 314### Stop using the root window 315 316The root window is an X11-centric concept that is no longer exposed in the 317backend-neutral GDK API. If you need to interact with the X11 root window, 318you can use [method@GdkX11.Display.get_xrootwindow] to get its XID. 319 320### Stop using `GdkVisual` 321 322This object is not useful with current GTK drawing APIs and has been removed 323without replacement. 324 325### Stop using `GdkDeviceManager` 326 327The `GdkDeviceManager` object has been removed in GTK 4. Most of its APIs already 328had replacements in GTK 3 and were deprecated in favor of `GdkSeat`. 329 330### Adapt to `GdkWindow` API changes 331 332`GdkWindow` has been renamed to `GdkSurface`. 333 334In GTK 4, the two roles of a standalone toplevel window and of a popup that 335is placed relative to a parent window have been separated out into two 336interfaces, [class@Gdk.Toplevel] and [class@Gdk.Popup]. Surfaces 337implementing these interfaces are created with [ctor@Gdk.Surface.new_toplevel] 338and [ctor@Gdk.Surface.new_popup], respectively, and they are presented on 339screen using [method@Gdk.Toplevel.present] and [method@Gdk.Popup.present]. 340The `present()` functions take parameters in the form of an auxiliary layout 341struct, [struct@Gdk.PopupLayout] or [struct@Gdk.ToplevelLayout]. 342 343If your code is dealing directly with surfaces, you may have to change it 344to call the API in these interfaces, depending on whether the surface you are 345dealing with is a toplevel or a popup. 346 347As part of this reorganization, X11-only concepts such as sticky, 348keep-below, urgency, skip-taskbar or window groups have either been 349removed or moved to X11 backend api. If you need to use them on your 350X11 windows, you will have to use those backend apis or set the 351corresponding X11 properties (as specified in the EWMH) yourself. 352 353Subsurfaces are not currently supported. Native and foreign subwindows 354are no longer supported. These concepts were complicating the code 355and could not be supported across backends. 356 357A number of GdkWindow APIs are no longer available. This includes 358`gdk_window_reparent()`, `gdk_window_set_geometry_hints()`, `gdk_window_raise()`, 359`gdk_window_restack()`, `gdk_window_move()`, `gdk_window_resize()`. If 360you need to manually control the position or stacking of your X11 361windows, you you will have to use Xlib apis. 362 363A number of minor API cleanups have happened in `GdkSurface` 364as well. For example, `gdk_surface_input_shape_combine_region()` 365has been renamed to [method@Gdk.Surface.set_input_region], and 366`gdk_surface_begin_resize_drag()` has been renamed to 367[method@Gdk.Toplevel.begin_resize]. 368 369### The "iconified" window state has been renamed to "minimized" 370 371The `GDK_TOPLEVEL_STATE_ICONIFIED` value of the `GdkSurfaceState` enumeration 372is now `GDK_TOPLEVEL_STATE_MINIMIZED` in the `GdkToplevelState` enumeration. 373 374The `GdkWindow` functions `gdk_window_iconify()` and 375`gdk_window_deiconify()` have been renamed to [method@Gdk.Toplevel.minimize] 376and [method@Gdk.Toplevel.present], respectively. 377 378The behavior of the minimization and unminimization operations have 379not been changed, and they still require support from the underlying 380windowing system. 381 382### Adapt to `GdkEvent` API changes 383 384Direct access to [class@Gdk.Event] structs is no longer possible in GTK 4. 385`GdkEvent` is now a strictly read-only type, and you can no longer 386change any of its fields, or construct new events. All event fields 387have accessors that you will have to use. 388 389Event compression is always enabled in GTK 4, for both motion and 390scroll events. If you need to see the uncoalesced motion or scroll 391history, use [method@Gdk.Event.get_history] on the latest event. 392 393### Stop using grabs 394 395GTK 4 no longer provides the `gdk_device_grab()` or `gdk_seat_grab()` 396apis. If you need to dismiss a popup when the user clicks outside 397(the most common use for grabs), you can use the `GdkPopup` 398[property@Gdk.Popup:autohide] property instead. [class@Gtk.Popover] 399also has a [property@Gtk.Popover:autohide] property for this. If you 400need to prevent the user from interacting with a window while a dialog 401is open, use the [property@Gtk.Window:modal] property of the dialog. 402 403### Adapt to coordinate API changes 404 405A number of coordinate APIs in GTK 3 had `double` variants: 406`gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`. 407These have been changed to use doubles, and the `double` variants 408have been removed. Update your code accordingly. 409 410Any APIs that deal with global (or root) coordinates have been 411removed in GTK 4, since not all backends support them. You should 412replace your use of such APIs with surface-relative equivalents. 413Examples of this are `gdk_surface_get_origin()`, `gdk_surface_move()` 414or `gdk_event_get_root_coords()`. 415 416### Adapt to `GdkKeymap` API changes 417 418`GdkKeymap` no longer exists as an independent object. 419 420If you need access to keymap state, it is now exposed as properties 421on the `GdkDevice` representing the keyboard: 422[property@Gdk.Device:direction], 423[property@Gdk.Device:has-bidi-layouts], 424[property@Gdk.Device:caps-lock-state], 425[property@Gdk.Device:num-lock-state], 426[property@Gdk.Device:scroll-lock-state] and 427[property@Gdk.Device:modifier-state]. To obtain the keyboard device, 428you can use 429 430``` 431gdk_seat_get_keyboard (gdk_display_get_default_seat (display) 432``` 433 434If you need access to translated keys for event handling, `GdkEvent` 435now includes all of the translated key state, including consumed 436modifiers, group and shift level, so there should be no need to 437manually call `gdk_keymap_translate_keyboard_state()` (which has 438been removed). 439 440If you need to do forward or backward mapping between key codes 441and key values, use [method@Gdk.Display.map_keycode] and 442[method@Gdk.Display.map_keyval], which are the replacements for 443`gdk_keymap_get_entries_for_keycode()` and 444`gdk_keymap_get_entries_for_keyval()`. 445 446### Adapt to changes in keyboard modifier handling 447 448GTK 3 has the idea that use of modifiers may differ between different 449platforms, and has a `GdkModifierIntent` api to let platforms provide 450hint about how modifiers are expected to be used. It also promoted 451the use of `<Primary>` instead of `<Control>` to specify accelerators that 452adapt to platform conventions. 453 454In GTK 4, the meaning of modifiers has been fixed, and backends are 455expected to map the platform conventions to the existing modifiers. 456The expected use of modifiers in GTK 4 is: 457 458`GDK_CONTROL_MASK` 459 : Primary accelerators 460 461`GDK_ALT_MASK` 462 : Mnemonics 463 464`GDK_SHIFT_MASK` 465 : Extending selections 466 467`GDK_CONTROL_MASK` 468 : Modifying selections 469 470`GDK_CONTROL_MASK|GDK_ALT_MASK` 471 : Prevent text input 472 473Consequently, `GdkModifierIntent` and related APIs have been removed, 474and `<Control>` is preferred over `<Primary>` in accelerators. 475 476A related change is that GTK 4 no longer supports the use of archaic 477X11 'real' modifiers with the names Mod1,..., Mod5, and `GDK_MOD1_MASK` 478has been renamed to `GDK_ALT_MASK`. 479 480### Replace `GtkClipboard` with `GdkClipboard` 481 482The `GtkClipboard` API has been removed, and replaced by `GdkClipboard`. 483There is not direct 1:1 mapping between the old an the new API, so it cannot 484be a mechanical replacement; the new API is based on object types and `GValue` 485like object properties, instead of opaque identifiers, so it should be easier 486to use. 487 488For instance, the example below copies the contents of an entry into the 489clipboard: 490 491```c 492static void 493copy_text (GtkWidget *widget) 494{ 495 GtkEditable *editable = GTK_EDITABLE (widget); 496 497 // Initialize a GValue with the contents of the widget 498 GValue value = G_VALUE_INIT; 499 g_value_init (&value, G_TYPE_STRING); 500 g_value_set_string (&value, gtk_editable_get_text (editable)); 501 502 // Store the value in the clipboard object 503 GdkClipboard *clipboard = gtk_widget_get_clipboard (widget); 504 gdk_clipboard_set_value (clipboard, &value); 505 506 g_value_unset (&value); 507} 508``` 509 510whereas the example below pastes the contents into the entry: 511 512```c 513static void 514paste_text (GtkWidget *widget) 515{ 516 GtkEditable *editable = GTK_EDITABLE (widget); 517 518 // Initialize a GValue to receive text 519 GValue value = G_VALUE_INIT; 520 g_value_init (&value, G_TYPE_STRING); 521 522 // Get the content provider for the clipboard, and ask it for text 523 GdkClipboard *clipboard = gtk_widget_get_clipboard (widget); 524 GdkContentProvider *provider = gdk_clipboard_get_content (clipboard); 525 526 // If the content provider does not contain text, we are not interested 527 if (!gdk_content_provider_get_value (provider, &value, NULL)) 528 return; 529 530 const char *str = g_value_get_string (&value); 531 532 gtk_editable_set_text (editable, str); 533 534 g_value_unset (&value); 535} 536``` 537 538The convenience API for specific target types in `GtkClipboard` has been 539replaced by their corresponding GType: 540 541| GtkClipboard | GType | 542| ----------------------------------- | ---------------------- | 543| `gtk_clipboard_request_text()` | `G_TYPE_STRING` | 544| `gtk_clipboard_request_rich_text()` | `GTK_TYPE_TEXT_BUFFER` | 545| `gtk_clipboard_request_image()` | `GDK_TYPE_PIXBUF` | 546| `gtk_clipboard_request_uris()` |` GDK_TYPE_FILE_LIST` | 547 548**Note**: Support for rich text serialization across different processes 549for `GtkTextBuffer` is not available any more. 550 551If you are copying the contents of an image, it is recommended to use 552`GDK_TYPE_PAINTABLE` instead of `GDK_TYPE_PIXBUF`, to minimize the amount of 553potential copies. 554 555### Stop using `gtk_get_current_...` APIs 556 557The function `gtk_get_current_event()` and its variants have been 558replaced by equivalent event controller APIs: 559[method@Gtk.EventController.get_current_event], etc. 560 561### Convert your UI files 562 563A number of the changes outlined below affect `.ui` files. The 564`gtk4-builder-tool simplify` command can perform many of the 565necessary changes automatically, when called with the `--3to4` 566option. You should always review the resulting changes. 567 568The `<requires>` tag now supports for the `lib` attribute the 569`gtk` value only, instead of the `gtk+` one previously. 570 571### Adapt to GtkBuilder API changes 572 573`gtk_builder_connect_signals()` no longer exists. Instead, signals are 574always connected automatically. If you need to add user data to your 575signals, [method@Gtk.Builder.set_current_object] must be called. An important 576caveat is that you have to do this before loading any XML. This means if 577you need to use [method@Gtk.Builder.set_current_object], you can no longer use 578[ctor@Gtk.Builder.new_from_file], [ctor@Gtk.Builder.new_from_resource], or 579[ctor@Gtk.Builder.new_from_string]. Instead, you must use vanilla [ctor@Gtk.Builder.new], 580then call [method@Gtk.Builder.set_current_object], then load the XML using 581[method@Gtk.Builder.add_from_file], [method@Gtk.Builder.add_from_resource], or 582[method@Gtk.Builder.add_from_string]. You must check the return value for 583failure and manually abort with `g_error()` if something went wrong. 584 585You only have to worry about this if you were previously using 586`gtk_builder_connect_signals()`. If you are using templates, then 587`gtk_widget_init_template()` will call `gtk_builder_set_current_object()` 588for you, so templates work like before. 589 590### Adapt to event controller API changes 591 592A few changes to the event controller and [class@Gtk.Gesture] APIs 593did not make it back to GTK 3, and have to be taken into account 594when moving to GTK 4. One is that the [signal@Gtk.EventControllerMotion::enter] 595and [signal@Gtk.EventControllerMotion::leave] signals have gained new arguments. 596Another is that `GtkGestureMultiPress` has been renamed to [class@Gtk.GestureClick], 597and has lost its area property. A [class@Gtk.EventControllerFocus] has been 598split off from [class@Gtk.EventControllerKey]. 599 600In GTK 3, `GtkEventController:widget` was a construct-only property, so a 601`GtkWidget` was provided whenever constructing a `GtkEventController`. In 602GTK 4, [property@Gtk.EventController:widget] is now read-only. Use 603[method@Gtk.Widget.add_controller] to add an event controller to a widget. 604 605In GTK 3, widgets did not own their event controllers, and event 606controllers did not own their widgets, so developers were responsible 607for manually keeping event controllers alive for the lifetime of their 608associated widgets. In GTK 4, widgets own their event controllers. 609[method@Gtk.Widget.add_controller] takes ownership of the event controller, so 610there is no longer any need to store a reference to the event controller 611after it has been added to a widget. 612 613Although not normally needed, an event controller could be removed from 614a widget in GTK 3 by destroying the event controller with `g_object_unref()`. 615In GTK 4, you must use [method@Gtk.Widget.remove_controller]. 616 617### Focus handling changes 618 619The semantics of the [property@Gtk.Widget:can-focus] property have changed. 620In GTK 3, this property only meant that the widget itself would not 621accept keyboard input, but its children still might (in the case of 622containers). In GTK 4, if `:can-focus` is `FALSE`, the focus cannot enter 623the widget or any of its descendents, and the default value has changed 624from `FALSE` to `TRUE`. In addition, there is a [property@Gtk.Widget:focusable] 625property, which controls whether an individual widget can receive 626the input focus. 627 628The `gtk4-builder-tool` utility, when called with the `--3to4` option of the 629`simplify` command, will replace `:can-focus` by `:focusable`. 630 631The feature to automatically keep the focus widget scrolled into view with 632`gtk_container_set_focus_vadjustment()` has been removed together with 633`GtkContainer`, and is provided by scrollable widgets instead. In the common 634case that the scrollable is a [class@Gtk.Viewport], use 635[property@Gtk.Viewport:scroll-to-focus]. 636 637### Use the new apis for keyboard shortcuts 638 639The APIs for keyboard shortcuts and accelerators have changed in GTK 4. 640 641Instead of `GtkAccelGroup`, you now use a [class@Gtk.ShortcutController] with global 642scope, and instead of `GtkBindingSet`, you now use [method@Gtk.WidgetClass.add_shortcut], 643[method@Gtk.WidgetClass.add_binding] and its variants. In both cases, you probably 644want to add actions that can be triggered by your shortcuts. 645 646There is no direct replacement for loading and saving accelerators with 647`GtkAccelMap`. But since `GtkShortcutController` implements `GListModel` and 648both [class@Gtk.ShortcutTrigger] and [class@Gtk.ShortcutAction] can be 649serialized to strings, it is relatively easy to implement saving and loading 650yourself. 651 652### Stop using `GtkEventBox` 653 654`GtkEventBox` is no longer needed and has been removed. 655 656All widgets receive all events. 657 658### Stop using `GtkButtonBox` 659 660`GtkButtonBox` has been removed. Use a [class@Gtk.Box] instead. 661 662### Adapt to `GtkBox` API changes 663 664The GtkBox `pack_start()` and `pack_end()` methods have been replaced by 665[method@Gtk.Box.prepend] and [method@Gtk.Box.append]. You can also reorder 666box children as necessary. 667 668### Adapt to `GtkWindow` API changes 669 670Following the `GdkSurface` changes, a number of `GtkWindow` APIs that were 671X11-specific have been removed. This includes `gtk_window_set_geometry_hints()`, 672`gtk_window_set_gravity()`, `gtk_window_move()`, `gtk_window_parse_geometry()`, 673`gtk_window_set_keep_above()`, `gtk_window_set_keep_below()`, 674`gtk_window_begin_resize_drag()`, `gtk_window_begin_move_drag()`. 675Most likely, you should just stop using them. In some cases, you can 676fall back to using the underlying `GdkToplevel` APIs (for example, 677[method@Gdk.Toplevel.begin_resize]). 678 679The APIs for controlling `GtkWindow` size have changed to be better aligned 680with the way size changes are integrated in the frame cycle. `gtk_window_resize()` 681and `gtk_window_get_size()` have been removed. Instead, use 682[method@Gtk.Window.set_default_size] and [method@Gtk.Window.get_default_size]. 683 684### Adapt to `GtkHeaderBar` and `GtkActionBar` API changes 685 686The `gtk_header_bar_set_show_close_button()` function has been renamed to 687the more accurate name [method@Gtk.HeaderBar.set_show_title_buttons]. The 688corresponding getter and the property itself have also been renamed. 689The default value of the property is now `TRUE` instead of `FALSE`. 690 691The `gtk_header_bar_set_custom_title()` function has been renamed to 692the more accurate name [method@Gtk.HeaderBar.set_title_widget]. The 693corresponding getter and the property itself have also been renamed. 694 695The `gtk_header_bar_set_title()` function has been removed along with its 696corresponding getter and the property. By default [class@Gtk.HeaderBar] 697shows the title of the window, so if you were setting the title of the 698header bar, consider setting the window title instead. If you need to show a 699title that's different from the window title, use the 700[property@Gtk.HeaderBar:title-widget] property to add a [class@Gtk.Label] as 701shown in the example in the [class@Gtk.HeaderBar] documentation. 702 703The `gtk_header_bar_set_subtitle()` function has been removed along with 704its corresponding getter and the property. The old "subtitle" behavior 705can be replicated by setting the [property@Gtk.HeaderBar:title-widget] property to 706a [class@Gtk.Box] with two labels inside, with the title label matching the 707example in `GtkHeaderBar` documentation, and the subtitle label being 708similar, but with `"subtitle"` style class instead of `"title"`. 709 710The `gtk_header_bar_set_has_subtitle()` function has been removed along with 711its corresponding getter and the property. Its behavior can be replicated by 712setting the [property@Gtk.HeaderBar:title-widget] property to a 713[class@Gtk.Stack] with [property@Gtk.Stack:vhomogeneous] property set to 714`TRUE` and two pages, each with a [class@Gtk.Box] with title and subtitle as 715described above. 716 717Some of the internal structure of `GtkHeaderBar` has been made available as 718public API: [class@Gtk.WindowHandle] and [class@Gtk.WindowControls]. If you 719have unusual needs for custom headerbars, these might be useful to you. 720 721The `:pack-type` child properties of `GtkHeaderBar` and `GtkActionBar` have 722been removed. If you need to programmatically place children, use the 723[method@Gtk.HeaderBar.pack_start] and [method@Gtk.HeaderBar.pack_end] methods. 724In UI files, use the `type` attribute on the `child` element. 725 726The `gtk4-builder-tool` utility can help with this conversion, with the 727`--3to4` option of the `simplify` command. 728 729### Adapt to GtkStack, GtkAssistant and GtkNotebook API changes 730 731The child properties of `GtkStack`, `GtkAssistant` and `GtkNotebook` have been 732converted into child meta objects. 733 734Instead of `gtk_container_child_set (stack, child, …)`, you can now use 735`g_object_set (gtk_stack_get_page (stack, child), …)`. In .ui files, the 736`GtkStackPage` objects must be created explicitly, and take the child widget 737as property. The changes to `GtkNotebook` and `GtkAssistant` are similar. 738 739`gtk4-builder-tool` can help with this conversion, with the `--3to4` option 740of the `simplify` command. 741 742### Adapt to button class hierarchy changes 743 744`GtkCheckButton` is no longer derived from `GtkToggleButton`. Call 745[method@Gtk.CheckButton.set_active] instead of [method@Gtk.ToggleButton.set_active]. 746 747`GtkRadioButton` has been removed, and its grouping functionality has 748been added to `GtkCheckButton` and `GtkToggleButton`. Use grouped 749check buttons for traditional radio groups, and used grouped toggle 750buttons for view switchers. The new API to set up groups of buttons 751is [method@Gtk.CheckButton.set_group] and [method@Gtk.ToggleButton.set_group]. 752 753`gtk4-builder-tool` can help with this conversion, with the `--3to4` option 754of the `simplify` command. 755 756### Adapt to GtkScrolledWindow API changes 757 758The constructor for `GtkScrolledWindow` no longer takes the adjustments 759as arguments - these were almost always `NULL`. 760 761### Adapt to GtkBin removal 762 763The abstract base class `GtkBin` for single-child containers has been 764removed. The former subclasses are now derived directly from `GtkWidget`, 765and have a "child" property for their child widget. To add a child, use 766the setter for the "child" property (e.g. [method@Gtk.Frame.set_child]) instead 767of `gtk_container_add()`. Adding a child in a ui file with `<child>` still works. 768 769The affected classes are: 770 771- [class@Gtk.AspectFrame] 772- [class@Gtk.Button] (and subclasses) 773- [class@Gtk.ComboBox] 774- [class@Gtk.FlowBoxChild] 775- [class@Gtk.Frame] 776- [class@Gtk.ListBoxRow] 777- [class@Gtk.Overlay] 778- [class@Gtk.Popover] 779- [class@Gtk.Revealer] 780- [class@Gtk.ScrolledWindow] 781- [class@Gtk.SearchBar] 782- [class@Gtk.Viewport] 783- [class@Gtk.Window] (and subclasses) 784 785If you have custom widgets that were derived from `GtkBin`, you should 786port them to derive from `GtkWidget`. Notable vfuncs that you will have 787to implement include the `GObject` dispose vfunc (to unparent your child), 788[vfunc@Gtk.Widget.compute_expand] (if you want your container to propagate 789expand flags) and [vfunc@Gtk.Widget.get_request_mode] (if you want your 790container to support height-for-width). 791 792You may also want to implement the [iface@Gtk.Buildable] interface, to support 793adding children with `<child>` in ui files. 794 795### Adapt to GtkContainer removal 796 797The abstract base class `GtkContainer` for general containers has been 798removed. The former subclasses are now derived directly from `GtkWidget`, 799and have class-specific add() and remove() functions. 800 801The most noticeable change is the use of [method@Gtk.Box.append] or [method@Gtk.Box.prepend] 802instead of `gtk_container_add()` for adding children to `GtkBox`, and the change 803to use container-specific remove functions, such as [method@Gtk.Stack.remove] instead 804of `gtk_container_remove()`. Adding a child in a ui file with `<child>` still works. 805 806The affected classes are: 807 808- [class@Gtk.ActionBar] 809- [class@Gtk.Box] (and subclasses) 810- [class@Gtk.Expander] 811- [class@Gtk.Fixed] 812- [class@Gtk.FlowBox] 813- [class@Gtk.Grid] 814- [class@Gtk.HeaderBar] 815- [class@Gtk.IconView] 816- [class@Gtk.InfoBar] 817- [class@Gtk.ListBox] 818- [class@Gtk.Notebook] 819- [class@Gtk.Paned] 820- [class@Gtk.Stack] 821- [class@Gtk.TextView] 822- [class@Gtk.TreeView] 823 824Without `GtkContainer`, there are no longer facilities for defining and 825using child properties. If you have custom widgets using child properties, 826they will have to be converted either to layout properties provided 827by a layout manager (if they are layout-related), or handled in some 828other way. One possibility is to use child meta objects, as seen with 829[class@Gtk.AssistantPage], [class@Gtk.StackPage] and the like. 830 831If you used to define child properties with `<packing>` in ui files, you have 832to switch to using `<layout>` for the corresponding layout properties. 833`gtk4-builder-tool` can help with this conversion, with the `--3to4` option 834of the `simplify` command. 835 836The replacements for gtk_container_add() are: 837 838| Widget | Replacement | 839| ------ | ----------- | 840| `GtkActionBar` | [method@Gtk.ActionBar.pack_start], [method@Gtk.ActionBar.pack_end] | 841| `GtkBox` | [method@Gtk.Box.prepend], [method@Gtk.Box.append] | 842| `GtkExpander` | [method@Gtk.Expander.set_child] | 843| `GtkFixed` | [method@Gtk.Fixed.put] | 844| `GtkFlowBox` | [method@Gtk.FlowBox.insert] | 845| `GtkGrid` | [method@Gtk.Grid.attach] | 846| `GtkHeaderBar` | [method@Gtk.HeaderBar.pack_start], [method@Gtk.HeaderBar.pack_end] | 847| `GtkIconView` | - | 848| `GtkInfoBar` | [method@Gtk.InfoBar.add_child] | 849| `GtkListBox` | [method@Gtk.ListBox.insert] | 850| `GtkNotebook` | [method@Gtk.Notebook.append_page] | 851| `GtkPaned` | [method@Gtk.Paned.set_start_child], [method@Gtk.Paned.set_end_child] | 852| `GtkStack` | [method@Gtk.Stack.add_child] | 853| `GtkTextView` | [method@Gtk.TextView.add_child_at_anchor], [method@Gtk.TextView.add_overlay] | 854| `GtkTreeView` | - | 855 856### Stop using GtkContainer::border-width 857 858GTK 4 has removed the `GtkContainer::border-width` property (together 859with the rest of `GtkContainer`). Use other means to influence the spacing 860of your containers, such as the CSS margin and padding properties on child 861widgets, or the CSS border-spacing property on containers. 862 863### Adapt to gtk_widget_destroy() removal 864 865The function `gtk_widget_destroy()` has been removed. To explicitly destroy 866a toplevel window, use [method@Gtk.Window.destroy]. To destroy a widget that is 867part of a hierarchy, remove it from its parent using a container-specific 868remove API, such as [method@Gtk.Box.remove] or [method@Gtk.Stack.remove]. To 869destroy a freestanding non-toplevel widget, use `g_object_unref()` to drop your 870reference. 871 872### Adapt to coordinate API changes 873 874A number of APIs that are accepting or returning coordinates have 875been changed from ints to doubles: `gtk_widget_translate_coordinates()`, 876`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent, 877except for cases where out parameters are involved: you need to 878pass double* now, instead of int*. 879 880### Adapt to GtkStyleContext API changes 881 882The getters in the GtkStyleContext API, such as 883[method@Gtk.StyleContext.get_color], [method@Gtk.StyleContext.get_border], 884or [method@Gtk.StyleContext.get_margin] have lost their state argument, 885and always use the context's current state. Update all callers 886to omit the state argument. 887 888The most commonly used GtkStyleContext API, `gtk_style_context_add_class()`, 889has been moved to GtkWidget as [method@Gtk.Widget.add_css_class], as have the 890corresponding `gtk_style_context_remove_class()` and 891`gtk_style_context_has_class()` APIs. 892 893### Adapt to GtkCssProvider API changes 894 895In GTK 4, the various `GtkCssProvider` load functions have lost their 896`GError` argument. If you want to handle CSS loading errors, use the 897[signal@Gtk.CssProvider::parsing-error] signal instead. gtk_css_provider_get_named() 898has been replaced by [method@Gtk.CssProvider.load_named]. 899 900### Stop using GtkShadowType and GtkRelief properties 901 902The shadow-type properties in `GtkScrolledWindow`, `GtkViewport`, 903and `GtkFrame`, as well as the relief properties in `GtkButton` 904and its subclasses have been removed. `GtkScrolledWindow`, `GtkButton` 905and `GtkMenuButton` have instead gained a boolean has-frame property. 906 907### Adapt to GtkWidget's size request changes 908 909GTK 3 used five different virtual functions in GtkWidget to 910implement size requisition, namely the `gtk_widget_get_preferred_width()` 911family of functions. To simplify widget implementations, GTK 4 uses 912only one virtual function, [vfunc@Gtk.Widget.measure], that widgets 913have to implement. [method@Gtk.Widget.measure] replaces the various 914`gtk_widget_get_preferred_` functions for querying sizes. 915 916### Adapt to GtkWidget's size allocation changes 917 918The [vfunc@Gtk.Widget.size_allocate] vfunc takes the baseline as an argument 919now, so you no longer need to call `gtk_widget_get_allocated_baseline()` 920to get it. 921 922The ::size-allocate signal has been removed, since it is easy 923to misuse. If you need to learn about sizing changes of custom 924drawing widgets, use the [signal@Gtk.DrawingArea::resize] or 925[signal@Gtk.GLArea::resize] signals. If you want to track the size 926of toplevel windows, use property notification for 927[property@Gtk.Window:default-width] and [property@Gtk.Window:default-height]. 928 929### Switch to GtkWidget's children APIs 930 931In GTK 4, any widget can have children (and `GtkContainer` is gone). 932There is new API to navigate the widget tree, for use in widget 933implementations: 934[method@Gtk.Widget.get_first_child], 935[method@Gtk.Widget.get_last_child], 936[method@Gtk.Widget.get_next_sibling], 937[method@Gtk.Widget.get_prev_sibling]. 938 939### Don't use -gtk-gradient in your CSS 940 941GTK now supports standard CSS syntax for both linear and radial 942gradients, just use those. 943 944### Don't use -gtk-icon-effect in your CSS 945 946GTK now supports a more versatile -gtk-icon-filter instead. 947 948Replace 949 950| Old | Replacement | 951| ------ | ----------- | 952| -gtk-icon-effect: dim | -gtk-icon-filter: opacity(0.5) | 953| -gtk-icon-effect: highlight | -gtk-icon-filter: brightness(1.2) | 954 955### Don't use -gtk-icon-theme in your CSS 956 957GTK 4 always uses the current icon theme, with no way to change this. 958 959### Don't use -gtk-outline-...-radius in your CSS 960 961These non-standard properties have been removed from GTK 962CSS. Just use regular border radius. 963 964### Adapt to drawing model changes 965 966This area has seen the most radical changes in the transition from GTK 3 967to GTK 4. Widgets no longer use a draw() function to render their contents 968to a cairo surface. Instead, they have a [vfunc@Gtk.Widget.snapshot] function 969that creates one or more GskRenderNodes to represent their content. Third-party 970widgets that use a draw() function or a `GtkWidget::draw` signal handler for 971custom drawing will need to be converted to use [method@Gtk.Snapshot.append_cairo]. 972 973The auxiliary [class@Gtk.Snapshot] object has APIs to help with creating render 974nodes. 975 976If you are using a `GtkDrawingArea` for custom drawing, you need to switch 977to using [method@Gtk.DrawingArea.set_draw_func] to set a draw function instead 978of connecting a handler to the `GtkWidget::draw` signal. 979 980### Stop using APIs to query GdkSurfaces 981 982A number of APIs for querying special-purpose windows have been removed, 983since these windows no longer exist: 984`gtk_tree_view_get_bin_window()`, `gtk_viewport_get_bin_window()`, 985`gtk_viewport_get_view_window()`. 986 987### Widgets are now visible by default 988 989The default value of [property@Gtk.Widget:visible] in GTK 4 is %TRUE, so you no 990longer need to explicitly show all your widgets. On the flip side, you 991need to hide widgets that are not meant to be visible from the start. 992The only widgets that still need to be explicitly shown are toplevel 993windows, dialogs and popovers. 994 995A convenient way to remove unnecessary property assignments like this 996from ui files it run the command `gtk4-builder-tool simplify --replace` 997on them. 998 999The function `gtk_widget_show_all()`, the `GtkWidget:no-show-all` property 1000and its getter and setter have been removed in GTK 4, so you should stop 1001using them. 1002 1003### Adapt to changes in animated hiding and showing of widgets 1004 1005Widgets that appear and disappear with an animation, such as 1006`GtkInfoBar`, `GtkRevealer` no longer use `gtk_widget_show()` and 1007`gtk_widget_hide()` for this, but have gained dedicated APIs for this 1008purpose that you should use instead, such as [method@Gtk.InfoBar.set_revealed]. 1009 1010### Stop passing commandline arguments to gtk_init 1011 1012The [func@Gtk.init] and [func@Gtk.init_check] functions no longer accept 1013commandline arguments. Just call them without arguments. Other initialization 1014functions that were purely related to commandline argument handling, such as 1015`gtk_parse_args()` and `gtk_get_option_group()`, are gone. 1016 1017The APIs to initialize GDK separately are also gone, but it is very unlikely 1018that you are affected by that. 1019 1020### GdkPixbuf is deemphasized 1021 1022A number of `GdkPixbuf`-based APIs have been removed. The available replacements 1023are either using `GIcon`, or the newly introduced [class@Gdk.Texture] or 1024[iface@Gdk.Paintable] classes instead. If you are dealing with pixbufs, you can use 1025[ctor@Gdk.Texture.new_for_pixbuf] to convert them to texture objects where needed. 1026 1027### GtkWidget event signals are removed 1028 1029Event controllers and GtkGestures have already been introduced in GTK 3 to handle 1030input for many cases. In GTK 4, the traditional widget signals for handling input, 1031such as `GtkWidget::motion-event` or `GtkWidget::event` have been removed. All event 1032handling is done via event controllers now. 1033 1034### Invalidation handling has changed 1035 1036Only [method@Gtk.Widget.queue_draw] is left to mark a widget as needing redraw. 1037Variations like `gtk_widget_queue_draw_rectangle()` or `gtk_widget_queue_draw_region()` 1038are no longer available. 1039 1040### Stop using GtkWidget::draw 1041 1042The `GtkWidget::draw` signal has been removed. Widgets need to implement the 1043[vfunc@Gtk.Widget.snapshot] function now. Connecting draw signal handlers is 1044no longer possible. If you want to keep using cairo for drawing, use 1045[method@Gtk.Snapshot.append_cairo]. 1046 1047### Window content observation has changed 1048 1049Observing widget contents and widget size is now done by using the 1050[class@Gtk.WidgetPaintable] object instead of connecting to widget signals. 1051 1052### Monitor handling has changed 1053 1054Instead of a monitor number, [class@Gdk.Monitor] is now used throughout. 1055[method@Gdk.Display.get_monitors] returns the list of monitors that can be queried 1056or observed for monitors to pass to APIs like [method@Gtk.Window.fullscreen_on_monitor]. 1057 1058### Adapt to monitor API changes 1059 1060The `gdk_monitor_get_workarea()` API is gone. Individual backends can still 1061provide this information, for example with [method@GdkX11.Monitor.get_workarea]. 1062 1063If you use this information, your code should check which backend is in 1064use and then call the appropriate backend API. 1065 1066### Adapt to cursor API changes 1067 1068Use the new [method@Gtk.Widget.set_cursor] function to set cursors, instead of 1069setting the cursor on the underlying window directly. This is necessary 1070because most widgets don't have their own window anymore, turning any 1071such calls into global cursor changes. 1072 1073For creating standard cursors, `gdk_cursor_new_for_display()` has been removed, 1074you have to use cursor names instead of `GdkCursorType`. For creating custom cursors, 1075use [ctor@Gdk.Cursor.new_from_texture]. The ability to get cursor images has been removed. 1076 1077### Adapt to icon size API changes 1078 1079Instead of the existing extensible set of symbolic icon sizes, GTK now only 1080supports normal and large icons with the [enum@Gtk.IconSize] enumeration. The actual sizes 1081can be defined by themes via the CSS property -gtk-icon-size. 1082 1083GtkImage setters like [method@Gtk.Image.set_from_icon_name] no longer take a `GtkIconSize` 1084argument. You can use the separate [method@Gtk.Image.set_icon_size] setter if you need 1085to override the icon size. 1086 1087The :stock-size property of GtkCellRendererPixbuf has been renamed to 1088[property@Gtk.CellRendererPixbuf:icon-size]. 1089 1090### Adapt to changes in the GtkAssistant API 1091 1092The :has-padding property is gone, and `GtkAssistant` no longer adds padding 1093to pages. You can easily do that yourself. 1094 1095### Adapt to changes in the API of GtkEntry, GtkSearchEntry and GtkSpinButton 1096 1097The [iface@Gtk.Editable] interface has been made more useful, and the core functionality of 1098`GtkEntry` has been broken out as a [class@Gtk.Text] widget. 1099[class@Gtk.Entry], 1100[class@Gtk.SearchEntry], 1101[class@Gtk.SpinButton] and the new 1102[class@Gtk.PasswordEntry] now use a [class@Gtk.Text] widget internally 1103and implement [iface@Gtk.Editable]. In particular, this means that it is no longer 1104possible to use `GtkEntry` API such as `gtk_entry_grab_focus_without_selecting()` 1105on a search entry. 1106 1107Use `GtkEditable` API for editable functionality, and widget-specific APIs for 1108things that go beyond the common interface. For password entries, use 1109[class@Gtk.PasswordEntry]. As an example, `gtk_spin_button_set_max_width_chars()` 1110has been removed in favor of [method@Gtk.Editable.set_max_width_chars]. 1111 1112### Adapt to changes in GtkOverlay API 1113 1114The GtkOverlay :pass-through child property has been replaced by the 1115[property@Gtk.Widget:can-target] property. Note that they have the opposite sense: 1116pass-through == !can-target. 1117 1118### Use GtkFixed instead of GtkLayout 1119 1120Since `GtkScrolledWindow` can deal with widgets that do not implement 1121the `GtkScrollable` interface by automatically wrapping them into a 1122`GtkViewport`, `GtkLayout` is redundant, and has been removed in favor 1123of the existing [class@Gtk.Fixed] widget. 1124 1125### Adapt to search entry changes 1126 1127The way search entries are connected to global events has changed; 1128`gtk_search_entry_handle_event()` has been dropped and replaced by 1129[method@Gtk.SearchEntry.set_key_capture_widget] and 1130[method@Gtk.EventControllerKey.forward]. 1131 1132### Adapt to GtkScale changes 1133 1134The default value of `GtkScale:draw-value` has been changed to %FALSE. 1135If you want your scales to draw values, you will have to set this 1136property explicitly now. 1137 1138`gtk4-builder-tool` can help with this conversion, with the `--3to4` option 1139of the `simplify` command. 1140 1141### Stop using gtk_window_activate_default() 1142 1143The handling of default widgets has been changed, and activating 1144the default now works by calling [method@Gtk.Widget.activate_default] 1145on the widget that caused the activation. If you have a custom widget 1146that wants to override the default handling, you can provide an 1147implementation of the "default.activate" action in your widgets' action 1148groups. 1149 1150### Stop using gtk_widget_grab_default() 1151 1152The function `gtk_widget_grab_default()` has been removed. If you need 1153to mark a widget as default, use [method@Gtk.Window.set_default_widget] 1154directly. 1155 1156### Stop setting ::has-default and ::has-focus in .ui files 1157 1158The special handling for the :has-default and :has-focus properties 1159has been removed. If you want to define the initial focus or the 1160the default widget in a .ui file, set the [property@Gtk.Window:default-widget] or 1161[property@Gtk.Window:focus-widget] properties of the toplevel window. 1162 1163### Stop using the GtkWidget::display-changed signal 1164 1165To track the current display, use the [property@Gtk.Widget:root] property instead. 1166 1167### GtkPopover::modal has been renamed to autohide 1168 1169The modal property has been renamed to [property@Gtk.Popover:autohide]. 1170 1171`gtk-builder-tool` can assist with the rename in ui files. 1172 1173### gtk_widget_get_surface has been removed 1174 1175`gtk_widget_get_surface()` has been removed. 1176Use [method@Gtk.Native.get_surface] in combination with 1177[method@Gtk.Widget.get_native] instead. 1178 1179### gtk_widget_is_toplevel has been removed 1180 1181`gtk_widget_is_toplevel()` has been removed. 1182Use `GTK_IS_ROOT`, `GTK_IS_NATIVE` or `GTK_IS_WINDOW` 1183instead, as appropriate. 1184 1185### gtk_widget_get_toplevel has been removed 1186 1187`gtk_widget_get_toplevel()` has been removed. 1188Use [method@Gtk.Widget.get_root] or [method@Gtk.Widget.get_native] 1189instead, as appropriate. 1190 1191### GtkEntryBuffer ::deleted-text has changed 1192 1193To allow signal handlers to access the deleted text before it 1194has been deleted, the [signal@Gtk.EntryBuffer::deleted-text] signal 1195has changed from %G_SIGNAL_RUN_FIRST to %G_SIGNAL_RUN_LAST. The default 1196handler removes the text from the [class@Gtk.EntryBuffer]. 1197 1198To adapt existing code, use `g_signal_connect_after()` or 1199%G_CONNECT_AFTER when using `g_signal_connect_data()` or 1200`g_signal_connect_object()`. 1201 1202### GtkMenu, GtkMenuBar and GtkMenuItem are gone 1203 1204These widgets were heavily relying on X11-centric concepts such as 1205override-redirect windows and grabs, and were hard to adjust to other 1206windowing systems. 1207 1208Menus can already be replaced using GtkPopoverMenu in GTK 3. Additionally, 1209GTK 4 introduces GtkPopoverMenuBar to replace menubars. These new widgets 1210can only be constructed from menu models, so the porting effort involves 1211switching to menu models and actions. 1212 1213Tabular menus were rarely used and complicated the menu code, 1214so they have not been brought over to [class@Gtk.PopoverMenu]. 1215If you need complex layout in menu-like popups, consider directly using a 1216[class@Gtk.Popover] instead. 1217 1218Since menus are gone, `GtkMenuButton` also lost its ability to show menus, 1219and needs to be used with popovers in GTK 4. 1220 1221### GtkToolbar has been removed 1222 1223Toolbars were using outdated concepts such as requiring special toolitem 1224widgets. Toolbars should be replaced by using a `GtkBox` with regular widgets 1225instead and the "toolbar" style class. 1226 1227### GtkAspectFrame is no longer a frame 1228 1229`GtkAspectFrame` is no longer derived from `GtkFrame` and does not 1230place a label and frame around its child anymore. It still lets 1231you control the aspect ratio of its child. 1232 1233### Stop using custom tooltip windows 1234 1235Tooltips no longer use `GtkWindow`s in GTK 4, and it is no longer 1236possible to provide a custom window for tooltips. Replacing the content 1237of the tooltip with a custom widget is still possible, with 1238[method@Gtk.Tooltip.set_custom]. 1239 1240### Switch to the new Drag-and-Drop api 1241 1242The source-side Drag-and-Drop apis in GTK 4 have been changed to use an event 1243controller, [class@Gtk.DragSource]. Instead of calling `gtk_drag_source_set()` 1244and connecting to `GtkWidget` signals, you create a [class@Gtk.DragSource] object, 1245attach it to the widget with [method@Gtk.Widget.add_controller], and connect 1246to `GtkDragSource` signals. Instead of calling `gtk_drag_begin()` on a widget 1247to start a drag manually, call [func@Gdk.Drag.begin]. 1248The `::drag-data-get` signal has been replaced by the [signal@Gtk.DragSource::prepare] 1249signal, which returns a [class@Gdk.ContentProvider] for the drag operation. 1250 1251The destination-side Drag-and-Drop API in GTK 4 have also been changed 1252to use an event controller, [class@Gtk.DropTarget]. Instead of calling 1253`gtk_drag_dest_set()` and connecting to `GtkWidget` signals, you create 1254a [class@Gtk.DropTarget] object, attach it to the widget with 1255[method@Gtk.Widget.add_controller], and connect to `GtkDropTarget` signals. 1256The `::drag-motion` signal has been renamed to [signal@Gtk.DropTarget::accept], 1257and instead of `::drag-data-received`, you need to use async read methods on the 1258[class@Gdk.Drop] object, such as [method@Gdk.Drop.read_async] or 1259[method@Gdk.Drop.read_value_async]. 1260 1261### Adapt to GtkIconTheme API changes 1262 1263`gtk_icon_theme_lookup_icon()` returns a [class@Gtk.IconPaintable] object now, 1264instead of a `GtkIconInfo`. It always returns a paintable in the requested size, 1265and never fails. A number of no-longer-relevant lookup flags and API variants 1266have been removed. 1267 1268Note that while GTK 4 is moving towards [iface@Gdk.Paintable] as a primary API 1269for paintable content, it is meant to be a 'pure' content producer, therefore 1270a [class@Gtk.IconPaintable] for a symbolic icon will *not* get recolored depending 1271on the context it is rendered it. To properly render a symbolic icon that 1272is provided in the form of a `GtkIconPaintable` (this can be checked with 1273[method@Gtk.IconPaintable.is_symbolic]), you have to call 1274[method@Gtk.IconPaintable.get_icon_name] and set the icon name on a `GtkImage`. 1275 1276### Update to GtkFileChooser API changes 1277 1278`GtkFileChooser` moved to a GFile-based API. If you need to convert a path 1279or a URI, use `g_file_new_for_path()`, `g_file_new_for_commandline_arg()`, 1280or `g_file_new_for_uri()`; similarly, if you need to get a path, name or URI 1281from a `GFile`, use `g_file_get_path()`, `g_file_get_basename()` or `g_file_get_uri()`. 1282With the removal or path and URI-based functions, the "local-only" property 1283has been removed; GFile can be used to access non-local as well as local 1284resources. 1285 1286The `GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER` action has been removed. Use 1287%GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, instead. If a new folder is needed, 1288the user can create one. 1289 1290The "confirm-overwrite" signal, and the "do-overwrite-confirmation" 1291property have been removed from `GtkFileChooser`. The file chooser widgets 1292will automatically handle the confirmation of overwriting a file when 1293using `GTK_FILE_CHOOSER_ACTION_SAVE`. 1294 1295`GtkFileChooser` does not support a custom extra widget any more. If you 1296need to add extra widgets, use [method@Gtk.FileChooser.add_choice] instead. 1297 1298`GtkFileChooser` does not support a custom preview widget any more. 1299 1300### Stop using blocking dialog functions 1301 1302`GtkDialog`, `GtkNativeDialog`, and `GtkPrintOperation` removed their 1303blocking API using nested main loops. Nested main loops present 1304re-entrancy issues and other hard to debug issues when coupled 1305with other event sources (IPC, accessibility, network operations) 1306that are not under the toolkit or the application developer's 1307control. Additionally, "stop-the-world" functions do not fit 1308the event-driven programming model of GTK. 1309 1310You can replace calls to `gtk_dialog_run()` by specifying that the 1311`GtkDialog` must be modal using [method@Gtk.Window.set_modal] or the 1312%GTK_DIALOG_MODAL flag, and connecting to the [signal@Gtk.Dialog::response] 1313signal. 1314 1315### Stop using GtkBuildable API 1316 1317All the `GtkBuildable` API was made private, except for the 1318getter function to retrieve the buildable ID. If you are 1319using `gtk_buildable_get_name()` you should replace it with 1320[method@Gtk.Buildable.get_buildable_id]. 1321 1322### Adapt to GtkAboutDialog API changes 1323 1324`GtkAboutDialog` now directly derives from `GtkWindow`, the `GtkDialog` 1325API can no longer be used on it. 1326 1327### Adapt to GtkTreeView and GtkIconView tooltip context changes 1328 1329The getter functions for retrieving the data from `GtkTreeView` 1330and `GtkIconView` inside a `GtkWidget::query-tooltip` signal do not take the 1331pointer coordinates as inout arguments any more, but as normal in ones. 1332 1333See: [method@Gtk.TreeView.get_tooltip_context], [method@Gtk.IconView.get_tooltip_context] 1334 1335### Adapt to GtkPopover changes 1336 1337In GTK 3, a `GtkPopover` could be attached to any widget, using the `relative-to` 1338property. This is no longer possible in GTK 4. The parent widget has to be aware 1339of its popover children, and manage their size allocation. Therefore, only widgets 1340with dedicated popover support can have them, such as [class@Gtk.MenuButton] or 1341[class@Gtk.PopoverMenuBar]. 1342 1343If you want to make a custom widget that has an attached popover, you need to call 1344[method@Gtk.Popover.present] in your [vfunc@Gtk.Widget.size_allocate] vfunc, in order 1345to update the positioning of the popover. 1346 1347### Stop using GtkFileChooserButton 1348 1349The `GtkFileChooserButton` widget was removed, due to its shortcomings in 1350the user interaction. You can replace it with a simple `GtkButton` that 1351shows a [class@Gtk.FileChooserNative] dialog when clicked; once the file selection 1352has completed, you can update the label of the `GtkButton` with the selected 1353file. 1354 1355### Adapt to changed GtkSettings properties 1356 1357In GTK 3 the [property@Gtk.Settings:gtk-cursor-aspect-ratio] property of 1358`GtkSettings` was a `float`. In GTK 4 this has been changed to a `double`. 1359 1360## Changes to consider after the switch 1361 1362GTK 4 has a number of new features that you may want to take 1363advantage of once the dust has settled over the initial migration. 1364 1365### Consider porting to the new list widgets 1366 1367In GTK 2 and 3, `GtkTreeModel` and `GtkCellRenderer` and widgets using 1368these were the primary way of displaying data and lists. GTK 4 brings 1369a new family of widgets for this purpose that uses list models instead 1370of tree models, and widgets instead of cell renderers. 1371 1372To learn more about the new list widgets, you can read the [List Widget 1373Overview](#ListWidget). 1374 1375