sizable news

For the upcoming GTK 4.6, we have overhauled a lot of the sizing infrastructure to make widgets fit even tighter and to make sure our sizing infrastructure actually does what it says.

halign/valign

When using the GtkWidget::halign or GtkWidget::valign properties, GTK 4.4 would look at the default size of the widget and then place the widget accordingly. This leaves a lot of extra space when one of the values was set to fill. In GTK 4.6, GTK will measure the size of the other dimension relative to the filled dimension. This makes the widget thinner but avoids extra space.

A centered label with empty space in GTK 4.4
A centered label with empty space in GTK 4.4

A centered label with no extra space in GTK 4.6
A centered label with no extra space in GTK 4.6

What if you like the old behavior?

If you do not use fill in either direction, the behavior will be as before. So update the other dimension to not be the default fill and you should get the old behavior back.

GtkBox

GtkBox has learned to assign size to widgets as needed. In GTK 4.4, size was always distributed equally among children that had the same default size. GTK 4.6 will query the children for their actual size to decide which child to distribute how much of the extra size to.

You can see this in the example, where the box was given enough space for 3, 4, 5 or 6 lines of text.

A left-aligned box in GTK 4.4
A left-aligned box in GTK 4.6

GtkLabel

As you could see above, GtkLabel also learned to properly wrap to any given number of lines. This allows labels to take a lot less widths as before, so they no longer take up empty space when they can just line-break.

xalign and halign

It’s worth pointing out that in a lot of cases applications used GtkWidget::halign = GTK_HALIGN_START; when they should have used GtkLabel::xalign = 0.0;. The first aligns the widget as far to the left as possible while the seconds aligns the text inside the assigned space to the left. So if your widgets suddenly look glued to the left edge, you might want to look into that.

GtkWindow

GtkWindow has learned how to adapt minimum size to the aspect ratio. So you can now resize your windows any way you like and they will never get too small, but they will always get as small as possible, no matter if you want to make them flat and wide or thin and high.

a new warning

While doing this work, we figured out that a few widgets do not conform to measuring requirements and added a new warning. So if you see something like:
Gtk-CRITICAL **: 00:48:33.319: gtk_widget_measure: assertion 'for_size >= minimum opposite size' failed: 23 >= 42
It means you have a widget that reports an minimum size for size -1 that is larger than the minimum size it reports for a different size, and that should never happen. You can use GTK_DEBUG=size-request and redirect to a file to find the offending widget. We also added code to work around any problems that warning, but it should be fixed nonetheless. After all, if a widget reports a wrong size, it’s likely it’s doing something wrong.

GTK 4.0

2020 has been a very long year. What better way to end it than with a major release!  Today, we released GTK 4.0.

GTK 4.0 is the result of a lot of hard work by a small team of dedicated developers. We will have a separate post to go over the statistics, but the short summary is that since the 3.89.1 release in November 2016, we’ve added over 18000 commits and made more than 20 development releases.

Congratulations and a big thank you to everybody who has participated in this effort, and in particular to Benjamin, Emmanuele, Timm, Carlos, Jonas and Christian!

What’s new

It is impossible to summarize 4 years of development in a single post. We’ve written detailed articles about many of the new things in this release over the past year: Data transfers, Event controllers, Layout managers, Render nodes, Media playback, Scalable lists, Shaders, Accessibility.  Here are some of the highlights, in visual form:

Media playback:

Drag-and-Drop:

Layout managers and transforms:

Scalable lists and grids:

Shaders:

What’s old

GTK 4 is now stable, and we consider it ready for consumption. That does not mean GTK 3 is dead – we will continue to support and update it for the foreseeable future (the latest release, 3.24.24, quietly went out a few days ago). It does mean, however, that GTK 2 has reached the end of its life. We will do one final 2.x release in the coming days, and we encourage everybody to port their GTK 2 applications to GTK 3 or 4.

How to get it

The source tarballs are available in the usual place. Binary packages should appear in major distributions soon.

The GNOME 40 release will have a number of applications ported to GTK 4.  If you want to try GTK 4.0 today, you can use the nightly flatpak builds of gtk4-demo and gtk4-widget-factory:

$ flatpak install https://nightly.gnome.org/repo/appstream/org.gtk.Demo4.flatpakref
$ flatpak run org.gtk.Demo4

If you are itching to port your application to GTK 4, our migration guide is available as part of the documentation.

How to support GTK

GTK could not be developed without the many volunteers who contribute bug reports, patches, translations or ideas. Thanks to all of you. We are also grateful to the GNOME foundation for supporting GTK with development resources, infrastructure, and travel assistance.

Donating to the GNOME foundation is a good way to support future GTK development.

What comes next

We are very thankful for all the early testers that have provided us with bug reports and feedback, which made this release much better. But we fully expect that there will be a quick 4.0.1 release to fix up the oversights and gotchas that only come to light after a .0 release.

Now that we have a 4.0 release, we need to bring along the library ecosystem to enable applications to use it. vte, webkit and gtksourceview are some of the most notable libraries that tend to be used together with GTK. We expect GTK 4 ports of these to be available soon.

If more serious issues show up, we will do a 4.2 release in time for GNOME 40, otherwise we might wait until the summer for that.

What the future will bring beyond GTK 4 remains to be seen. We have some fun things in the pipeline, but we would also like to hear what features application developers would like to see in GTK. Tell us!

A celebration

We will celebrate the 4.0 release with an (online) gathering this coming Friday. Feel free to drop by!

Drag-and-drop in lists

I’ve recently had an occasion to implement reordering of a GtkListBox via drag-and-drop (DND). It was not that complicated. Since I haven’t seen drag-and-drop used much with list boxes, here is a quick summary of what is needed to get the basics working.

Setting up the drag source

There are two ways to make a GTK+ widget a drag source (i.e. a place where clicking and dragging will initiate a DND operation). You can decide dynamically to initiate a drag by calling gtk_drag_begin(). But we go for the simpler approach here: we just declare statically that our list rows should be drag sources, and let GTK+ handle all the details:

handle = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (handle),
        gtk_image_new_from_icon_name ("open-menu-symbolic", 1));
gtk_drag_source_set (handle,
        GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);

Note that I choose to create a visible drag handle here instead of allowing drags to start anywhere on the row. It looks like this:

The entries tell GTK+ what data we want to offer via drags from this source. In our case, we will not offer a standard mime type like text/plain, but instead make up our own, private type, and also hint GTK+ that we don’t want to support drags to other applications:

static GtkTargetEntry entries[] = {
   { "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
};

A little gotcha here is that the widget you set up as drag source must have a GdkWindow. A GtkButton or a GtkEventBox (as in this example) will work. GTK4 will offer a different API to create drag sources that avoids the need for a window.

With this code in place, you can already drag your rows, but so far, there’s nowhere to drop them. Lets fix that.

Accepting drops

In contrast to drags, where we created a visible drag handle to give users a hint that drag-and-drop is supported, we want to just accept drops anywhere in the list. The easiest way to do that is to just make each row a drop target (i.e. a place that will potentially accept drops).

gtk_drag_dest_set (row,
        GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);

The entries are the same that we discussed above. GTK_DEST_DEFAULT_ALL tells GTK+ to handle all aspects of the DND operation for us, so we can keep this example simple.

Now we can start a drag on the handle, and we can drop it on some other row. But nothing happens after that. We need to do a little bit of extra work to make the reordering happen. Lets do that next.

Transferring the data

Drag-and-drop is often used to transfer data between applications. GTK+ uses a data holder object called GtkSelectionData for this. To send and receive data, we need to connect to signals on both the source and the target side:

g_signal_connect (handle, "drag-data-get",
        G_CALLBACK (drag_data_get), NULL);
g_signal_connect (row, "drag-data-received",
        G_CALLBACK (drag_data_received), NULL);

On the source side, the drag-data-get signal is emitted when GTK+ needs the data to send it to the drop target. In our case, the function will just put a pointer to the source widget in the selection data:

gtk_selection_data_set (selection_data,
        gdk_atom_intern_static_string ("GTK_LIST_BOX_ROW"),
        32,
        (const guchar *)&widget,
        sizeof (gpointer));

On the target side, drag-data-received is emitted on the drop target when GTK+ passes the data it received on to the application. In our case, we will pull the pointer out of the selection data, and reorder the row.

handle = *(gpointer*)gtk_selection_data_get_data (selection_data);
source = gtk_widget_get_ancestor (handle, GTK_TYPE_LIST_BOX_ROW);

if (source == target)
  return;

source_list = gtk_widget_get_parent (source);
target_list = gtk_widget_get_parent (target);
position = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (target));

g_object_ref (source);
gtk_container_remove (GTK_CONTAINER (source_list), source);
gtk_list_box_insert (GTK_LIST_BOX (target_list), source, position);
g_object_unref (source);

The only trick here is that we need to take a reference on the widget before removing it from its parent container, to prevent it from getting finalized.

And with this, we have reorderable rows. Yay!

As a final step, lets make it look good.

A nice drag icon

So far, during the drag, you just see just the cursor, which is not very helpful and not very pretty. The expected behavior is to drag a visual representation of the row.

To make that happen, we connect to the drag-begin signal on the drag source:

g_signal_connect (handle, "drag-begin",
        G_CALLBACK (drag_begin), NULL);

…and do some extra work to create a nice ‘drag icon’:

row = gtk_widget_get_ancestor (widget, GTK_TYPE_LIST_BOX_ROW);
gtk_widget_get_allocation (row, &alloc);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                      alloc.width, alloc.height);
cr = cairo_create (surface);
gtk_widget_draw (row, cr);

gtk_drag_set_icon_surface (context, surface);

cairo_destroy (cr);
cairo_surface_destroy (surface);

This looks more complicated than it is – we are creating a cairo surface of the right size, render the row widget to it (the signal is emitted on the handle, so we have to find the row as an ancestor).

Unfortunately, this does not yet yield a perfect result, since list box rows generally don’t render a background or frame. To work around that, we can temporarily add a custom style class to the row’s style context, and use some custom CSS to ensure we get a background and frame:

context = gtk_widget_get_style_context (row);
gtk_style_context_add_class (context, "drag-icon");
gtk_widget_draw (row, cr);
gtk_style_context_remove_class (context, "drag-icon")

As an extra refinement, we can set an offset on the surface, to prevent a visual ‘jump’ at the beginning of the drag, by placing this code before the gtk_drag_set_icon_surface() call:

gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
cairo_surface_set_device_offset (surface, -x, -y);


Voila!

Next steps

This article just shows the simplest possible setup for row reordering by drag-and-drop. Many refinements are possible, some easy and some not so easy.

An obvious enhancement is to allow dragging between different lists in the same application. This is just a matter of being careful about the handling of the list widgets in the drag_data_received() call, and the code I have shown here should already work for this.

Another refinement would be to drop the row before or after the target row, depending on which edge is closer. Together with this, you probably want to modify the drop target highlighing to indicate the edge where the drop will happen. This could be done in different ways, but all of them will require listening to drag-motion events and juggling event coordinates, which is not something I wanted to get into here.

Finally, scrolling the list during the drag. This is important for long lists, if you want to drag a row from the top to bottom – if the list doesn’t scroll, you have to do this in page increments, which is just too cumbersome. Implementing this may be easiest by moving the drag target to be the list widget itself, instead of the individual rows.

References

The GTK+ Inspector

Many GTK+ users and developers have already heard of the GTK+ Inspector, a tool to inspect, modify and understand GTK+ applications. The Inspector is extremely powerful, and allows theme designers to test CSS changes on-the-fly and magnify widgets to see even the smallest details, lets developers check the application widgets and their properties, and lets users to play (and eventually break) applications.

In this article, we’ll explore the GTK+ Inspector and show what can you do with it.

Prelude

Since the Inspector is a debugging tool, it is disabled by default. To start using the Inspector, you first have to enable it. You can easily do that with DConf Editor:

Enabling the Gtk+ Inspector with DConf Editor
Enabling the GTK+ Inspector with DConf Editor

Alternatively, you can use the terminal to enable it. To do that, run the following command:

$ gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true

Done! The Inspector is now enabled!

Opening the Inspector

Now that the Inspector is enabled, you want to run it. The Inspector is always associated with an application. Let’s use GNOME Calendar for example:

GNOME Calendar
The GNOME Calendar application

There are multiple ways to bring up the Inspector. You can open it while using the application, by typing <Ctrl> + <Shift> + D (or <Ctrl> + <Shift> + I to automatically select the widget under the mouse pointer). Alternatively, you can launch the application from the terminal with the environment variable GTK_DEBUG=interactive.

The Inspector will open, and you’ll see the following window:

Inspector on Calendar
The Inspector window over GNOME Calendar

And that’s all you have to do. Now let’s explore the various functions that the Inspector has to offer.

Exploring the Inspector

At first, the overwhelming number of buttons and tabs can confuse those who are not well-versed in the art of inspecting applications. A quick explanation of the tabs, in order:

  • Objects: exposes the widgets of the application, and allows editing properties and seeing detailed information about each widget. Explained below.
  • Statistics: shows miscellaneous statistics of the application. You need to run the application with GOBJECT_DEBUG=instance-count.
  • Resources: shows the various resources that are embedded in the application binary, such as custom icons or GtkBuilder files, among others.
  • CSS: allows testing CSS live. Explained below.
  • Visual: controls some visual aspects of the application, such as the text direction, dark/light variant, the theme, the scaling factor, etc.
  • General: shows miscellaneous information about the GTK+ application (and the session it is running in).

Let’s dissect the main window of the GTK+ Inspector:

Inspector window
The main Inspector window

Those 4 annotated sections of the Inspector are the most commonly used ones. Theme designers will want to check (3) and (4), while developers usually use (1) and (2).

Inspecting widgets

For developers, the Inspector shows its usefulness by letting you change the properties of any widget on the screen. Let’s start by clicking the first button and selecting a widget using the mouse cursor:

Selecting widgets
Selecting a widget with the Inspector

You can now easily change the properties of that widget by browsing the Objects > Properties tab. You can change, for example, the visibility of a widget, the text of a label, and much more!

Editing a widget property
Editing a widget property

Now that you know how to inspect a GTK+ application, play around and explore how many applications are organized. Change the widgets’ properties and see what happens. Most of the times, this is safe and won’t break your GNOME session, or freeze your computer!

Editing CSS

The Inspector is a powerful tool for designers too. One of the greatest features it has is the live CSS editor. Let’s start by going to the CSS tab:

CSS Editor
The Inspector CSS Editor view

Let’s play with CSS! Paste the following CSS code and see what happens:

window stack {
    background-color: orange;
}

Whoa! The window became alien! That CSS code changes the background color of any GtkStack widget inside a GtkWindow. If you want to learn more about CSS selectors and how GTK+ is using CSS for theming, there are some useful links at the end of this article.

The cautious reader may ask: what is the hierarchy of CSS elements? How can I see which CSS elements are available?

Fear not! GTK+ Inspector allows you to easily check the CSS hierarchy at the Objects > CSS Nodes tab.

CSS Nodes
The CSS Nodes tab

GTK+ widgets have documented CSS names. You can browse the GTK+ documentation to see how widgets are organized, and how you can use CSS to control the various aspects of the widgets.

Not sure if your CSS changes are perfect? Let’s magnify the widget to make sure we don’t miss any detail:

Zooming widget using Magnifier
Zooming a widget using the Magnifier tab

Looking good? Join -design and share your awsome CSS snipplets with the community!

Wrapping up

While this article explores some of the biggest aspects of the GTK+ Inspector, this is by far not an exhaustive list of all the features of the Inspector. After reading this article, however, you’ll hopefully be able to open the Inspector and explore more of its awesome power on your own.

Doubts? Comments? Suggestions? Stop by and leave a comment, join #gtk+ channel at the GNOME IRC network and let us know what you think!

Useful Links

Future of relative window positioning

With emerging display server technologies, toolkits sometimes need to adapt how they implement the features they provide. One set of features that needs adaptation is how GTK+ positions popup windows such as menus, popovers and tooltips, so that they will be placed within the work area of the monitor.

In the old days, when GTK+ wanted to position a menu, it would first look up the global position of the parent window of the menu. It would then look up the work areas of all the monitors connected. With the given work areas, the global position of the parent window, and the intended menu position relative to the parent window it wanted to place the menu, GTK+ would use a clever algorithm calculating a reasonable position for the menu to be placed so that it would be visible to the user. For example, if the File menu doesn’t have enough space to popup below the parent menu item, then GTK+ would re-position it above the parent menu item instead.

popup-flip

For various reasons the concept of “global window positions” has been removed from clients in these new display server technologies, meaning we cannot use our clever algorithm in GTK+ any more.

But we still want to make our menus, tooltips, popovers, etc. fully visible to the user expecting to interact with them, so how can we ensure this without knowing anything about where our windows are positioned?

To tackle this in GTK+, we had to solve a number of problems.

  • The positioning logic needs to be moved to GDK, while still allowing GTK+ to affect how the menu positioning behaves should the initially intended position end up outside of the work area.
  • Different GDK backends might do things differently.
  • Some types of windows need to know the position it ended up at, so they can adapt how they draw them self.
  • Some windows simply want to take up as much space as they may (for example a menu with far too many choices should not be taller than the screen).

Last year, William Hua and I started working on bringing GTK+ into the bright future of global position-less menu windows. After having come up with a set of patches doing just that, the discussion of how such an API would actually look like started. After 200-300 comments, we decided we should probably discuss this in person.

Enter GTK2016 in Toronto!

At the hackfest, we got the chance to sit down with a whiteboard in front of us and go through the different use cases, the problems that needed to be solved, how backends would work, and eventually we came up with an API.

william-draws-whiteboard(photo credit: Allison Lortie)

The API we came up with looks as this:

From the GDK side we introduce a new function (so far without any API stability promises; it’s intended to be used only by GTK+ so far) gdk_window_move_to_rect () which takes a set of arguments describing how the application wants its window to be placed in relation to some parent surface. It takes

  • a transient-for window

The parent window it is to be placed relative to an anchor rectangle on the parent window a popup or a menu will often want to be placed in relation to a rectangle on the parent, for example a right-click context menu should expand in some direction from the pixel the pointer was located at when clicking, or a file menu should be placed either below or above the file menu item rectangle on the parent window.

  • a rectangle anchor gravity

Different popup menus might want to open in a certain direction. For example a vertical menu might want to open to the right, while a horizontal menu might want to open downwards.

  • a window anchor gravity

Different popup menus might want to be aligned to the anchor rectangle of the parent anchor rectangle differently. For example, while a combo box might want to expand in a certain direction, it will want to cover the rectangle it expanded from.

  • an anchor hint

Different popup menus want to adjust their positions differently; some will want to expand in different directions from the parent anchor rectangle, some will want to just be slid into visibility, some will want to be resized, while some will want some combination of all the three.

  • an rectangle anchor offset

The offset is simply a nudge factor for a common use case where a popup menu will offset its position relative to an anchor.

By having GTK+ come up with a declarative description of how it wants its menu to be positioned, we allow GDK to implement the actual positioning differently depending on how the display server system is designed. On Mir, a MirSurfaceSpec is created, while on Wayland an xdg_positioner object is created. On X11, Windows and Mac OS X, the backends can use the available global positions as well as monitor work areas and calculate an optimal position just as before.

Application developers are, however, not expected to use this API directly yet. Normally what is wanted is to create a menu, a popover, a combo box, and for this we have introduced a set of parameters and helper functions to make this very convenient. The API consists of a few new properties:

  • GtkMenu:anchor-hints – the positioning strategy.
  • GtkMenu:rect-anchor-dx – horizontal offset to shift window.
  • GtkMenu:rect-anchor-dy – vertical offset to shift window.
  • GtkMenu:menu-type-hint – a window type – this is still needed so that the X11 backend can let the window manager know what type of popup window is being mapped.

and a few more functions:

  • gtk_menu_popup_at_rect () – given the parameters set, popup a menu relative to a given rectangle on a parent window.
  • gtk_menu_popup_at_widget () – given the parameters set, popup a menu relative to a given widget on a parent window.
  • gtk_menu_popup_at_pointer () – given the parameters set, popup a menu relative to where the user just clicked.

With these functions, developers of custom widgets can now position popup menus in a portable manner. So far, GTK+’s own popup menus have already been ported to use these new functions. There is already a basic proof-of-concept in the Mir backend, and a Wayland implementation is in progress.

Head over to the bug to see all the details of how to place your menus in the future.

gnome-sponsored-badge-shadow

Controlling content sizes in GtkScrolledWindow

The GtkScrolledWindow widget is an old friend of Gtk+ application developers; its purpose is to allow big widgets to fit into small spaces through the use of scroll bars.

GtkScrolledWindow Example
A vertical GtkScrolledWindow in action

Since Gtk+ 3.0, GtkScrolledWindow has the ability to set the minimum content sizes (both width and height) through the GtkScrolledWindow:min-content-width and GtkScrolledWindow:min-content-height properties, and their related functions.

Starting from the next stable release, Gtk+ will also provide the maximum size counterparts of those properties.

What Do They Do?

The minimum sizes properties, as the name implies, define the minimum size, be it width or height, that the scrollable area will have – even if its child does not completely fill the available space.

scrolledwindow min-content-height
The scrolled window is allocated even when child widgets don’t fill the available space.

The maximum content sizes, on the other hand, define how much the scrollable area is allowed to grow before its contents will starts scrolling.

Lets see it in action:

scroll animation
Example demonstrating minimum and maximum content sizes. The scrolled window is never smaller than 110px, and never taller than 250px.
Where & How to Use Them

You want to use the new properties whenever you want to limit the size of the scrollable area. For example, GtkPopover always shrinks its children widgets to their minimum sizes. The following section exemplifies how to make the content grow to at most 300px, both width and height wise:

<template>
  <object class="GtkPopover">
    <child>
      <object class="GtkScrolledWindow">
        <property name="visible">True</property>
        <property name="max-content-width">300</property>
        <property name="max-content-height">300</property>
      </object>
    </child>
  </object>
</template>

Alternatively, you can call gtk_scrolled_window_set_max_content_width() and gtk_scrolled_window_set_max_content_height() if you want to achieve the same thing programmatically.

GTK+ 3.0 Released

GTK+ 3.0 is a major new version of GTK+, containing far too many changes to list them all here.

The major highlights include:

  • Cairo drawing throughout. GDK no longer wraps the antiquated X11 drawing API; we’ve made a clean break and exclusively rely on cairo for all our drawing needs now. This has also enabled us to remove several other X11-centric concepts such as GCs, colormaps and pixmaps.
  • Modern input device handling. The input device handling in GDK has long been a sadly neglected area. This has changed; with 3.0, GTK+ steps into the modern world of XI2 with full support for multiple pointers, keyboards and other gizmos.
  • A new theming API which sports a familiar CSS syntax for theme configuration and other improvements such as animated state transitions.
  • More flexible geometry management, with support for height-for-width, for both widgets and cell renderers.
  • Multiple backend support for GDK. With GTK+ 2.x, you had to recompile your application to have it work with a different GDK backend. In GTK+ 3, multiple GDK backends can be built into a single library and selected at runtime.
  • Easy application support. With the integration of D-Bus support in GIO, we could finally add a GtkApplication class that handles a lot of the platform integration aspects of writing an application, such as keeping track of open Windows, ensuring uniqueness, exporting actions, etc.
  • Of course, there’s some new widgets as well, such as a switch and an application chooser.

GTK+ is the work of hundreds of contributors, far too many to list them all here. But I want to take the time to thank some people who contributed in a major way:

  • Carlos Garnacho (Lanedo), for his work on XI2 support and the new theme system
  • Benjamin Otte (Red Hat), for his work on GDK and cairo drawing
  • Tristan Van Berkom (Openismus), for his work on geometry management
  • Colin Walters (Red Hat), for his work on GtkApplication
  • Ryan Lortie (Codethink), for his work on dconf, GSettings and GtkApplication
  • Javier Jardón, for tireless code, build and documentation cleanup

GTK+ 2.18 stable release

GTK+ 2.18 adds new functionality while maintaining source and binary compatibility with GTK+ 2.16. Highlights of new features and improvements in GTK+ 2.18 are:

GtkInfoBar
A new widget to show a transient ‘message area’ inside a content pane. The API is similar to GtkDialog and supports theming for different message types (warnings, errors, etc)

GtkBuilder

  • Scale marks can be specified in builder markup
  • GtkAssistant action widgets can be added in builder markup

GtkLabel
GtkLabel can show embedded URLs, much like SexyUrlLabe

GtkEntry
GtkEntry has been refactored to follow the model-view pattern, with GtkEntryBuffer as model. One intended use case for this is to support ‘secure memory’ for password entries

File chooser

  • Backup files are hidden by default
  • GTK+ remembers the sorting state of the file list
  • File sizes are shown by default
  • The ‘Create Folder’ button can be disabled with the the ::create-folders property

Printing support

  • GTK+ supports authentication against CUPS servers
  • A backend for the PAPI printing system has been added
  • The file and lpr backends can print multiple pages per sheet
  • The file backend can produce svg files
  • GTK+ supports printing an application-defined ‘selection’ in addition to the usual page ranges
  • The print dialog can optinally include the page setup controls, avoiding the need for a separate page setup dialog in many situations

Theming support

  • The bullet character used in invisible entries can be set by themes with the ::invisible-char style property
  • The file chooser can show different icons for xdg user dirs. The icon names are folder-documents, folder-download, folder-music, folder-pictures, folder-publicshare, folder-templates and folder-video
  • The GtkInfoBar uses symbolic colors for theming its background color depending on the message type. The color names are info_fg_color, info_bg_color, warning_fg_color”, warning_bg_color, etc.

GDK changes
GDK has been rewritten to use ‘client-side windows’. This means that GDK maintains its own window hierarchy and only uses X windows where it is necessary or explicitly requested. Some of the benefits of this change are

  • Reduced flicker
  • The ability to do transformed and animated rendering of widgets
  • Easier embedding of GTK+ widgets, e.g. into Clutter scene graphs
  • See gdk-demo for some simple examples of client-side windows in action. See the documentation for information about possible problems when moving to client-side windows.

For more details and lists of fixed bugs, see the
announcements for the 2.17.x development releases: 2.17.0, 2.17.1, 2.17.2, 2.17.3, 2.17.4, 2.17.5, 2.17.6, 2.17.8, 2.17.9, 2.17.10, 2.17.11

GTK+ 2.17.8 unstable release

This is a development release leading up to GTK+ 2.18.

Overview of Changes from GTK+ 2.17.7

  • Client-side windows
    • – various fixes to expose handlings
    • fix memory leaks
  • Minor API additions

    • New setter as part of the GSEAL effort: gtk_widget_set_allocation

11 bugs fixed in this release!

GTK 2.17.6 unstable release

This is a development release leading up to GTK+ 2.18.

Overview of Changes from GTK+ 2.17.5

  • Client-side windows:
    • Several optimizations, such as client-side tracking of viewable windows
    • Clipping for drawing pixbufs on windows has been fixed
    • Rendering to large subwindows has been fixed
  • Changes that are relevant for translators:
    • Markup has been removed from several strings

12 bugs fixed in this release!

See the original announcement for more info and downloads.