It's not too hard to get an AppKit/Cocoa project from the early 2000s compiling on modern macOS, but Cocoa had already accrued 20 years of age by 2005, which no doubt has reduced the degree of changes that've been necessary in the 18 years since. GTK only hit that 20 year mark a few years ago and hasn't enjoyed the same level of corporate firepower to develop it.
Across a number of minority language communities I participate in, there's a constant stream of "Why isn't there a good native GUI toolkit in $MY_FAVORITE_LANGUAGE yet? All the ones I can find suck." questions, to which the answer is, you're asking for a project that can easily be on the order of magnitude of all the other Open Source projects in the language combined, if not greater. What you get with less than effort than that are the aforementioned "suck"y GUI toolkits. Which I celebrate and praise, but realistically, just getting a production-grade "rich text widget" is alone a staggering undertaking, let alone everything else that goes into a GUI toolkit.
Just a project to bind an existing GUI toolkit into your favorite language can easily overwhelm a dedicated team of multiple people, and as annoyingly complicated as that can be, it's wildly easier than building the entire toolkit.
Getting to "maturity" is a really, really hard problem.
That's to say that a useful GUI toolkit has typically been a whole lot more than simply "draw me some widgets and let me poll on input events"
I wonder if that's really still as true though in newer (not C/C++) languages like Rust for example, where you can reuse a lot more of what the ecosystem and language already provide.
Someone may reply to me with one. I'd have to look at it and analyze. But I know I'm not going to get dozens of citations of high-quality toolkits of, say, the calibre that I can put rich text widgets with high-quality multi-font unicode support and everything else I want out of such a widget, into a tree control with those rich text widgets as my leaves, and have a million node's worth of rich text controls because they can be lazy-loaded based on visibility, just to come up with one use case.
Reminds of early-mid-00s and Delphi components. The standard components were fine, but lacked many important features (including Unicode!), so you'd hunt/shop around for third-party components.
That probably wasn't as much of a problem for a working adult but it wasn't much fun as a broke teenager itching to make things (as I was at that point).
The newer UI Toolkits have only labels. Buttons, scrollbars, borders, menus, comboboxes cannot be implemented with the current state of the art technology. /s
I have to disagree, it's not that hard and can be done by one person. Red language did it, it has very clear declarative GUI toolkit for Win/macOS/GTK in <2MB executable. So no, it's not that hard.
At that size you've got a programmer GUI toolkit, that as long as it is used by a programmer who is willing to live within its constraints, it will work fine, but it won't satisfy anyone else.
To put it another way, Window's Wordpad is an OK document editor, if you're happy to live within its constraints... but it's no replacement for a Word document being shared over Sharepoint with change tracking between multiple people before finally going out to 1,000 people via a mail merge. There's a ton of Wordpad-class GUI toolkits. There's not very many Word-class GUI toolkits.
I find the analogy particularly apt because it is often said of Word "Everyone uses only 10% of Word but everyone uses a different 10%", and the same is true of GUI toolkits. Once you get out of the super-basics of text widgets and radio buttons, you're in a hugely diverse world where nobody is using the same thing but to be a "real GUI toolkit" you need to support them, like, table widgets with complicated lazy loading, rich text widgets rich enough to implement a full custom editor, arbitrarily complicated graphing libraries, OpenGL support, internationalization and FULL Unicode support (far beyond merely the rendering of text), and so on and so on. I mean, take a minute and click through this: https://doc.qt.io/qt-5/classes.html Some of it is because QT is also a framework, but a lot of it is there for a GUI toolkit reason.
Just blipping through that, a list of features that are absolute drop dead requirements for someone out there that I didn't think to mention includes: Printer support, animation support, OAuth support, canvas support, filesystem support (for that open dialog and friends), font interaction for if you need direct rendering, help support, alternate calendar support, video support, and who knows what else I missed. Few apps need all these things, but there's plenty of apps in the world that absolutely, positively need at least one of those things.
That's a mindboggling thought. How much did 2005 Cocoa have in common with 1985 Cocoa? (That's a real question, I have no idea)
Qt and GTK were released (or first labelled stable) in 1995 and 98 respectively, so 20 years gives us 2015 and 2018 which is well within the Qt5 and GTK3 era.
For Qt, I would say Qt4 in 2005 marks a point of maturity. After that there have been whole substructures and programming idioms added and removed and all sorts of things tidied up, but anything you wrote directly to Qt4 is going to be conceptually similar in current Qt versions.
The Qt2 to Qt3 and Qt3 to Qt4 transitions (I never used Qt 1) broke almost every line of Qt code, but from 4 to 6 is a different prospect. It's a question of updating some details and seeking replacements for specific APIs that haven't been carried across. That can be difficult or totally blocking but it's quite different from having to rewrite everything.
Except - not strctly Cocoa but memory management has changed a lot and might have changed some APIs.
1985 just had malloc and free or [Class alloc] and [object free] 1986/7 introduced autorelease and retain. 2009? had garbage collection and then 2010? had the autorelease and retain automated (ARC).
But a few things changed considerably. The background models and that now you go away from NSCell objects to child windows is the step and the required step to get stuff onto the GPU. The next one is Recycle View anything, removing the concept of NSOutlineView to NSTable View.
Hopefully easier? Unsure however.
> But I think having that compatibility is one of the reasons of Linux's success, the rule of "Do not break user space".
Quite. Of course, it's a sometimes repeated joke that the Linux GUI toolkit with the most binary compatibility is the Win32 API (via Wine).
Cambalache is a successor for Glade but it also has issues. It uses its own storage format and you have to export to a .ui file for use in your Gtk4 project, and if you make changes to the UI file it's very difficult or even impossible to use those changes in Cambalache again.
The general consensus on a few of the GNOME-related Matrix channels seems to be writing .ui files by hand.
Cambalache is years away to reach feature parity with Glade. Then there is the whole of using Web to render the designer.
I'm sure all the distros are busy, but it sure would be nice if one of them would fund get a developer they pay to do this.
It suffers from we don't think about UI but only about technology. GUI Builder the old way stink (only XCode stinks like a perfume). There is also a reason why Microsoft does not offer a GUI Builder for their new WinUI 3
There are good reasons why professional developers abandoned GTK+, and this is just one of them.
* First: GNOME was born without an IDE. But, there was an interesting little project (by Naba Kumar) which started in late the mid 90's called Anjuta. IIRC, Anjuta 0.x to 1.x was what was called a "monolithic" IDE; that is: it didn't had any plugins and its features were "hard-coded". The 2.0 rewrite allowed it to have plugins, but they didn't covered (at first) all of the features of Anjuta 1.x. It was only around 2.4 or 2.6 that Anjuta finally got feature-rich and reasonably stable enough to become part of the GNOME project and the "IDE of the GNOME project" although most GNOME devs didn't use it.
* Second: GNOME was born without a GUI Builder. The most successful one was Glade. At first, glade generated C source code for the UI using GTK. Then people thought it was bad and someone created libglade. The 'project libglade' was two things: a XML format specifying an UI description and a library that could dynamically (at runtime) load it and build a GTK interface from that description. It could even connect signals without a single line of C source code.
Since libglade seemed like a good idea it was eventually incorporated into GTK in a format that is now called GtkBuilder.
Parallel to this, many events happened. Glade changed hands a few times and eventually its main developer became Chema Celorio. Celorio was a skydiver and one day he had a problem with his parachute and died. Glade development became dormant until it was picked up again by Tristan Van Berkom. Trista modernized it, 'resurrected' it, improved its UI, rewrote many parts of it and eventually removed its code generation back-end to use only the GtkBuilder format.
* Third: At the same time, Anjuta development also changed hands. I remember Johannes Schimidt and a few others. At some point, there was an integration between Glade and Anjuta, but it was not very different from running the two tools separated except for the fact that they shared the same window.
There was some hope when, during the selection for Google Summer of code an interesting project was chosen: improve the integration by Pavel Kostyuchenko. The project was successful and the integration between Glade and Anjuta improved because of it.
I was happy and hopeful for these facts when one day I saw that (part of) the integration code was chopped off. I was so intrigued by this fact that I decided to ask Anjuta devs personally (on IRC) what had happened. The answer was something like: "it was not as good as we'd like, fixing it would be much more work than rewriting it."
That was when I decided to join the project to fix it myself. I improved the integration between Glade and Anjuta. Rewrote how it created functions inside the C source code, how it discovered automatically which .c and .h files were associated with the .ui file. Implemented automatic creation of members on the C struct that corresponded to the UI elements, fixed some bugs, wrote a documentation which was a good tutorial on how to use these features... I even implemented the preview feature in Glade. I really made the integration work to my liking. It was the workflow I dreamed.
The future seemed bright: there were new developers, frequent commits, new feature were implemented frequently... But GTK evolved faster than Glade. Tristan eventually abandoned it and it was picked up by Juan Pablo Ugarte. By around this time, Glade became something of a monstrosity of technical debt, slow, crash-prone and buggy but it worked. Implementing support for modern GTK features (like bindings and css) seemed to much work and too hard to do.
* Fourth: Around 2013 Christian Hergert started developing a modern IDE for GNOME: GNOME Builder. He left his job, started a campaign to get money to back him up during first versions and quickly showed a lot of progress. It was said at the time that it was going to have Glade integration (it eventually did have, but it was never a decent one). The project thrived and Redhat hired him.
Development of Anjuta slowly became dormant after this. It is now archived.
Hergert started another project, Drafting, to replace Glade but it was de-prioritized. Ugarte basically abandoned Glade and started Cambalache. Cambalache seems like a good idea, works but has no IDE integration and is still mostly a "one man show".
And that is how we arrived at where we are. GNOME still lacks a good UI builder with IDE integration and no current plans to fill this gap.
this deserves to be made into its own blog post.
In general you can get most of old Linux stuff to work if you find and install the relevant libraries, the main issue is that these libraries tend to be spread all over the place and sometimes even conflict with existing libraries.
With Windows you also need to do something similar with older games (e.g. use dgVoodoo2 to play old Direct3D and Glide games) but since Windows comes out with a lot more stuff and that stuff tends to be backwards compatible for the most stuff, there is much less to worry about.
There was an article a couple of years ago about taking binaries from either windows 1 or 2, changing a few bits of the header and it would run fine.
Edit: actually it's covered in the Wikipedia article https://en.m.wikipedia.org/wiki/Windows_1.0x
It's an old citation but here's the snippet:
"Due to Microsoft's extensive support for backward compatibility, it is not only possible to execute Windows 1.0 binary programs on current versions of Windows to a large extent but also to recompile their source code into an equally functional "modern" application with just limited modifications"
I haven't touched windows in probably 15 years though so I can't speak for any of this. Funny, I was a Windows software developer for a decade and now I know nothing about it. I don't even know if the debug tools I used to use made the leap to 64 bit
Windows had one for DOS, Windows 16, "posix" and "os/2" with the last two in air quotes because it was only a subsection and they claimed mission accomplished - I think it was specifically to satisfy some government requirement but don't use me as a reference here. I don't think it could do os/2 "Presentation Manager" for instance.
Regardless, it didn't come free - there's people up in Redmond who had that as part (or maybe all) of their job. I would have done that - maintain an esoteric part of Windows for a Microsoft salary? That's the kind of job where you have almost no boss. Sign me up.
There was a Presentation Manager subsystem for NT that could run 16-bit OS/2 graphical programs, but it was about as hard to come by as buying a single LTSC license is today.
The lesson of DESQ is to design software to run on the computers of tomorrow and don't worry so much about the computers of today. That sounds stupid to me as well but neither of us have yachts or private jets so what do we know. It's about colonizing the future.
I wouldn't be surprised if FreeDOS could spin this up.
https://virtuallyfun.com/2011/03/27/desqviewx/
There's also a long running ticket in dosemu2 around some issues with DesqView/X https://github.com/dosemu2/dosemu2/issues/606
In some more years it will probably be working fine there.
DesqView/X was graphically multi-tasking DOS programs and running X applications the year after Linux was released. This was the Windows 3.1 era ( no cooperative multitasking ) and before OS/2 2.0 was out. Amazing.
Like everything else at the time though, it could not run Windows applications ( Microsoft Office ) and so it was doomed.
Old Microsoft put lots of thought into extensibility of APIs and makes it so that the old interfaces still work when they introduce new functionality.
New Microsoft rewrites components from scratch and deprecates the old one every few years, and doesn't bother to shim over the old interface.
The former group has it such that if your app was well written circa 1997-2001, it works well on the current release.
The latter group has it so that you have several different copies of .NET on your hard drive and the "recommended" UI libraries for new applications has changed a lot, and the new hotness from a few years ago is deprecated.
This seems to be a trend across the industry, not just Microsoft. And it's a real shame. It makes it too risky to use a lot of shiny new things in real projects.
The Microsoft-specific variant of it is something I've seen up close. One of the issues always struck me as confusing interface and implementation. There isn't a good recognition of the fact that when you write against an API, you code against an abstraction, not a particular implementation. If your interface is good enough, you can do the rewrite treadmill thing to justify your current bonus or whatever, but you can point the old interface at a new implementation without most callers knowing the difference.
So, I think a good example of this working relatively well would be Windows audio. The WinMM API still works. They rewrote the audio stack a couple of times, and introduced new APIs such as WASAPI and I forget the newer one. Winmm isn't broken. It may not have access to all the latest features, but it works.
In contrast, all too often they discard an entire API because they want to rewrite the components underneath. But the I in API stands for interface. A good interface can survive rewrites of what's underneath.
Absolutely!
But a good interface is also a really difficult thing to engineer, in part because it seems like a relatively easy thing. The gotchas don't become apparent until long after you ship.
Sometimes I wonder if some of this is just cost-cutting. A difficult task is an expensive task. Other times, I wonder if it's because API design is an actual specialty, and there are too many devs doing it who don't have the chops for it.
Some interfaces that are very simple can allow a broad range of implementations but cannot not expose their capabilities. On the other hand, some interfaces that provide good control over runtime characteristics etc. already give away the implementation.
If "API" were primarily about abstraction, it would be called APA.
One point I'll offer is that ability to shim an old interface onto a new implementation validates the design of the new thing. If you can't shim them, chances are there's some necessary problem you aren't solving, and possibly aren't aware of.
Concrete details of all these things will alter the discussion. I think my example of audio is a good one for the strength of "the old way". The old interface works, even though it does vastly different things than it did in 1995. Like you say, maybe there are some features you can't get with the old interface -- that can be OK. But they didn't break it.
The Win32 subsystem on NT-based Windows began as such a shim too. The NT native APIs sometimes look very very different. Most people don't know this. eg. Most people don't know that renaming things isn't its own syscall that operates on a source filename a la unix rename(2), which is what Win9x did -- that there's transparently an NtCreateFile() call that happens inside MoveFile() ... Philosophically, the NT API "hates" doing things based on filenames, most operations that Unix or Winapi have as filenames operate on handles... But nobody needs to know, the Win9x API is the public API.
Deprecated C++/CX and .NET Native, while neither Native AOT nor C++/WinRT are proper replacements in capabilities, replaced UWP/WinUI 2.0 with WinAppSDK/WinUI 3.0 with lots of missing capabilities.
I highly encourage you to take a look at the work Microsoft did with the XBox backwards compatibility for the XBox One X/S; unlike their naming teams, MS have people who care deeply about this stuff. Not only did they spend a lot of time making sure that most games work on the One X, they spent time doing things like having the newer platform upgrade the games on the fly where possible.
MS absolutely has people tinkering with their old APIs, sometimes to quite good effect.
Really old citation, 1995...
>There was an article a couple of years ago about taking binaries from either windows 1...
The below article seems to go more indepth and was written in 2020, might even be the one you were thinking of:
https://soylentnews.org/article.pl?sid=20/05/10/1753203
>As previously noted, Windows 95 dropped support for 1.x and 2.x binaries. The same however was not true for Windows NT, which modern versions of Windows are based upon. However, running 16-bit applications is complicated by the fact that NTVDM is not available on 64-bit installations.
>After letting NTVDM install, a second attempt shows, yes, it is possible to run Windows 1.x applications on Windows 10 [32-bit].
>FONTTEST also worked without issue, although the TrueType fonts from Windows 3.1 had disappeared.
No way. I'll need major citations on that. Wikipedia for one, firmly disagrees as does every book I've read on that history.
Windows backwards compatibility is also pretty phenomenal if you DON'T know what you're doing and are important enough.
There is the famous case about Windows 95 detecting SimCity and then switching to a more careful memory manager as SimCity had quite some use after free problems, which would crash otherwise.
https://www.joelonsoftware.com/2000/05/24/strategy-letter-ii...
This is a point on which I give Microsoft high praise, and they have my great sympathy.
The issue for Windows is existential -- a large percentage (perhaps a majority) of people would ditch Windows in a heartbeat if they had to replace their software because of a new Windows version. Backward compatibility is Microsoft's moat.
It has been worth it to Microsoft to put serious resources toward that end, and they've worked miracles in terms of backward compatibility. It really is amazing.
And I have sympathy for them about it, too, because I guarantee that Microsoft would rather be able to run without carrying that burden too much.
I think this is the main reason why they are extremely forceful about updates. If everyone is using the same version, backward compatibility becomes easier because you don't have to keep it for as long.
And then I opened again a windows laptop...and the words than came to mind were "missing the forest for the trees".
Like, I feel that Microsoft really cares a lot about each and every tree, and went above and beyond to make the most trees happy and cut down as few trees as they could at every iteration. And we lauded then for that, cheering at every tree that could stay alive.
Except now the forest is really badly planned, it grew and expanded a lot but without enough prunning really, each user has to carve a path with a chainsaw to get anywhere livable, we regularly fall into forgotten valleys with runes to unlock lost technology.
I won't argue it needs to be a walled garden breaking new at every release, but there must be a better middle-ground for all of this.
It's hard, really hard, so I don't really blame them for failing. But, Apple mostly managed it. AppKit/UIKit is pretty much a direct path from NeXTStep in the 1980s. 30+ years of evolution, without breaking the whole API until SwiftUI came along. Pretty impressive. Apple should get more credit for that.
Just thinking about the two processor architecture transitions and the whole OS7 -> OSX switch, they really have an expertise no other company seems to even get close to.
Offering emulation where compatibility is broken definitely helps.
[1] https://learn.microsoft.com/en-us/windows/apps/get-started/#...
[2] https://learn.microsoft.com/en-us/windows/win32/
[3] https://learn.microsoft.com/en-us/windows/win32/hidpi/high-d...
"if you're creating a new Windows app from scratch, it is highly recommended that you create a Universal Windows Platform (UWP) application. UWP applications automatically—and dynamically—scale for each display that they're running on."
but no fault on you for being confused, Microsoft announces changes in strategy so fast they can't update their docs to keep up, so their once great MSDN has become a rats nest of contradictory advice and recommendations.
At any rate if you've tried to do Win32 hidpi you will know that it hardly works and this represents defeat by Microsoft. For example hidpi is only even attempted for windows created from dialog resources, but most aren't, so if you run any classical win32 apps they still have tiny 16x16 icons everywhere, tiny fonts, basically unusable on modern screens. Apple went through this pain with the original Retina transition where icons were blurry on old apps for a while, but they updated all their own apps and brought the ecosystem with them on that journey. Microsoft never did.
And it's all like that. Win32 has barely evolved for decades. There are occasional new magic flags and an ever-greater pile of hacks, but there's been no serious attempt to keep it competitive. The assumption was that everyone would migrate to .NET and WinForms but that didn't happen for various reasons. By then, Win32 - never a particularly well designed or well loved API even inside MS - was so aged that they felt it'd be easier to start over from scratch. And once that Rubicon was crossed, they did it again and again.
Motif is pretty good here too.
But Gtk5 port will be total madness. No more modal windows and no more traditional tree view. I can agree that it removes a lot of problems and maintenance from the Gtk Team, but the cost for the application developers is huge.
But just as Win32API we can all still use Gtk2
Port it back to its original toolkit, Motif, now that that's open. Won't be needing an update after that ;)
Very Windows 3 with iconised windows on the desktop.
Of course gimp would keep working if you keep it on gtk3.
As long as Gtk continues to have backwards compat, old/unmaintained apps should never just 'stop working'.
And it will be the same once Gtk3 is phased out: https://docs.gtk.org/gtk4/migrating-3to4.html
Which is odd because desktop user interfaces haven't fundamentally changed in the past two decades. Theoretically you could generate UI code for Win32, Qt, GTK, and others from a common markup format.
In theory yes, but the attempts I've seen at this run into issues with things like widgets present on one platform not being present on others (e.g. Win32 has no miller column widget like Cocoa's NSBrowser) and the UI toolkit chasing identical behavior between platforms.
For this sort of idea to work, I think an approach that fills gaps (following previous example, providing a Windows implementation of a miller column widget to mirror NSBrowser) and doesn't try to fight the behaviors of the UI toolkits it's built upon is what's ultimately required. Without that, an approach that reimplements everything from scratch is probably better.
Neither does GTK, Qt or pretty much any other toolkit I've used. It's not exactly a great example of a standard widget.
We could also limit our definition of modern UI toolkits to only ones that support the Touch Bar and POWER9, but it's kinda silly. The vast majority of interaction metaphors are the same between systems. If your OS has a different or unique function that the vendor wants to see used, it's up to them to expose it well.
I'll give you the touch bar, since that very much does interact with the way GUIs work, but if your graphical toolkit needs to care about the CPU architecture at all I feel like something has gone terribly wrong. The closest thing that seems reasonable is to allow graphical acceleration, but requiring even that is a great way to ensure that things will break on a regular basis.
Lazarus's LCL components pretty much do that. One source, can target Win32, Qt, GTK, and Cocoa.
Widget frameworks are very complicated and have intricate APIs.
With present day computer technologies it is difficult to mutate an API or interface that others are implementing or using. I think people also rely on side effects that aren't promised by APIs, which makes it harder to change things.
I want to be capable of refactoring my logic and code without breaking my data structure and I want to change my data structure without breaking my logic. These are at odds.
How many times has a library upgrade caused a compiler error for you?
When someone implements my Java API, it is difficult for me to change it. Breaking software upgrades is my common experience upgrading software libraries.
My idea is that we should trace the method names, field/properties names and parameters used of methods in an Abstract Syntax Tree of code and then turn it into a structure and hash the symbols in the structure to correspond to in-memory layout index offset. (We put the data for the member symbol for example "children" in the same memory position every time)
We can use heuristics with this AST that from any given symbol name, there is a traversal from one symbol to another.
My idea is to handle the seamless migration of types - such as replacing one type for another, new type, merging types, splitting up types into members, changing the associations of a type, changing the plurality of the type (is it a 1-to-1 or 1-to-many mapping or many-to-many mapping?)
The idea is to create a struct data layout from an AST symbol trace and turn it into deterministic arrangement of data at the machine code layer.
When I refer to a symbol on a computer, it is at a numerical position in memory, relative to other symbols, such as relative to a symbol with RIP relative addressing in assembly.
If the same symbol corresponds to the same numerical position every time regardless of the AST, we get binary compatibility regardless of the AST that created that symbol traversal.
If I change the AST, but the data has the same underlying associations, the data structure can be inferred. For example, git detects file moves based on file hashes.
We could define a list of keywords and hash them into buckets and then people use these symbol names and they get binary compatibility for free.
For example, if a library upgrade changes the object hierarchy and splits something off into a new object, or introduces a plurality (one to many) where there was none before? Such as having multiple addresses for a customer, or multiple email addresses and contact numbers for an account where previously there was only one.
The hash of the relationship diagram can map to a struct layout deterministically.
For example, take the following data associational hierarchy:
bussiness_unit-> department-> product -> manager
and managers now need to be responsible for departments, the associational diagram changes to
business_unit -> manager -> department -> product
there are fields on business_unit to manager and children of manager object for department and children on department for products, or something like this.
or similar. This kind of schema changes should be programmatically deterministic, because these kinds of migrations are so common.
This idea could also solve database migrations too.
can't talk about GTK but Qt broke C++ API compatibility once between 2012 and 2023 for Qt 5 -> Qt 6 (and really porting from 4 to 5 and 5 to 6 is not particularly complicated), I wouldn't say that it's fair to call this "makes a point of ignoring backwards compatibility with their releases"
GTK2 will continue to be included with Debian 12 ("Bookworm") when it's released later this year (knock on wood). Any apps written for GTK2 20 years ago will still work against it as the GTK2 API (and ABI) has remained backwards compatible all that time.
(OK, GTK2 is EOL and not receiving any more updates since Dec 2020. So that's not great. But it does still work, and so will the apps that use it.)
I did hunt down some old version of Gdk_pixbuf and made it to build (at least on my system)[1] so it isn't that big of a deal.
I attempted removing the dependency at some point (when i wrote the text at the second site i hadn't explored that part of the code much so i was under the impression that it made little use) and while possible, it needs a lot of functionality to be reimplemented in terms of fpimage (graphics functionality that i guess didn't exist when Gdk_pixbuf was originally used). I did stub out all the Gdb_pixbuf code though and while glitchy, it does work[2].
I might poke on it now and then but i'm not part of the Lazarus dev team and whenever i fix any bug on Linux it is for the Gtk2 backend since that is what i'm using (i have no plans nor interest for the later versions of Gtk).
[0] https://www.lazarus-ide.org/
It's very easy to understand.
QT is a commercial and de-facto proprietary product and the development model is: do what the paying customer wants.
GTK has no customers and after it was taken over by the GNOME crowd the development model is to deliberately sabotage the FOSS ecosystem. Small long tail projects can not afford to follow the relentless stream of backwards incompatible changes produced by upstream and die off. Even big projects like GIMP struggle with this. The result is a broken ecosystem which serves certain market participants (e.g. that offer desktop operating systems) very well.
For people who thought they are smart its of course a fuckery.
The most painfull came from breaking the drawing code: Gtk2 moved to Pango/Cairo, Gtk4 moved to GPU Textures. Gtk5 will now break ageing view models. And i hope Gtk6 will break the single threading of the whole Gui.
Flatpak looks like it may partially fix that problem for desktop apps. Certainly, Flatpak makes it more realistic to support a commercial app on Linux.
For gaming, somewhat ironically, the Windows APIs are serving to provide that compatibility role. If I wanted to reach Linux gamers, I think I would write a Windows game that was properly tested for good compatibility and performance on Proton. Not only can I probably effectively reach more Linux desktops that way today but my game will probably still run well a couple of years from now whereas a “native” Linux binary will probably have broken by then.
There was a time, when I was young, backwards compatibility was a big part of our job. To me, it seems every other day QT and GTK makes a point of ignoring backwards compatibility with their releases, making Application Development hard.
I admit, I do *not* understand GTK/QT development model at all. But I think having that compatibility is one of the reasons of Linux's success, the rule of "Do not break user space".