Krita, OpenGL and Qt

The Beginning

Adrian Page first coded an OpenGL-based canvas implementation for Krita in 2005. That was back in the Qt3 days. OpenGL was fairly simple back then, but we had to duplicate all our canvas handling code, once implemented in OpenGL, once implemented with QPainter.

Krita’s canvas code executes in three phases. There’s the image projection, that is, the result of combining all the layers, which is drawn first. Then we draw the canvas decorations: that’s the selection outline, the guides, the assistants, the reference images and so on. Then we draw the tool decorations: that’s the outline cursor, the line for the straight line or ruler tool and so on.

Obviously, implementing all of that twice, once in  OpenGL, once with QPainter isn’t ideal.

The Good Days

So we were elated when Qt4 appeared. Qt4 came with an OpenGL based QPainter engine. This was ideal; we could split up our canvas code. The image would be drawn with pure OpenGL on a QGLWidget or with QPainter on a QWidget, and the canvas decorations and tool decorations would be drawn with QPainter on either canvas.

The Qt documentation even came with a nice example showing how this was to be done.

The First Fly in the Ointment

However, the Qt developers apparently saw the OpenGL QPainter engine more as a way to speed up the drawing of QWidgets than something that application developers would use. And the OpenGL QPainter engine never was able to render a complex application completely correctly.

So at some point, the engine stopped working on macOS. Mostly because Apple doesn’t want people to use OpenGL, so they’re starving their drivers from development, but also because the Qt developers thought that the OpenGL QPainter engine was a failed experiment because it didn’t improve performance when painting their widgets: they had forgotten that applications developers are using QPainter in their OpenGL applications. Or even told them not to do that. Though the documentation never reflected that opinion.

That sucked, since we needed it, and in 2016 we had to spend a Summer of Code slot on fixing the OpenGL QPainter engine so it worked on macOS with OpenGL 3.2 Core Profile. That landed in Qt.

R.I.P Touch UI for Krita

With the migration from Qt4 to Qt5 something else happened: Qt4 QML was based on QGraphicsView. I’ve always suspected that QGraphicsView was created for companies that needed mapping software, but in the Nokia days there were several attempts to use QGraphicsView as a basis for a mobile ui framework, DUI (best link I could find; there’s serious loss of history here).

Those attempts failed, until someone came up with QML, which initially was also rendered with QGraphicsView.

We used QML to create Krita Sketch and Krita Gemini. Because it was based on QGraphicsView, the touch ui we created worked seamlessly with our OpenGL-based canvas.

When Qt5 came out, QML was based on OpenGL and a scenegraph. We spent several months and quite a bit of money trying to integrate our OpenGL canvas in in the new scenegraph, but it just did not work. At all. It couldn’t be made to work, and Krita Sketch and Krita Gemini died.

(As an aside: it was much harder than we had expected to port our OpenGL code from Qt4 to Qt5. It was a huge hassle, in fact.)

The Next Episode

And then Google Chrome happened.

The quality of OpenGL drivers on Windows was always variable, sometimes even really bad. We had already encountered that when developing Krita Sketch, when we suddenly had a lot of Windows users.

Google encountered the same problems with Chrome, and they implemented a solution: Angle.

Angle seamlessly translates OpenGL into Direct3D. And once Chrome used that, all their crashes were gone.

And the GPU manufacturers had no reason all anymore to fix their drivers, so they didn’t. Games would use Direct3D, Chrome used Angle, and pretty soon Qt added an option to use Angle, too, because otherwise QML-based applications on Windows would keep crashing.

This was excellent news for us. We started using Angle, and the number of bug reports dropped a serious amount. And when we wanted to support HDR screens on Windows, the fact that we were using Angle already was great, because that enabled us to make HDR work, because on Windows, HDR can only be made to work when the window is rendered using Direct3D.

The HDR patches still haven’t landed in Qt, so we are carrying them, along with a lot of other patches that are needed to make Krita work well.

We regularly port those patches to newer versions of Qt5, but we make all our Krita binary builds with Qt 5.12, because every version of Qt since 5.12 has been too buggy to use. For example: with 5.15, using a QMdiArea in subwindow mode will hang on Windows.

Except for the fact that Krita Sketch was still dead, and we were porting to Android, and a mobile UI would have been nice, everything was fine.

Qt6 Drops Angle

Because, obviously, Qt’s Angle build option only  existed to make sure that QML apps would work on Windows, not for anything, Qt6 has dropped the Angle option…

Because there’s going to be a new framework which will use the various GPU API’s (Metal, Vulkan, Direct3D, OpenGL) directly with a abstraction layer (Rendering Hardware Interface ) above them that will be used to render the QML scenegraph: RHI. It looks like that’s all internal to Qt, though.

It’s really hard to find documentation, but it looks like QPainter will render using those modules; but what isn’t clear is what will happen when we’re going to use QPainter on a QOpenGLWidget. Or would we have to implement a Metal canvas, a Direct3 canvas, and an OpenGL canvas? And will we be able to access the HDR functionality on Windows?

Or should we just patch Qt6 so it can be built with Angle again?

Update

This blog post appeared on hackernews, and one of the reactions (the one I linked to) was really helpful: Jean-Michaël Celerier has actually implemented something outside Qt, using Qt’s RHI interface. So that is possible! Even though the documentation says “Aim to be a product – and in the bigger picture, part of a product (Qt) – that is usable out of the box both by internal (such as, Qt Quick) and, eventually, external users.”

So, I guess the choice for Krita boils down to using RHI — after we’ve determined that it is possible to use that, or using Angle.

In both cases we would be running an abstraction on top of Metal, Direct3D, OpenGL or Vulkan. In the first case, we’d tie Krita even closer to Qt (and every Qt major release changes its approach to graphics, so in a couple of years, who knows…) In the second case, we will have to maintain patches against Qt.

We haven’t come to a conclusion yet.

Nightmares and Bugs

(Recommended music while reading this: Peggy Seeger singing “The Housewive’s Lament)

I’ve been having nightmares, well, really weird dreams for quite some time now. Things like finding myself trying to clear up the floor of a large DIY store just before the first opening day, and not managing it, no matter how many friends were helping. Trying to pack all my luggage when leaving a rented holiday home, and never being able to fit everything in. Trying to pack furniture and stuff into boxes before moving out because someone needs to replace the floor, and having to squash ancient china cups in a carton box, breaking them all in the process. If I manage to wake up, I’m exhausted and tired.

And I guess I’ve grokked why I keep having these dreams. And it’s not lockdown or Covid-19. It’s this:

Krita's Bug Graph

When we held our last bug fundraiser in 2018, we decided to focus for a year on stability. we had about 300 bugs. And we’ve never even managed to come close to that number of bugs ever since! And yet, in the past year, we’ve closed more than a thousand issues.

Clearly, something is wrong here. This isn’t sustainable. We have managed to deflect a lot of reports that were actually cries for support to a new community website, krita-artists.org and to r/krita. Our experiment with ask.krita.org wasn’t successful, but krita-artists really works. We still do get a lot of worthless bug reports, but I think it could be a lot worse, now that we really have millions of users on four platforms.

But it’s still not sustainable. Every report needs to be read, often deciphered, triaged, investigated, fixed — and all those steps involve communication with the reporter. Even the most useless bug of reports can take an hour to resolve with the reporter.

11:32:47. Eep, incoming bug interrupt. Bug 422729No action (assignable shortcut) for Magnetic Selection Tool. 11:33:24: Check, yes, reporter is right. 11:34:32: Confirm. Check code. Notice that all .action files that define actions in the plugins/tools folder are wrong. 11:37:35: Add note to bug report. Fix all of them. 11:47:49: reporter asks a question that needs to be answered, but is not very relevant. 11:56:29: answer given, while I’m building Krita with my fix. 11:57:03: Tested fix, isn’t complete, more work needed. Oh, wait, tested the wrong build. Tested the right build, but the new action isn’t found. 12:00:00 Debug more. 12:25:45: fixed some more broken xml files, ready to make the commit. 12:27:41: Bug is fixed. 12:31:33: Fix is backported to krita/4.3 branch and an extra commit is added that in future will print a warning if the xml parser cannot read the .action files.

Back to this blog post… This was a fast fix: it took about an hour, and in between I also had to run downstairs to receive my new book on Jan van Eyck.

So, this bug report reported a small, but real issue and uncovered a deeper issue. Without the report we probably wouldn’t have noticed the issue. Krita is better because of the report, and the reporter is one of our “known-good” reporters: he has reported 16 bugs this year, one is still in Reported state because we couldn’t reproduce it, six are Confirmed, two are Assigned and seven are Resolved Fixed. Yu-Hsuan Lai has helped us make Krita materially better!

But… Even with me, Dmitry, Agata, Wolthera, Emmett, Eoin, Ivan, Mathias and more people fixing bugs all the time, we’re not getting the numbers down. The floor remains littered, the luggage unpacked and the china unboxed.

Of course we’re not the only ones in this situation: every project that takes bug reports from the general public faces this issue. Some people argue that any bug that has a workaround should be documented and closed; but workaround don’t make for a happy workflow. Others argue that every bug report that is older than two weeks, or a month should be closed because it’s clearly not a priority. But the issue reported is real, and will get reported over and again, with no way of chaining the reports together.

It’s also possible to treat reports like a funnel: first ask people to report on a user-support forum, like krita-artists.org, and only when it seems to be a real bug create a bug report, and only when it’s triaged, put it in a queue. But the problem with that is that nobody’s queue is ever empty. That can be done by assigning the bug to one of us: currently we have 64 bugs in the Assigned state. that means, on average, ten bugs each person’s queue. That in turn probably means betwee a week and a month of tasks already in our queue… Which means we shouldn’t actually look at any newly reported bugs, before we funnel them into our queue. (Another option would be to create issues on invent.kde.org for every bug we really want to work on, something we used to do with phabricator… But pretty quickly we drowned in those tasks as well.)

Which in turns means that either reporting bugs is useless or our todo queues are useless.

And that todo list doesn’t even include working on new features, refactoring old code so we decrease technical depth or working on regressions — that is, features we broke accidentally.

So, even though bug reports help make Krita better, the one  thing I’m sure of is that we shouldn’t do anything that will make it easier to report bugs. We have more than enough reports to keep us busy.

It would be nice, though, if we could make it easier to make good bug reports, for instance by automatically attaching our system information and usage logs to a bug report made with the Help->Report Bug functionality.

Theoretically, that can be done, bugzilla offers a complete REST interface. And I seem to remember that we had that in KDE, years ago, but that it broke because of an update of bugzilla. There’s a new version of bugzilla coming, apparently, and maybe it’ll be worthwhile to investigate that again, in the future.

Argh… I think the dreams will continue for a while.

Cherries, or does the brand make a difference, when it comes to oilpaint

Last summer, when everything was still normal, I wanted to do some painting again after a hiatus of 15 years. (During which I did a lot of sculpture, but I hurt one of my fingers and the scar tissue both still hurts, especially if I put pressure on it, and the fingertip is completely insensitive at the same time. This makes sculpting in wax Not Fun.)

I took out my old Talens van Gogh paints, went on the roof terrace and started doodling. But the white spirit fume was rather bad for me, even outside… Some of those tubes I’ve had since I was twelve years old, and never used them up. Oil paint might be expensive, but apart from white, you don’t use much of it.

Then I discovered Talens Cobra water-mixable oils. I got a bunch of them, new brushes, some paper suitable for painting with oils, and had a lot of fun.

When we had a sprint last year (remember when we could have sprints, it sure seems a different country now), I let the artists paint with it, and they had fun, too!

The paper never really pleased me. I had two kinds, something linen-like and something with a bit of a coarse texture. Neither pleased me.

So, when around Christmas, I wanted to paint two small portraits of roleplaying characters, I started working on small panels.

I painted the portraits of Moyri and Khushi. This was lots of fun, too, but I sort of realized that in the first place I could do with some teaching where it comes to the technical aspects of painting. Sure, I have been going to life drawing class every other week for a couple of years now, but the teaching there is more about art and composition and things than technical advice on how to hold your brush, load it, put paint down and so on.

And I wanted to experiment with some other paint, so I got Schmincke Mussini paint. This paint turned out to be much nicer to use than Cobra or van Gogh, with a very smooth consistency and great colors. The Cobra vermilion is much too orange; the Mussini vermilion is just perfect. But the paint is mixed with a kind of resin, following the recipe of Cesare Mussini, who with a horde of other painters/scholars in the Nineteenth century was looking for the The Secret of the Old Masters and thought it were mystery ingredients, instead of just starting young, drawing all day and painting all day.

So I decided to look for a place to learn. I found Art Partout, in Deventer and a bunch of other places in the Netherlands. I took them up on their offer of a test lesson before plunging in. They let us paint cherries, which is a bit boring, but, well, I already found I learned some things, so I decided to join.

Except of course that the day the lessons were supposed to begin, the lock-down happened… They did send out paint, brushes, documentation and a link to a bunch of videos, so we could get started, though. The paint was Schmincke Norma, so now I have four kinds of paint to play with: Talen van Gogh, Talens Cobra, Schmincke Mussini and Schmincke Norma.

The first lesson was…. Painting two cherries. The identical two cherries I had already painting during the test lesson! Anyway, my results then weren’t too good, so I decided to just do it again, but with a twist: I’d paint the original cherries with the Norma paint, and then one with Cobra and one with Mussini, just to check whether the snootiness about Cobra being no good had anything to it.

Mussini, Norma, Norma, Cobra, table and background also Cobra, stalks Norma.

There was absolutely no difference in handling that I could feel between Norma and Cobra, apart from being able to clean the brushes with water.

But the Mussini was a lot better, with better covering, better spreading and fuller color.

I wish I had thought of this experiment before I did the second cherry with Norma, though, because I’d have liked to check with my old van Gogh paints. Though that set is missing some colors, and I cannot get the cap off the tubes of some others.

But there’s a second panel, which is meant to be used to paint berries, but I might just use it for another four cherries, in the interest of science…

And I’ve made a nice place to work for myself, with only one bug: it’s to easy  to turn to the left and switch on the monitor of my work computer.

My painting desk

 

The Power of Blogging

In my last post, I related the tale of how I had spent three months trying to return to laptops to Lenovo that I had mistakenly ordered... I thought it would only be friendly to mail Lenovo’s customer support (by Digital River, as they never tire of telling you) a link.

What the final demand letter hadn’t managed, the blog post managed.

The next working day, I had mail from Lenovo! Asking me whether I still wanted to return the laptops. I answered that I had only one left, which I really wanted to return, yes, especially since it had a faulty battery, and that the other was living a useful life in Mexico. I also explained that the problem seemed to be that TNT couldn’t send me the mail with the link to the return form.

The next day, I had a mail with all the details for shipping back the laptop, and within another two days, the laptop was gone! The box no longer clutters our dining room, and it was gone!

Then the wait for the refund started, and within a week, we had our money back!

Truly, the powers of blogging are infinite.

A Tale of Four Laptops, or, How Lenovo’s Digital River Customer Support Sucks

In September, I made a mistake… We needed new laptops for Dmitry and Agata, and after much deliberation, we decided upon Lenovo Yoga C940’s. These are very cool devices, with HDR screens, nice keyboard, built-in pen, two-in-one convertible — everything in short for the discerning Krita hacker.

I accidentally ordered the S940 instead — two of them. These are very awful devices, without a pen, no touch-screen, don’t fold, don’t have HDR, don’t even have normal USB ports. Overpriced, under-powered — why the heck does Lenovo call these Ideapads yoga’s? I have no idea.

Well, no problem, I thought. I’ll just return them and ordered the C940 instead. The C940’s arrived in time for our BlenderCon sprintlet, and were all what one expected them to be. And I filled in Lenovo’s web form to return the S940’s.

That turned out to be a big problem. Here’s what happened:

  • I ordered them September 24th
  • They were delivered September 26th (nice and fast)
  • I filled in the return form on September 26th
  • Not having heard anything from Lenovo or TNT, I called customer support (by “Digital River”) and was promised I’d get a mail the same day with the forms needs to send the devices back; you cannot just send them back, you have to have the forms. There’s no other way to get to know the return address.
  • Not having heard anything back, I called them on October 21st. Same promises
  • Not having heard anything back, I called them on October 21st. I had to call twice, because as soon as she’d heard my name, the first customer support person closed the connection. I got promises of escalation to higher-ups
  • Not having heard anything back, I called them November 4th. I got the same person on the phone, who gave the same promise of escalation.
  • Not having heard anything back, I called them November 19th, and was promised that my money would be refunded immediately and they would figure out a way to get the laptops back.
  • Not having received my money, or heard anything back, I called them December 13th. They promised me they’d do something about it, but that I was very mistaken in supposing I should have had my money back, they hadn’t got the laptops, right? When I asked them for an address to send them to myself, I was told that was impossible, so sorry. I told them I would get legal advice if I didn’t hear from them.
  • Not having heard anything from Lenovo, I called my legal adviser, who called Lenovo to get an address out of them we could send a paper letter to. This is apparently impossible. My legal adviser told me he was shocked at how rude the Lenovo representative was.
  • I sent the required final demand letter by email in January…
  • And not having heard anything from Lenovo whatsoever, my legal adviser told me the only solution would be to sue…

Well, I’m not prepared to bother with that. I’ll take my loss, think black thoughts of Lenovo and find a use for the devices. In fact, I’ve handed one to Ivan who didn’t have a windows machine, and tried to setup the other as a test machine.

But Lenovo is really, really awful. These laptops come with something called Lenovo Vantage, which has only one reason for its existence: it can switch the media keys into proper function keys. That used to be in the bios, but no longer… For the rest it’s a marketing and spyware tool — like Windows 10 itself, of course. And then Lenovo Vantage was updated, this function is gone! People started complaining about that on the Lenovo forums, and as of writing, Google still found those posts, but Lenovo has deleted all of them.

I’ve bought Yoga’s, Thinkpads and even Ideapads in great numbers in the past twenty years… But I think it’s time to make a change.

Python 3.8 woes

I’m not as deep into Python these days as I was twenty years ago. Twenty years ago, Python was small language with clear documentation and clear, consistent ways of doing things. One thing was hard, though, and that was packaging your python application so people on different systems could use it.

These days, Python is big, has lots of computer-sciency features that I don’t grok, and packaging Python is still hard. And the documentation is, for the most part, not very useful. I didn’t care a lot about that, though, since we only use Python as Krita’s extension language together with PyQt. And we had a nice and working setup for that.

Well, nice… It’s a bit hacky, especially for Windows. Especially since we need to build Krita with mingw, because msvc has problems compiling the Vc library. And Python has problems getting built with mingw-gcc on Windows.

We have three related parts: python, sip, which creates Python libraries out of special hand-written header-like files, and PyQt, which binds Pyton and Qt.

So, we start with a system-wide install of Python. This is used to configure Qt and build sip and PyQt. Then we download an embeddable Python of exactly the same version as the system-wide install, and install that with Krita’s other dependencies.

But last week the KDE binary factory windows images got updated to Python 3.8.1 (from 3.6.0) so we had to update the references to Python in Krita’s build system. There are a couple of places where the exact version is hard-coded, not just in the build system, but also in the code that setups Python for actual usage when Krita runs.

And at that point, our house of cards fell apart. Python 3.8 has a new, improved, more consistent way of finding dll libraries on Windows. At least, that was the idea. Following discussion in Python’s bug tracker, a Python developer declared victory:

Given that the actual error we had was

c:\dev\krita>python
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt5
>>> import PyQt5.Qt
>>> import PyQt5.QtCore
Traceback (most recent call last):
File "", line 1, in
ImportError: DLL load failed while importing QtCore: The specified module
could not be found.

This seemed related: the PYQt pyd files link to the Qt dll’s. The pyd files are in lib/krita-python-plugins, the Qt dll’s in the bin folder, and it looks like the QtCore pyd, even though dependency walker shows it can find the QtCore.dll, Python cannot find it anymore.

So, on to the changelog. This says:

DLL dependencies for extension modules and DLLs loaded with ctypes on Windows are now resolved more securely. Only the system paths, the directory containing the DLL or PYD file, and directories added with add_dll_directory() are searched for load-time dependencies. Specifically, PATH and the current working directory are no longer used, and modifications to these will no longer have any effect on normal DLL resolution. If your application relies on these mechanisms, you should check for add_dll_directory() and if it exists, use it to add your DLLs directory while loading your library. Note that Windows 7 users will need to ensure that Windows Update KB2533623 has been installed (this is also verified by the installer). (Contributed by Steve Dower in bpo-36085.)

Well, that sounds relevant, so let’s check the documentation and see if there are examples of using this add_dll_directory…

os.add_dll_directory(path)
Add a path to the DLL search path.

This search path is used when resolving dependencies for imported extension modules (the module itself is resolved through sys.path), and also by ctypes.

Remove the directory by calling close() on the returned object or using it in a with statement.

See the Microsoft documentation for more information about how DLLs are loaded.

Availability: Windows.

New in version 3.8: Previous versions of CPython would resolve DLLs using the default behavior for the current process. This led to inconsistencies, such as only sometimes searching PATH or the current working directory, and OS functions such as AddDllDirectory having no effect.

In 3.8, the two primary ways DLLs are loaded now explicitly override the process-wide behavior to ensure consistency. See the porting notes for information on updating libraries.

Well, no… So let’s google for it. That didn’t find a lot of useful links. The most useful was a patch for VTK that uses this method from the C++ wrapper The examples in that tweet would’ve been a good addition to the documentation.

So I started experimenting myself. And failed. Our code that detects whether PyQt5 is available isn’t very complicated, but no matter what I did — even copying the Qt5 dll’s to the PyQt5 folder, using add_dll_directory in various ways, I would always get the same error.

And now I’m stuck. Downgrading to Python 3.6 makes everything work again, another hint that this dll finding change is the problem, but that’s not the way forward, of course.

For now, the beta of Krita 4.2.9 is delayed until we find a solution.

 

About “Qt offering changes 2020”

When I read “Qt offering changes 2020” yesterday, my first reaction was to write a pissy blog post. I’m still writing a blog post with my thoughts about the changes, but I’ll be nice. There are three parts to this post: a short recap of my history with Qt and then my thoughts on what this means for KDE, for Krita and for free software.

I started programming using Qt and PyQt when I read about Qt in Linux Journal, which I was subscribing to back in 1996. That means that I’ve been using Qt for about 25 years. I initially wanted to write an application for handling linguistic field data, and I evaluated GTK+, wxWidgets, Qt, Tk, fltk, V and a few others that have been forgotten in the mists of time. I choose Qt because it had great documentation, a consistent API, the most logical (to me…) way of doing things like setting up a window with a menu or handling scrollbars and finally because it made C++ as easy as Java.

I’ve stayed with Qt for 25 years because, through all the vicissitudes, it kept those qualities. Mostly. There are now a lot more modules, most of which aren’t necessary for my work, there are people working on Qt who seem to be a bit ashamed that Qt makes C++ as easy as Java and want to make Qt as computer-sciency as C++, there have been the licensing issues with the QPL, the changes to GPL, to LGPL and then again some modules back to GPL there have been the Nokia years, the Digia times.

But I’ve always felt that I could build on Qt. And the reason for that is the KDE Free Qt Foundation. To summarize: this is a legal agreement that keeps Qt free software. If the Qt company won’t release a version of Qt under a free software license within a year of a release, Qt becomes licensed under the BSD license.

With yesterday’s message, the Qt company is searching the utter boundaries of this agreement. To recap:

  • Long Term Support releases remain commercial only (the post doesn’t mention this, but those releases also need to be released under a free software license within a year to adhere to the agreement, at least to my understanding).
  • Access to pre-built binaries will be restricted: put behind an account wall or be only available to commercial license holders
  • And there’s a new, cheaper license for small companies that they can use to develop, but not deploy their work to customers.

This is a weirdly mixed bag of “changes”. The last one is a bit silly. Even the “commercial” side of Krita is too big to qualify! We’re five people and have a budget of about 125k…

The middle point is worth considering as well. Now there is nothing in any free software license that talks about a duty to make binaries available.

For a very long time, Krita, when part of KOffice, only made source tarballs available. Right now, we, like the Qt company, have binaries for Linux, Windows, macOS and (experimentally) Android. The Windows binaries are for sale in the Windows Store and on Steam, the Linux binaries are for sale on Steam. And all binaries can be downloaded for free from krita.org and other places.

This move by the Qt company would be like the Krita project shutting down the free downloads of our binaries and only make them available in the various stores. It would be legal, but not nice and would cost us hundreds of thousands of users, if not millions. It is hard not to wonder what the cost to the Qt community will be.

The first change, the restriction of the LTS releases to commercial customers has all kinds of unexpected ramifications.

First off, Linux distributions. Disitributions already rarely use LTS releases, and in any case, with Qt 3 and Qt 4 there didn’t use to be any LTS releases. But disitributions do have to keep older versions of Qt around for unported applications for a longer time, so they do need security and bug fixes for those older versions of Qt.

Then there’s the issue of how fixes are going to land in the LTS releases. At the last Qt contributor summit the Qt project decided on a process where all fixes go through “dev” and then are ported to the stable branches/LTS branches. That’s going to break when Qt6 becomes dev: patches won’t apply to Qt 5.

Albert has already blogged about this change as well, but he only really focused on distributions and KDE Plasma; there is of course much more to KDE than the Plasma desktop and Linux distributions.

As for Krita, we’re using Qt 5.12 for our binaries because we carry a lot of patches that would need porting to Qt 5.13 or 5.14 and because Qt 5.13 turned out to be very, very buggy. For Krita, using a stable version of Qt that gets bug fixes is pretty important, and that will be a problem, because we will lose access to those versions.

In my opinion, while we’ve done without stable, LTS releases of Qt for years, it’s inevitable that Qt 5.15 will be forked into a community edition that gets maintained, hopefully not just by KDE people, but by everyone who needs a stable, LGPL licenced release of Qt5 for years to come.

Splitting up the Qt community, already responsible for handling a huge amount of code, is not a good idea, but it looks like the Qt company has made it inevitable.

And once there’s a community maintained fork of Qt, would I contribute to the unforked Qt? Probably not. It’s already a lot of work to get patches in, and doing that work twice, nah, not interested. If there’s a maintained community version of Qt 5, would I be interested in porting to Qt 6? Probably not, either. It isn’t like the proposed changes for Qt 6 excite me. And I don’t expect to be the only one.

As for the more intangible consequences of these changes: I’m afraid those aren’t so good. Even in our small Krita community, we’ve had people suggest it might be a good idea to see whether we couldn’t port Krita to, say, Blender’s development platform. This would be a sheer impossible task, but that people start throwing out ideas like that is a clear sign that the Qt company has made Qt much less attractive.

If I were to start a new free software project, would I use Qt? Last Sunday the answer would have been “of course!”. Today it’s “hm, let’s first check alternatives”. If I had a big GTK based project that’s being really hampered by how bad, incomplete and hard to use GTK is, would I consider porting to Qt? Same thing. If the KDE Free Qt Foundation hadn’t that agreement with the Qt company, the answer would probably be no, right now, it’s still probably a yes.

Now as for the actual announcement. I think the way the Qt company represents the changes is actually going to help to harm Qt’s reputation. The announcement is full of weasel-wording…

“General Qt Account requirement” — this means that in order to download Qt binaries, everyone is going to need a Qt account. Apparently this will make open-source users more eager to report bugs, since they will already have an account. And, yay, wonderful, you need an account to access the completely useless Qt marketplace. And it allows, and now we’re getting at the core reason, the Qt company to see which companies are using the open source version of Qt and send salespeople their way. (But only if the people making the accounts are recognizable, of course, not if they make the account with their gmail address.) When I was working for Quby, I was unpleasantly surprised at how expensive Qt is, how little flexibility the Qt company shows when dealing with prospective customers — and how we never downloaded the installer anyway.

“LTS and offline installer to become commercial-only” — this will break every free software project that uses services like travis to make builds that download Qt in the build process. Of course, one can work around that, but the way the Qt company represents this is “We are making this change to encourage open-source users to quickly adopt new versions. This helps maximize the feedback we can get from the community and to emphasize the commercial support available to those with longer product life cycles that rely on a specific Qt version.” Which of course means “our regular releases are actually betas which we expect you freeloaders to test for us, to provide bug fixes for us, which we can use to provide the paying customers with stable releases”.

And yes, theoretically, the main development branch will have all bug fixes, too, and so nobody misses out on those bug fixes, and everyone has stability… Right? The problem is that Qt has become, over the years, bigger and buggier, and I doubt whether releases made fresh off the main development branch will be stable enough to provide, say, a stable version of Krita to our millions of users. Because, apart from all the bug fixes, they will also have all the new regressions.

“Summary”. The Qt Company is committed to the open-source model of providing Qt technology now and in the future and we are investing now more than ever. ” — though only to the extent that the Qt Company is forced to adhere to the open-source model by the KDE Free Qt Foundation.

We believe that these changes are necessary for our business model and the Qt ecosystem as a whole. ” — my fear is that the Qt Company will not survive the fracturing of the Qt ecosystem that this decision practically guarantees.

I’m on vacation…

I started feeling really tired in November, and then I realized I hadn’t taken much time off this year — a couple of days at the sea-side was most of it. So I thought it was time to do something else than bug triaging, bug fixing, writing code, acting like I’m a manager. This summer I’d bought water-soluble oil paints (Cobra, from Talens), and I have spent and hour here and an hour there learning the stuff again.

Continue reading “I’m on vacation…”

Mixing Green

For my own reference:

Palette with greens

Counter-clockwise outside:

  • Mix of Titanium and Zinc White
  • Burnt Sienna (to work as red)
  • Ultramarine
  • Phtalo Blue
  • Permanent Yellow with Phtalo Blue
  • Cobalt Blue

The group of six dots, left to right, each column top to bottom

  • Cadmium Yellow Lemon with Ultramarine
  • Cadmium Yellow Lemon Phtalo Blue
  • Cadmium Yellow Lemon with Cobalt Blue
  • Permanent Yellow Medium with Ultramarine
  • Permanent Yellow Medium Phtalo Blue
  • Permanent Yellow Medium with Cobalt Blue
  • Permanent Lemon Yellow with Ultramarine
  • Permanent Lemon Yellow Phtalo Blue
  • Permanent Lemon Yellow with Cobalt Blue

Inside two color, three colors in a row, left to right, top to bottom

  • Phtalo Blue with Lemon Yellow
  • Cobalt Blue with Permanent Yellow Medium
  • Cobalt Blue with Cadmium Yellow Lemon and Burnt Sienna
  • Cobalt Blue with Cadmium Yellow Lemon
  • Cobalt Blue with more Cadmium Yellow Lemon