Development release GIMP 2.99.2 is out

The new unstable version of GIMP, 2.99.2, marks the first step towards GIMP 3 based on the GTK3 user interface toolkit.

Release highlights:

  • GTK3-based user interface, with native support for Wayland and HiDPI displays.
  • Major refactoring and cleanup
  • Multiple layers selection
  • More (color) space invasion
  • Render caching available for better performance
  • New plug-in API
  • Plugins now possible with Python 3, JavaScript, Lua, and Vala
GIMP 2.99.2 splash screen by Aryeom, CC by-sa
GIMP 2.99.2 splash screen by Aryeom, Creative Commons by-sa 4.0
GIMP 2.99.2 with Coffee Run poster by Hjalti Hjálmarsson
GIMP 2.99.2 with Coffee Run poster by Hjalti Hjálmarsson, CC-BY 4.0

GTK3-based UI

The first difference will be visual as you will notice that GIMP got a bit more of a modern look and it can also use some new widgets (instead of redeveloping them on GTK2) as well as client-side window decorations on various dialogs. But the aesthetic differences are far from being the main appeal of GTK3.

GIMP 2.10.22 and 2.99.2 interfaces side by side
Left: GIMP 2.10.22 - Right: GIMP 2.99.2

High pixel density displays

One of the main issues of GTK2 was the absent support for high pixel density displays (e.g. small screens with high resolution or big screens with extremely high resolution) which has become more widespread, especially among graphics professionals. GIMP 2.10 came with partial workaround which was acceptable only in some limited cases but was not really appropriate for intense use of the software.

GTK3 brings proper support to GIMP so it will follow your system-set scale settings.

Status: done, some custom widgets might still need an update.

Improved input devices support

By “input device”, we are mostly talking about drawing tablets or pen displays. In GIMP 2, their support had many shortcomings: you had to plug the tablet before starting GIMP, enable each new device explicitly in the settings and, worse, unplugging the tablet could lead to instability of the software (though this issue got mostly worked around on GTK2 by GIMP developers in the v2.8 release series).

GIMP 3 (hence this first development release) is bringing hotplug support, which means: start GIMP, plug your tablet, done. You are ready to draw, with pressure, tilt, and everything.

We are also trying to improve general support by making the advanced configuration of input devices easier to set.

A while ago, we also experimented with support for touch gestures like zooming, panning, rotating etc. We did not finish this work because we realized this was not a priority compared to some other features.

Touch gestures are very nice and awesome but also sometimes become a burden. Actually, many professional artists even disable touch sensitivity to prevent unwanted input while working with a stylus (high-end tablets often come with a physical switch for this nowadays, and this can also be disabled in tablet settings). With this in mind, we have decided to not make it a priority compared to some other work-in-progress. So we are not sure whether specific gesture support will make it to GIMP v3.0. We do welcome patches from anyone willing to make it one’s priority though.

Status: some work needs to be done to simplify configuration dialog as the support for legacy features is either not needed anymore or can be done better. We might also want to add support for Wayland-specific features related to input devices.

Theming

With GTK3, we also inherit its CSS-based theme format. Unfortunately this means that all custom-made themes from past versions will be incompatible with GIMP 3.0 and future releases. On the bright side, this new theme format uses a very well known theming standard. This should make it much easier to tweak GIMP’s interface to your needs and preferences.

Moreover, the symbolic icon themes are much better supported. They will follow the theme-set foreground and background colors. If you ever had to switch from a dark theme to a light one in GIMP 2.10, you probably remember you also had to switch the symbolic icon themes manually. This won’t be necessary anymore as symbolic icons will be recolored according to your theme.

Finally, the “dark theme” is a core concept of GTK3, which means, for instance, that even window decorations get recolored as you can see in the screenshot above.

Also, a same theme could propose both a dark and a light variant, so the Theme preferences page shows a “Use dark theme variant if available” checkbox. Similarly, icon themes may propose both symbolic and color icons. Which is why the “Icon Theme” preferences page has a “Use symbolic icons if available” switch so that you could choose your preferred style.

Theme switching
Switching to Dark or light themes with a single checkbox with icons recoloring to theme colors

Status: waiting for theme contributors.

Code-side, changes related to theming are basically done. Now we need a new default theme. For now, GIMP 2.99.2 only lists the “System” theme, which lets GIMP follow your system-wide GTK theme. This is a regression from 2.10 that we intend to fix in time for GIMP 3.0 by reintroducing a default theme with a neutral dark/light variant as well as a neutral middle-gray custom theme.

The main issue with system themes is that they cover very basic desktop use cases. Meanwhile, advanced graphics work requires a neutral gray theme to avoid polluting your color perception. This is the main reason why GIMP needs to default to a neutral color theme with symbolic icons.

Colored themes and icons are still an option, and, in fact, we are pretty sure that the community will soon come up with good-looking custom themes. This is a great way to contribute to GIMP as a non-developer!

Wayland support

The port to GTK3 should normally give us Wayland support on Linux for free. And it mostly does. Unfortunately, a few bugs have already been reported for GIMP running on Wayland. Some of them are clearly blockers for releasing GIMP 3 (such as various weird GUI bugs or huge memory leaks). Others are less serious but still are a bit embarrassing, like the one where the splash screen is broken on HiDPI displays because Wayland doesn’t report scaling properly.

Until these issues are fixed, we don’t think we can safely claim that we provide appropriate Wayland support. We will be grateful for all patches to address that, whether they arrive to GIMP, GTK, or another relevant part of the technology stack. If you are interesting in helping out, here is the list of Wayland-related bugs.

Appropriate Wayland support also means we need to reimplement a few features through so called portals. We have already done this for the screenshot plug-in (using Freedesktop, GNOME, and KDE portals), and there is some ongoing work to fix on-display color picking (already works in KDE, doesn’t yet work with GNOME and Freedesktop portals).

As for the file portal, this is probably something that won’t happen for GIMP 3.0, because we still require some features of the GTK file dialog, but it might happen later with a planned redesign for improved export process.

Status: a few blocking bugs in particular require attention. We welcome contributions.

Multi-layer selection

Managing a complex project with tens and hundreds of layers is now much easier thanks to newly added multi-layer selection. Aryeom, the animation film director working with the core team, has been asking for this since 2015, so the ZeMarmot project finally made this happen. This is another example of a successful close artist-developer collaboration: every feature was carefully designed following discussions and was tested in production.

Selecting multiple layers in Layers dockable
Selecting 4 layers to organize them or transform them at once

The Layers dockable is now fully multi-selection aware, using the usual interaction for multi-items selection (Shift+click for selecting a range of layers and Ctrl+click for selecting or deselecting non-contiguous layers). Organizational operations now work on all selected layers, i.e. that you can move, reorder, delete, duplicate, merge (and more…) all selected layers at once.

Several tools now also work on multiple selected layers. For instance all transform tools (move, rotation, scale, perspective, unified transform…) will transform all selected layers (in addition to the existing layer links with the “chain” icon). You can also crop several layers at once or copy-paste merged layers’ projection. Even the Color Picker tool can now pick merged color from several layers (some kind of partial “Sample merged” without having to hide unwanted layers).

These are just a few examples because this change affects a large part of the code base: the concept of an active layer is prominent in every action. You can read more about this in a detailed development report.

Status: this is a work in the progress.

Some features in GIMP still expect a single layer and need to be fixed before the final release. It’s possible that we will inadvertently break something while working on that, which is why it’s important that we do more development releases. Moreover, we might extend the multi-item selection to paths and channels soon.

Finally, painting and GEGL operations (filters) are still limited to single layers. Adding ability to paint or run pixel operations on several layers at once will probably require some additional interface specification and designing to prevent undesired consequences like extremely slow operation or the ability to cancel a long-running process.

Plug-in API

We had to break the plug-in APi to introduce many improvements, although we took a special care not to break things where it wasn’t necessary to do so.

Porting a single-file plug-in from GIMP 2.10 to GIMP 3 usually takes between 5 and 30 minutes. We are working on a porting documentation to be released along with GIMP 3.

If you are a plug-in developer, one of the first steps you can take is making sure you don’t use any deprecated functions. We compiled a list of functions removed and their replacement. You can already do this part of the port while still targeting GIMP 2.10.x versions.

Object API

Among the noteworthy changes, we moved away from object IDs to real objects. In particular in GIMP 3, GimpImage, GimpItem, GimpDrawable, GimpLayer, GimpVectors, GimpChannel and GimpPDB are objects (other classes of objects already exist or may be added later).

It brings safer programming by having typed objects whose class can be easily verified, hence better error messaging (with IDs, which are basically integers, having weird bugs because of improper IDs was not uncommon and it was not always easy to track the bug).

Also object-programming implies class inheritance. Typically a GimpLayer is also a GimpDrawable, itself a GimpItem. This means you can use any methods from parent classes and easily test for class ownership.

A non-C consequence is that it enables bindings to adapt the API to their own object model. Hence duplicating a GimpImage named for instance img in Python 3 can be done with the quite pythonic API img2 = img.duplicate().

Status: object port is basically done. We also want to use object signalling, which is a work-in-progress and should eventually allow to connect signal handlers directly on objects, in order to manage events from the core application (something impossible in GIMP 2, except by regular polling).

GIO usage for file handling

Another change in our API is that paths are now handled as GFile, which implies using the GLib/GIO API.

While it may seem a bit cumbersome (as it adds the additional step of creating and managing a GFile), this allows much more robust file handling. In particular, you won’t have to take care about path character encoding (a real issue when developers just assume everyone uses the same encoding as themselves) hence broken paths and non-portable code. Also we don’t have to deal with difference of operating systems regarding folder separation or file system notations. Working with a GFile makes internal representation transparent and file handling robust.

The second big advantage is that it means all such API gains any ability of installed GIO modules, in particular loading or saving from/to remote locations (even possibly through secure channels like HTTPS). This opens a wide range of possibilities.

GIO port of file handling had been done in the core code of GIMP, back for GIMP 2.10 initial release. We are now bringing the advantages to plug-in developers as well in GIMP 3.0.

Status: done, except with legacy bindings.

Language bindings through GObject Introspection also have full access to GLib/GIO API so they are already able to create GFile from paths or URI without any problem. Yet legacy manual bindings, such as script-fu (Scheme), don’t have GFile access. We are working on it (a patch even already exists, but needs to be reviewed).

Plug-in declaration

Some major changes have been done in the API to declare your plug-in. This is now done by subclassing the GimpPlugIn class and overriding some methods to list and document the created plug-in procedures. We made a much cleaner and explicit API than the previous one which should help plug-in developers.

The way your plug-in procedure’s arguments are now handled has also been standardized, in particular using config GObject properties. This is easier to deal with as a generic logics. Especially the same config object allows us to generate many features. For instance, it will help generate dialogs on demand for plug-ins who do not want to tinker with GTK or other toolkit themselves. It also simplify and standardize argument saving for subsequent calls or a same procedure.

Eventually this is also part of the base work for a future recording/macro feature (very unlikely to be in GIMP 3.0, but this is part of the ground work towards such feature) since we will be able to reliably save the arguments used when running plug-ins.

Status: though the main part of this API is done, more needs to happen before the release, and in particular we are still tinkering with the argument representation.

Bindings

We have introspected the full API through GObject Introspection. It means that GIMP API should be fully usable in a wide range of language bindings. We have only tested a few so far, so we can confirm that GIMP can now be scripted (additionally to C and C++ of course) with:

  • Python 3
  • JavaScript
  • Lua
  • Vala

One of the main differences with how GIMP used to be scriptable, with Python 2 notably, is that a custom layer API is not needed anymore.

Also GIMP 2 bindings used to be made around the PDB protocol which is only a subset of the full C libgimp API. The new bindings are built around libgimp itself. Therefore plug-ins in Python 3, Javascript, Lua or Vala (or any future introspected binding) will have the same possibilities as C plug-ins. This is a bright new world for GIMP plug-in developers!

Another consequence is that the API is basically the same for all these languages, apart for language idiosyncrasies. For instance if finding an intersection of a drawable with a selection in C is:

success = gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height);

In Javascript, it will be:

let [ intersect, x, y, width, height ] = drawable.mask_intersect();

Or again in Python 3:

intersect, x, y, width, height = drawable.mask_intersect()

Another nice example is how C-type arrays, with an additional length arguments are handled. As expected, the length argument does not exist in a binding if the target language has an appropriate structure. For instance, while you can copy from multiple drawables from a script with:

/* Where @drawables is a C array of drawables, and @num_drawables
 * indicates the size of this array.
 */
gimp_edit_copy (num_drawables, drawables);

This can be done in Python 3 as (with num_drawables removed and C array replaced by a Python list):

Gimp.edit_copy([drawable1, drawable2, drawable3])

Not only do these binding now have access to the full GIMP API, but they also have access to many more introspected APIs used as dependencies to GIMP. For instance a plug-in can have access to the full GLib/GIO, GTK, Pango, Cairo APIs as well as the babl and GEGL API (for easier pixel manipulation and access to a massive range of existing operations). This was one of the main limitation of the former Python 2 binding, which could not manipulate pixels with GEGL.

Status: some people are regretting the facilities provided by the former Python 2 binding, such as automatic dialog creation. This is worked on right now (some embryo of dialog generation has even already landed in the development branch after 2.99.2 release) hence should be available for the next development release. The best part is that such API will be done on the main API, thus available to all bindings, not just Python or Scheme. This is one of the biggest advantages of introspected API compared to manually maintained bindings: rather than reimplementing nice features in every available binding, we will provide them in the main API so that every developer can enjoy them, whatever your preferred language.

Finally Script-fu is not one of the introspected bindings (though there is supposedly GObject Introspecting scheme bindings, but we haven’t tested any yet) and still mostly works as its own extension. Yet issues regarding some of the API changes have been raised (for instance the inability to create GFile as discussed earlier) and will have to be fixed before finale stable release.

Goat exercises

For each of the tested binding languages, we created a plug-in called “Goat exercise”, which is a demo for creating plug-ins. You can call it a “GIMP Hello World!“.

Each Goat Exercise does exactly the same thing in its own language: it creates a dialog with a label, buttons and a text view (GTK+ and GLib/GIO demo); one of the buttons triggers a filter modifying the active layer (GEGL demo and GIMP API demo); all this while showing its own source code inside the text view (making it easy to inspect the code from within GIMP) and with a button sending you to the repository file (if you prefer to check out the last version, comfortably in your code editor).

Goat Exercise in 5 languages
The 5 versions of the Goat Exercise plug-in in Python 3, Javascript, Lua, C and Vala

These plug-ins are quite important as we are planning to improve the plug-in ecosystem with GIMP 3. They are the first step of “self-documenting demo plug-ins” (while doing something a bit more exciting that a bare “Hello World”).

Status: current code of the Goat Exercise is not always up-to-date with the most recent API yet as it is a moving target. These will be updated before release.

Developer documentation

We have started to write down some documentation regarding plug-in development in GIMP 3, and will progressively start to publish some tutorials. Hopefully we will even be able to relaunch our developer website that has been slowly decaying for too many years. We hope that GIMP 3 will revitalize the GIMP plug-in ecosystem!

Status: still at an early stage, we welcome more contributors to make it possible.

Extensions

Extensions are a new file format that is simply a wrapper of data (brushes, splash screens, patterns, dynamics…) or plug-ins, associated with metadata (name, description, screenshots, version, requirements…). The goal will be to allow plug-in developers to publish their work on repositories for anyone to search third-party plug-ins, install/uninstall, enable/disable and update them, all within GIMP.

The menu Edit > Manage Extensions shows the base dialog. In the “System Extensions” tab in particular, you will notice an “Official Demo Plug-ins” which is our first extension. It in fact bundles all the Goat Exercises plug-ins we talked about earlier. If you switch if off, you will notice after a restart (right now you have to restart GIMP to see the effect) that the menu category Filters > Development > Goat Exercises disappeared.

Goat Exercise as extension
The Goat Exercises are themselves a system extension.

We’ll get back to talking about this feature after we’ve done more work on it. In particular, we will provide documentation on how to create extensions. It is definitely something plug-in and resource creators should look forward to, as it will help share their creations with others.

Status: still more work to do on the GIMP side, especially for communicating with repositories, and much more work to be done for the official repository and the website for extensions.

Space invasion

Space invasion” is the internal code name for the work originally started in 2018 whose goal was proper support of color space during core pixel processing. In the GIMP 2.10 series, despite core color management support, the profiles were sometimes lost during an operation processing and only reintroduced on finale results, which may result in wrong values in some cases.

Anyone interested to understand further the problematics can read Øyvind Kolås’s post and in particular the detailed associated release notes for GEGL 0.4.6 where he explains this really well.

Some of the improvements of this work have already been progressively backported to various GIMP 2.10.x releases, but GIMP 3.0 should be the culminating release where we hope to get this 100% right.

Status: the development branch is much more advanced on this topic than the 2.10 series, but some more work needs to be done. Various aspects of GIMP still mostly expect or display sRGB-only values.

Render caching

GIMP 3 now has a render cache that keeps the result of scaling, color management, display filters and shell mask (for tools like Fuzzy Select). This results in much snappier user experience in comparison to the GTK2 version of GIMP.

There is now also a Zoom Quality setting in Preferences -> Display. When set to Fast, GIMP will do a nearest neighbor interpolation from the next bigger mipmap level instead of linear or box filtering. This gives a slight and permanent boost to painting and all updates. We have a few ideas to improve this further like reblitting in high quality after a timeout.

Status: done.

Improved import policies

Color Profile Policy now exposes a new choice “Convert to Preferred Profile” and the import dialog default “Convert” action will convert the image to the preferred profile (if any was set, otherwise it falls back to the built-in profile). Converting to the built-in profile will still be available as a secondary action. If you want to always work with a given profile, you can set up your preferred workflow as soon as importing is done.

Moreover, a new Metadata Rotation Policy is exposed in the Preferences dialog, next to the Color Profile Policy (in page Preferences > Image Import & Export) with 3 options: “Ask what to do”, “Discard metadata without rotating”, and “Rotate the image then discard metadata”.

Import Policies
Updated Color Profile policy and new Metadata rotation policy

The metadata rotation policy used to be handled on the API side, with a dialog generated by libgimpui and saved in a global parasite. The whole logics and GUI has been moved as core logics, similar to the “Color Profile Policy”. This implies that plug-ins don’t even need to handle this as it will happen as specified by the user automatically on every new import.

Status: done.

Compact sliders

The compact spin scale was introduced in GIMP 2.10.18. In the 2.10 series, it was left as an optional feature which could be deactivated in the Preferences dialog. In GIMP 3, this is now the only possible behavior, with no options.

Compact slider
New compact slider is now default and only option

Please note that the bright blue color on the screenshot is not our preference, it’s what the system theme dictates. This widget actually uses GtkProgressBar colors by default. Therefore this can be adjusted in a custom theme by changing GtkProgressBar colors or only the colors in this specific widget (again, we welcome theme contributors!).

Status: done.

Refactoring

While porting old features and implementing new ones, a lot of side work has been done on the code structure. Many parts of the code base got refactored for better maintenance.

Even when some port is not done yet, ground work may have been prepared, such as the GimpAction interface to add a layer of abstraction to GtkAction (preparing us to actually move away from it at a later point which is one of the main remaining big ports for the move to GTK3).

Many other parts are constantly remodeled and improved as part of a never-ending background work.

Status: refactoring is always work in the progress, always was, always will be. It never really stops.

Packaging

Beta Flatpak available

This release is available in the “beta” branch of our official Flathub package, which is a hidden release branch (you won’t find this information on the public web page). This command will allow you to install GIMP 2.99.2:

flatpak install https://flathub.org/beta-repo/appstream/org.gimp.GIMP.flatpakref

From now on, you will be able to update to new development builds as soon as they are available through this channel (if your desktop has Flatpak integration, it might even check and propose you the updates automatically).

Note that Flatpak only allows one visible branch of a same application at once. So if you installed both the stable and development releases with Flatpak, your desktop in particular will only show either one or the other. To switch the visible branch, run the relevant command among the 2 proposed below:

flatpak make-current --user org.gimp.GIMP beta
flatpak make-current --user org.gimp.GIMP stable

Some people also created shortcuts running the explicit command flatpak run org.gimp.GIMP//beta (respectively stable) as workaround to get icons for both versions.

Windows

As usual, we provide a Windows installer for GIMP, you will find it on the Development Downloads page.

Some features may be missing. In particular, you won’t find the JavaScript binding on the Windows build because of the complexity of some dependencies. We will fix this in future releases leading up to GIMP 3.

macOS

Our macOS packager has still not fully returned, so unfortunately there is no official macOS package. As always, we remind that GIMP is free/libre software developed by community. Any of you can become an official package maintainer (and having several contributors would keep everyone safe).

If you are interested, we suggest to get in touch with us on our IRC channel for developers, #gimp.

What’s next

As you can see, a lot has been done (the NEWS file will also give a bit more details). The vast majority of the work has already been done. What remains now is the final stroll. This is however not such an idle walk in the park, as the final decisions and attention to details is always the most difficult part. We want to release a rock-solid GIMP v3 and need to pay a lot of attention to details. This is where we are now and why we are releasing this first development version.

This development report lists pretty accurately all the remaining steps, and you’ll notice how it actually follows quite well the changes in GIMP 2.99.2. The API part, though going unnoticed to many users, is probably the major part which we must absolutely get right before the release since our API is meant to stay stable withing the 3.x series. Once we have it done, we will want to keep existing interfaces of libgimp 3.0.0 functions unchanged unless absolutely necessary (i.e. unless we discover bugs that made a function useless). This is likely to take a lot of our time.

There are definitely other parts where help will be crucial, whether it’s plug-ins, core code, user interface, or application interface. So we do need more eyes on this to resolve as many little issues as we can.

To conclude, we remind that you can donate to the project and personally fund several GIMP developers who make this all possible at all. This is also a way to give back and accelerate the development of GIMP if you appreciate the project.