textures and paintables

With GTK4, we’ve been trying to find better solution for image data. In GTK3 the objects we used for this were pixbufs and Cairo surfaces. But they don’t fit the bill anymore, so now we have GdkTexture and GdkPaintable.


GdkTexture is the replacement for GdkPixbuf. Why is it better?
For a start, it is a lot simpler. The API looks like this:

int gdk_texture_get_width (GdkTexture *texture);
int gdk_texture_get_height (GdkTexture *texture);

void gdk_texture_download (GdkTexture *texture,
                           guchar     *data,
                           gsize       stride);

So it is a 2D pixel array and if you want to, you can download the pixels. It is also guaranteed immutable, so the pixels will never change. Lots of constructors exist to create textures from files, resources, data or pixbufs.

But the biggest difference between textures and pixbufs is that they don’t expose the memory that they use to store the pixels. In fact, before gdk_texture_download() is called, that data doesn’t even need to exist.
And this is used in the GL texture. The GtkGLArea widget for example uses this method to pass data around. GStreamer is expected to pass video in the form of GL textures, too.


But sometimes, you have something more complex than an immutable bunch of pixels. For example you could have an animated GIF or a scalable SVG. That’s where GdkPaintable comes in.
In abstract terms, GdkPaintable is an interface for objects that know how to render themselves at any size. Inspired by CSS images, they can optionally provide intrinsic sizing information that GTK widgets can use to place them.
So the core of the GdkPaintable interface are the function make the paintable render itself and the 3 functions that provide sizing information:

void gdk_paintable_snapshot (GdkPaintable *paintable,
                             GdkSnapshot  *snapshot,
                             double        width,
                             double        height);

int gdk_paintable_get_intrinsic_width (GdkPaintable *paintable);
int gdk_paintable_get_intrinsic_height (GdkPaintable *paintable);
int gdk_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable);

On top of that, the paintable can emit the “invalidate-contents” and “invalidate-size” signals when its contents or size changes.

To make this more concrete, let’s take a scalable SVG as an example: The paintable implementation would return no intrinsic size (the return value 0 for those sizing function achieves that) and whenever it is drawn, it would draw itself pixel-exact at the given size.
Or take the example of the animated GIF: It would provide its pixel size as its intrinsic size and draw the current frame of the animation scaled to the given size. And whenever the next frame of the animation should be displayed, it would emit the “invalidate-size” signal.
And last but not least, GdkTexture implements this interface.

We’re currently in the process of changing all the code that in GTK3 accepted GdkPixbuf to now accept GdkPaintable. The GtkImage widget of course has been changed already, as have the drag’n’drop icons or GtkAboutDialog. Experimental patches exist to let applications provide paintables to the GTK CSS engine.

And if you now put all this information together about GStreamer potentially providing textures backed by GL images and creating paintables that do animations that can then be uploaded to CSS, you can maybe see where this is going

GTK+ 2.15.3 unstable release

This is the third development release leading up to GTK+ 2.16.
8 bugs fixed in this release!

  • General:
    • Keyboard shortcut handling has been changed, to help with a longstanding complaint about the way GTK+ handles multiple layouts. GTK+ now only uses keys from groups other than the current group if they are not present in the current group. Feedback on this change is appreciated.

Read the original announcement for more info and downloads.

GLib 2.19.6 unstable release

This is the sixth development release leading up to GLib 2.20.
7 bugs fixed in this release!

  • General
    • New format macro to print goffset data: G_OFFSET_FORMAT
  • GIO:
    • Add a GFilter{Input,Output}Stream::close-base-stream properties which determine whether the base stream will be closed when the filter stream is finalized.
    • g_data_input_stream_read_line and …_read_until have asynchronous variants now.

Read the original announcement for more info and downloads.

GTK+ 2.15.2 unstable release

This is the second development release leading up to GTK+ 2.16.
4 bugs fixed in this release!

  • GtkAction:
    • Make toolitems pick up icon names from actions
    • Draw proxies of radio actions properly
    • Make menu proxies of recent actions work
    • Avoid accidental activations when changing actions on proxies
    • Make derived button classes work as proxies
  • Input methods
    • Avoid an assertion due to early use of input methods
  • GtkScale
    • Avoid a segfault in the marker drawing code
  • GtkImageMenuItem
    • Add a property to override the show-menu-images setting

Read the original announcement for more info and downloads.

GTK+ 2.15.1 unstable release

This is the first development release leading up to GTK+ 2.16.
35 bugs fixed in this release!

  • GtkFileChooser:
    • Remember the file chooser’s size across invocations
    • Handle uris that are entered in the entry
    • Improve autocompletion, in particular for uris
  • GtkEntry:
    • New property “im-module” for selecting input methods per-widget
    • New icon-related API got renamed for consistency
    • Added properties and setters for icon tooltips
  • GtkTextView:
    • New property “im-module” for selecting input methods per-widget
    • New signal “paste-done” to allow better handling of async pasting
  • GtkScale:
    • New api to add annotated marks: gtk_scale_add_mark.
  • GtkAction:
    • Rework the way actions and proxies interact, to make the interaction less ad hoc, more extensible, and better suited for support in GUI builders like glade. To be used as a proxy, a widget must now implement the GtkActivatable interface, and GtkActivatable implementations are responsible for syncing their appearance with the action and for activating the action. All the widgets that are commonly used as proxies implement GtkActivatable now. This is a big change, and it is not unlikely to break some current users of GtkAction, so feedback about problems caused by this is appreciated.
    • Add a “gicon” property to specify the icon with a GIcon
  • GDK:
    • On X11, GDK now caches cursors to avoid cursor theming overhead
    • New cursor type for blank cursors: GDK_BLANK_CURSOR
  • New deprecations:
    • gtk_scale_Button_get_orientation()
    • gtk_scale_button_set_orientation()
    • gtk_action_connect_proxy()
    • gtk_action_disconnect_proxy()
    • gtk_widget_get_action()
    • gtk_action_block_activate_from()
    • gtk_action_unblock_activate_from()
    • direct access to “gtk-action” object data
  • Changes that are relevant for translators:
    • Navigation and Media stock labels have separate message contexts now
    • The caps lock warning string has been changed

Read the original announcement for more info and downloads.

GTK+ 2.15.0 unstable release

This is the first development release leading up to GTK+ 2.16.

Overview of changes between 2.14.x and 2.15.0:

  • GtkFileChooser
    • Optionally shows file sizes
    • Mounts volumes when necessary
    • Picks better mime icons
  • GtkEntry
    • Can show icons at either side of the entry, which can be made clickable, drag sources, etc
    • Can show progress information
    • Picks the best available placeholder character for invisible entries unless it is explicitly set. See the invisible-char-set property
    • Input methods work again in invisible entries
    • Invisible entries can optionally display a caps-lock warning. This can be turned off with the caps-lock-warning property
  • GtkStatusIcon
  • GtkLinkButton
    • Respects user-defined tooltips
    • Has a default url hook
  • GtkBuilder
    • Can construct menus
    • Can associate accel groups with windows
    • Child properties can now be translatable, e.g. GtkAssistant::page-title
  • GtkOrientable
    • A new interface implemented by all widgets that have horizontal and vertical variants
    • Printing support
    • Print-to-file can save to non-local files
    • Page rendering can be deferred to a thread to avoid blocking the mainloop
  • GDK
    • GdkKeymap emits a state-changed signal when the Caps Lock state changes
  • Newly deprecated functions:
    • gdk_window_get_toplevels(),
    • gtk_font_selection_dialog_get_apply_button(),
    • gtk_status_icon_set_tooltip(),
    • gtk_toolbar_set_orientation()
  • Changes that are relevant for theme authors
    • The GtkMenu::arrow-placement style property allow more space efficient layout of scrolling menus
    • Submenu arrows can be scaled relative to the font size, with the
    • GtkMenuItem::arrow-scaling style property
    • Themes can set the GtkDialog::content-area-spacing style property to change the spacing between elements of the content area
    • The GtkEntry::state-hint style property can be used to make GTK+ pass the correct state when drawing the background of entries
    • The GtkEntry::prelight style property can be used to suppress prelighting of icons in entries on mouse-over
  • Changes that are relevant for translators
    • GTK+ has been switched to use the two-argument C_() macro instead of Q_() for messages with context

Read the original announcement for more information including bug fixes and download locations.

GLib 2.19.1 unstable release

This is the second development release leading up to GLib 2.20.

Overview of Changes from GLib 2.19.0 to GLib 2.19.1

  • g_icon_to_string, g_icon_new_for_string: GIcon serialization support
  • G_FILE_ATTRIBUTE_PREVIEW_ICON: new file attribute for preview images
  • g_app_info_get_commandline: new function to get the full commandline
  • g_mount_shadow, g_mount_unshadow, g_mount_is_shadowed: New
  • functions to ‘shadow’ mounts (i.e. hide them from the UI when they already have a different representation, like a bookmark)

42 bugs fixed in this release.

Read the original announcement for more info and downloads.