> That's great that they have the bandwidth to do that, I commend them for it, but other projects don't have the time to maintain and work around deprecated APIs forever.

That is the thing, Lazarus and LCL are almost entirely made by volunteer developers working on it in their free time and yet they manage to not break things unlike other projects that have corporate backing and fulltime developers.

It isn't a matter of bandwidth, it is a matter of caring about the work and time other people have spent on their platform.

> If they want to help avoid this in the future for other programs, I would urge them to try to write some kind of compatibility wrapper.

That would be pointless, LCL itself is already a compatibility layer for GUI applications (LCL is primarily a GUI toolkit) and Gtk2 is just one of the several backends. If they had to write Gtk3 support might as well do the Gtk3 backend anyway (which is what they did, Gtk3 work is already in progress, it just isn't as stable as the Gtk2 backend).

My point was that they wouldn't have to waste time on the Gtk3 backend and could focus on other things if Gtk3 didn't break backwards compatibility. Instead they'd add support for the new stuff Gtk3 introduced and use their limited time on more important things.

> It would mostly the same amount of work as doing it upstream, and upstream seems to have no interest in doing it since they would rather focus on helping people get their apps ported to the new way.

If upstream didn't break backwards compatibility with Gtk3 they wouldn't have to focus that either though and everyone would be spending their development time on what their applications are all about instead of keeping up with their depencencies' breakage.

> But this would only work for some things, other things simply can't be provided with any amount of backwards compatibility.

Which only happens because the upstream developers broke backwards compatibility.

> If you take that approach, you really could say the same thing about these other projects that don't want to upgrade their apps to GTK3/4, etc. Of course they won't do it because it's not fun for them, those projects don't really care about the toolkit, *they just want to have some kind of GUI quickly so they can then focus on the rest of their program*.

But that is exactly the issue here, applications aren't using Gtk (or whatever) because they love Gtk itself as an entity, they do it because Gtk provides something - a GUI library - that they want so they wont have to make their own and instead can focus on the stuff that actually matters: their application's functionality. It makes absolutely perfect sense that they wont want to waste time (especially if they are not working on their application full time) to keep up with Gtk's breakage.

Libraries in general are a means to an end, not the end in themselves.

Having a library stop being compatible with its previous versions means that a developer has to stop working on the application they are working on (the stuff that matters) to waste time on something they initially picked up so they can save time - so it makes sense to try and avoid that.

> At least that's been my experience with them anyway, I sympathize with that but it also conflicts with the need to make changes in the toolkit. So eventually somebody has to compromise somewhere.

Changes can be made in the toolkit without breaking existing applications. They may not look as pretty as if you break things and rebuild them, but at the same time you keep existing code working, existing applications running, existing knowledge valid and help make a more reliable platform for both developers (who can rely on your platform to help them instead of wasting their time) and users (who can rely on your platform to have their applications working even if the developers abandon the applications).

It is even good for keeping open source applications - it makes it easier for new developers to pick up some abandoned code and help keep it working. As an example some years ago i got MidasWWW working:

https://i.imgur.com/W37vhBW.png

...the codebase of which was at the time almost 25 years old. Yet because Motif didn't change its API, i barely had to touch the UI. It took me an hour or two (i do not remember, it wasn't much) to get it working and the vast majority of the changes i had to do were some old C-isms and 32bit assumptions that modern GCC on a 64bit machine complained about. In fact the only UI-related changes i had to make were because the Motif version the browser was written for had some incompatible changes from the "base" Motif at the time (ie. it wasn't exactly Motif's fault but whoever distributed their modified version).

> I'm sorry I really don't understand what you're saying here. The 20000-300000 developers should easily be able to join together and use their numbers to come up with a solution that is much better for them, no?

No because they all work on different projects.

What i mean is simple: if Gtk (or any other library that breaks backwards compatibility, while Gtk is a popular example that causes a ton of applications to waste time keeping up with it, it is certainly not the only case - SDL1.2 to SDL2 was another case, though at least AFAIK there is now a drop-in SDL1.2 replacement wrapper that calls SDL2) makes a breaking change because one or two of their developers wanted to make their life a bit easier, that breaking change will have a ripple effect to every single project that relies on Gtk and all the developers who work on those projects. One popular library having one breaking change, even if it was done with good intentions, by one developer can cause thousands of other developers on thousands of other projects to have to deal with it - and people do not work synchronously, this could take time.

> Somebody interested in this can just build this wrapper separately, there's no reason it needs to live in the same repo as the new version.

There are two reasons: 1. to dissuade the main developers from breaking things because, as you imply, it'd be additional work and they'd "feel" the effect of their breakage and 2. to make it much easier to keep up with any changes, if necessary.

What you describe is really having others run behind upstream developers to pick up their breakage so that the upstream developers wont have to care about breaking stuff, when what i describe is upstream developers not break stuff in the first place.

> If you want to describe new features, improved performance, security fixes, etc, as "shiny new toys" then yes, I guess you could say that. I'm not sure what the distinction here is because before you said you wanted these shiny new features?

You do not need to break backwards compatibility to provide those though.

> Xorg was at a point where they were going to have to break things intentionally, because some of those APIs are actively causing security issues and cannot be fixed without unavoidable breakage. The apps have to move to a new API if they want this to be fixed, there is no way around it.

Xorg's security issues have been greatly overstated. The server already has functionality to deny any access from untrusted sources (ie. pretend they are the only application running) so you could do that with applications you do not want to trust (or request they not be trusted, e.g. browsers), but even beyond that there are other ways to improve its security - even down to a sledgehammer-like approach of running separate nested instances. All the effort that went towards reimplementing from scratch (and doing all sorts of mistakes on their own) a display server with Wayland could have went towards improving Xorg instead and not break an already tiny desktop ecosystem.

> The rendering model has changed entirely and is now mostly hardware accelerated, so you may see major performance improvements on e.g. high DPI displays.

HiDPI shouldn't matter much for performance unless the previous implementation was done on the CPU, but that has nothing to do with the rendering model.

Immediate graphics APIs can still be batched and in fact this is what, e.g. most OpenGL implementations did for years - when you request to draw a triangle, the implementation wont draw that triangle immediately, but keep the request in case more triangles and other commands come later. As long as what you "perceive" is the same, it doesn't matter if you perform an immediate mode call "immediately" or keep it around for later use. This can be an issue with single-buffered output, so you'd need to be able to do that immediate output too, but most applications tend to do double-buffered output anyway. And at the end of the day, you still perform draw calls even with a scene graph, you just have better ways for batching those calls.

Note that i'm not against the scene graph approach (though it does need to have some "way around"), just saying that you can optimize immediate mode APIs a lot while preserving them.

But there is also another way: have both. Widgets can opt-in the new approach if they need the extra performance (after all not everything will need it) which will allow applications to keep working while converting to the new approach piecemeal. Old widgets will simply have a "canvas" scene graph node created for them where they can draw using the old API and new/converted widgets will use the pure scene graph.

Yes, this can introduce issues, but again, bugs can be fixed. And for a library with the popularity of Gtk (note that i do not specifically refer to Gtk here, it'd be the same for Qt or any other UI library that wanted to switch from immediate mode to scene graph without breaking compatibility) it wont be hard to find programs to test this against.

There are ways to solve this, and other things, if the developers care about not breaking backwards compatibility.