Gtk4 Tutorial
github.com
github.com
I still miss Visual Basic + WinForms
If you don't mind running Linux binaries in Windows, then take a look at GAMBAS, a solid, contemporary Object Basic VB equivalent:The compile times are also excellent, the compiler itself is decently friendly with its error messages and the runtime itself lets you write code that feels safer than C++ in most cases. Oh, and it really comes with "batteries included" - you'll find components for everything from UI elements, to database access, to working with events and such.
Here's actually a large list of all sorts of software that has been created in it: https://wiki.freepascal.org/Projects_using_Free_Pascal
Now, the bad things. It's basically dead.
Sure, there are contributors who keep working and they do have a roadmap here: https://wiki.freepascal.org/Roadmap
However, there is no hype around Pascal, many people disliked the language for a variety of reasons. No one also seems to care much about its advantages for some odd reason, instead people are talking about Electron, JavaFX/OpenJFX, .NET MAUI/Avalonia or other new technologies that attempt to do what Lazarus did many years ago, with varying degrees of success.
Sadly, to me it seems like technologies live or die by how much hype there is around them and how many thousands of man hours people are collectively willing to put into them to create brilliance. And Lazarus doesn't have that anymore. Compare both the IDE, its approach to things, as well as Pascal nowadays with the likes of Rust - the latter gets hundreds of libraries created for it, thousands of tutorials and will have developers that literally grow up to like and use it. The former feels neglected in comparison, you won't be doing web development while utilizing super popular libraries that attempt to cover most concerns like Rocket (https://rocket.rs/) does. You also won't be interfacing with the likes of GraphQL, or even RabbitMQ, due to a lack of interest in developing libraries for those, as well as many other technologies. It might be a similar story for something like YAML or TOML. Nor will you find many good books and tutorials, maybe apart from this nice piece of writing: https://castle-engine.io/modern_pascal_introduction.html
{$mode objfpc}{$H+}{$J-} // Just use this line in all modern sources
That screams "lots of old cruft". Poking around the rest of that tutorial, I see crufty things like inheritance, manual freeing of memory, and a whole section on CORBA.I can't speak to why Pascal died, but I would guess that historical baggage is the thing that's preventing a revival.
After all, JavaScript didn't remove the function(){} syntax either when the arrow syntax was introduced. Moreso, React hasn't remove class based components either as of yet, even though we have hooks and function components now.
I actually find myself wishing that Java 8+ hadn't removed so much of the standard library without backwards compatible ways to reintroduce the logic, since now the transition from 8 to newer releases is a massive pain, especially because of migrating a 1M SLoC enterprise app is no small feat.
So yes, Pascal has baggage but it's not always a bad thing.
"VBLANK-synced animation with simultaneous multi-touch drags" was not a thing in the 80s, 90s and barely the 2000's. Now it's a basic requirement.
Plenty of other examples of features like this, which don't change the demo code for a "Hello, World" example, but have massive implications for the internal structure of GUI toolkits.
Also, there's more focus on cross-platform now, which adds its own complications.
We are talking about Windows now, and there is zero cross-platform compatibility in Microsoft's UI frameworks (unless you mean cross-architecture between x86/amd64 and arm32/arm64). It is against their interests and they will never do it, just like Apple.
And it doesn't matter what MS or Apple want or do, there are numerous cross-platform UI toolkits available, and there always will be, because a bunch of software developers are not going to play by their rules.
The amount of crap we have to wade through is crazy.
I tried to follow the suggestions. WPF, Silverlight, UPF then XAML islands? But it's mostly a mess / trash. I feel like Silverlight has been sunset. WinRT stuff is gone? WPF - not sure.
Even weirder, they can't seem to get the designer working (this was what you could use to drag and drop control with way way back).
It's like billions are getting flushed down the toilet over at Microsoft. I've also tried using their HTML solutions / a somewhat similar mess - not sure even they have had any clue what they are doing for last decade.
Maybe the new hotness will be .NET MAUI?
WinForms itself is still around to this day, and Microsoft is actively updating and supporting it on the latest .NET versions. You can just pretend that none of that other stuff ever happened. I've been writing WinForms apps for 20 years, since the initial Visual Studio .NET beta. It still has that same high level of productivity that Visual Basic did.
Felt like it was a similar "magic" to the older skool BASIC of the previous era.
Also:
Linus Torvalds allegedly said:
"I personally believe that Visual Basic did more for programming than Object-Oriented Languages did. Yet people laugh at VB and say its a bad language, and theyve been talking about OO languages for decades. And no, Visual Basic wasnt a great language, but I think the easy database interfaces in VB were fundamentally more important."
Xojo is proprietary, free for non-commercial use, software platform that I'm told is quite similar to Visual Basic. I never used VB so I can't vouch for the similarities, but it looks similar. Usable on Linux, Apple, Windows, and also generates code for iPhone apps. I suspect its users are overwhelmingly Windows programmers and that windows is its native land.
Very easy to learn and use, nice IDE. Has all the common widgets/controls you've come to expect.
That said, I second the Lazarus recommendation, though my needs are simple enough that Tkinter suffices for me.
The problem with it is that they do everything ‘the right way’, which is not the easy way. So if you want to show a list of 10 things, you have to implement an interface that would still work fine if the list suddenly had 100000 things. Your documents are supposed to use an interface that has undo/redo all the way. Your interface is created out of components that have built in accessibility and internationalization support.
Nobody cares about that when you’re just building a basic app with one form. So getting started is hard.
I tried to do my part by removing boilerplate using macros [1] [2], but it is still complicated to design GTK apps. Even more now, because Glade has been deprecated for GTK4 and no visual editor is available to replace it for now, making developers manually write XML while exploring the sparse documentation. This is a regression for developers' experience.
I am really trying to like GTK after using Qt a lot in the past, but there is just too much effort. Things should be as simple as VB6/WinForms. With no visual GUI editor, I find myself to just write CLI tools in Rust instead of going the extra mile and creating GUIs.
When creating a project, I get an empty .ui file with no possibility to add any widget. This project still seems in its infancy, or I am doing something wrong. It also seems to enforce a "framework" instead of just being a graphical .ui file editor. How I am supposed to use this if I am using Rust instead of Python, and Relm instead of their MVC framework?
I miss Glade (and it had issues!).
However adding a GtkApplicationWindow and a GtkButton inside of the component tree is not updating the preview area. Adding a know valid GTK3 .ui file [0] does not update the preview area either.
Seems like the "preview" button is also missing from Glade. Oh well, let's edit XML files afterall. :)
[0] https://github.com/MicroJoe/gtk_liststore_item/blob/master/g...
It's just a .ui file editor, so unfortunately you can't use it with Relm. Maybe someone could write a tool that converts .ui files to Relm code. Although I guess it would be a one-way transition, so perhaps not so useful.
[0] https://github.com/MicroJoe/gladis/blob/master/gladis/exampl...
The "gtk_liststore_item" crate seems useful, have you thought about starting a conversation with the gtk-rs developers to try to upstream something like that?
[1]: https://gtk-rs.org/gtk4-rs/stable/latest/book/interface_buil...
I have not started to discuss with gtk_rs team for the moment.
Since this second crate has less "stars", I guess the gladis crate should be figured out first: incorporated, or documented in gtk-rs so that it is made obsolete.
EDIT: here is the feature request to merge gtk_liststore_item into gtk-rs: https://github.com/gtk-rs/gtk-rs-core/issues/297
The gtk4-rs book has a tutorial on them: https://gtk-rs.org/gtk4-rs/stable/latest/book/interface_buil...
Gladis seems to wrap the child widgets in a regular Rust struct. The composite template stuff in GTK uses subclassing to make a new widget wrapping the child widgets.
GTK has a better approach imo - the issue is that the macros for subclassing in gtk4-rs are _really_ verbose and confusing. You need two different structs, with several trait impls on them. Adding GObject properties is verbose and tedious. Adding methods on the widget is confusing - it's confusing which struct the method goes on and how to access the widget in each part.
Overall I liked GTK for the end result it produces, but not the API. I've been meaning to give Relm4 a try - it seems like a much better way to handle state and widget composition in Rust than the vanilla GTK stuff.
I didn't find it that complicated but I've also worked on plenty of GObject code in C. It's mostly a direct equivalent to what the C code would look like. I think part of the problem is that some of the examples are not really structured well, the mod/imp split makes it a lot more confusing than it needs to be. In my opinion you can just skip putting methods on the private struct and only put it on the public one and that also simplifies it a lot.
But Relm should be a step up if you like the declarative style.
* Automatically figuring out which parent objects the class you're subclassing derives from, instead of having to import and then list out all of them individually. This is for the glib::wrapper!() macro. * Automatically filling out ObjectSubclass, and WidgetImpl, etc. * Helpers for properties and signals * A flat list of methods, instead of the public/imp split
The bigger issue that Relm solves imo, is state management. I feel like I had a difficult time figuring out how to share state between widgets. You end up with lots of OnceCell, Rc, and RefCell, and it quickly becomes confusing, especially when you start subclassing GObject and making your own objects.
As soon as I think of a good project to work on, I'm going to try out Relm4 and see if it is better than gtk4-rs.
AFAIK this is a language limitation, there is no way in a Rust macro to take a type and get all the traits that are implemented for that type. It would need some kind of reflection API. Maybe someone could try it with this crate? https://crates.io/crates/reflect
"Helpers for properties and signals"
There are some open issues for this: https://github.com/gtk-rs/gtk-rs-core/issues/27 https://github.com/gtk-rs/gtk-rs-core/issues/214
"A flat list of methods, instead of the public/imp split"
You can already do this in your code and use "pub fn" and "fn" like normal.
"I feel like I had a difficult time figuring out how to share state between widgets. You end up with lots of OnceCell, Rc, and RefCell, and it quickly becomes confusing,"
I think you are supposed to use bind_property and the gtk::Expression objects to do data binding, though that part is not so convenient to use from C or Rust either.
As for font rendering, it is kinda broken in gtk3 too. I recently switched to roboto condensed and while qt applications look fine the spacing between letters in gtk3 apps is totally broken.
GtkMenu, GtkMenuBar, and GtkMenuItem are gone so you have to use GtkPopover* instead which has this issue.
I would love to not use adwaita except gtk4 has crippled the ability for users to theme their apps, especially when libadwaita is used. Also gtk3 does not have this issue even with adwaita.
Maybe it would be better if somebody fixed that thing with the menus. But I think IIRC if you wanted transparency in old X11 without a compositor, the toolkit had to copy the region under the popup, and then blit it to the popup... Yes, this meant that content in the transparent region that changed would be stale until the popup went away. So someone would have to decide if that would be a viable solution, or maybe someone could get away with just using the existing XShape stuff in GDK somehow.
As for the solution, why not remove shadows for non-composing wms?
The issue is not the shadows, the popup window itself is shaped. All that black region is supposed to be transparent. To fix with CSS you'd have to get rid of the "arrow" and make the corners square. But that may reduce usability of the popover since it no longer "points" to the parent. Maybe it could be positioned inside the popup somehow.
Can I? I haven't been following GTK+4, but GTK3 managed to break every theme except Adwaita, and the developers were pretty clear that having themes is not a priority for GTK+. There's also this website https://stopthemingmy.app/ which says 'don't theme apps, it breaks them' so it implies we're stuck with Adwaita.
There was a tweet going around a while ago that I'll try to re-state. Adwaita is not really a "theme" it's more like a CSS framework that you build your app on top of. Trying to swap out the theme is like trying to take a site built for Bootstrap and putting the CSS from Foundation on top of it, you might be able to hack it to sort of get it to work but what you're doing is combining two things which are fundamentally not compatible. Hopefully that helps explain why the method that people were using for third party theming in GTK3 was unreliable.
In GTK4, the Adwaita theme has actually been removed from GTK and moved into libadwaita. That could mean some changes for some things, but not other things. Will all GTK3 apps port to GTK4 and libadwaita? Probably the GNOME ones will, but other apps might not. In that case it would be up to those developers to come up with a solution for theming, they could try to base that on CSS, or they could do something else.
> Will all GTK3 apps port to GTK4 and libadwaita? Probably the GNOME ones will, but other apps might not
I have a question. Does it make sense to start new apps with GTK3? E.g. if I want my app to look at home in MATE/Xfce (which currently use GTK+3), and don't want to touch GNOME in any way, does it make sense to write it in GTK+3 (using GTK+2 HIG)?
Personally I don't think the look needs to be a major factor in your decision though. If you wanted some new features from GTK4 and wanted it to "look at home", and you really wanted to not use any GNOME APIs, then you could avoid using libadwaita and apply the theme yourself. Libadwaita is only useful if you want to follow the current GNOME HIG. I think if MATE/Xfce want to upgrade from GTK3 they would have to do this eventually anyway, and it would actually probably provide a better experience than GTK3 themes did. Also, GTK never had a HIG. You're thinking of the GNOME HIG, and the GNOME 2 HIG is pretty out dated. I think even MATE/Xfce would want to change some of those things in there that we know don't work well with the benefit of 15-20 years of hindsight.
GTK is used by a lot of projects that are unrelated to GNOME, but unfortunately GTK still lives under the GNOME umbrella, and the GNOME developers are an unbelievably antagonistic bunch.
I think the GTK project is a huge success and an open source triumph. I have an old app I started back on 1.x in the late 90s, would be great to port from 3 to 4.
There are better options aren't there? There must be something amazing about it I don't understand - can somebody enlighten me?
For me it's also one of the better options for a Linux toolkit with decent Rust bindings. The Rust-native toolkits aren't quite there yet, but I'm watching this page: https://www.areweguiyet.com/
Maybe on other operating systems. It looks fine on Linux, I don't care much for anything else.
Client-side window decorations: ugh. I miss being able to see at a glance which window has input focus, even if some of them are partially covered. I miss having consistent grab areas for all windows. I miss being able to click or drag any part of the title bar without having to avoid whatever widgets some clever app developer decided to shove into that space. I miss consistent keyboard and mouse controls for rearranging windows, configurable in one place. I miss small title bars. I miss window frames that draw correctly without a compositor.
A theme engine that ensures all themes are broken: Gtk complains whenever the desktop theme contains something that is out of spec, and seems to change the spec with every minor version. The result: Unless you only use the officially blessed and version-matched theme that comes with your version of Gtk, it constantly belches warning messages into ~/.xsession-errors, needlessly increasing wear on the SSD, and making it a pain to wade through all the Gtk spam if you ever have to use that log file to troubleshoot a real problem. Why even have a theming engine if no theme can ever hope to work properly for more than a month or two?
System tray icons: These are very useful to me, all day, every day of my life. Gtk is removing them. Various third party libraries have appeared in attempt to restore the missing functionality, but since they're not native parts of the toolkit, I doubt that any of them will ever work quite as well or become a clear choice for app developers.
A mess of an API: It looked reasonable enough at first glance, but in my (admittedly limited) experience coding with Gtk, I found that most of my time was spent troubleshooting different interfaces for the same task, having to discover by trial-and-error which ones were broken in which ways, and moving on to the next, until finally settling on one that did the job with the fewest problems. Perhaps some of those were old and deprecated, but I was unable to find documentation to that effect, nor any guidance on which bits were considered current or how to manage their quirks. I felt like the toolkit was constantly fighting me, wasting my time. It seems I'm not the only one who had trouble here: https://www.phoronix.com/scan.php?page=news_item&px=MTU2ODM
None of this is news. Gtk has been inflicting bad design decisions on users for years now, but since changing ecosystems (both as a user and as a developer) is a time-consuming chore, I have been quietly hoping that it would get better. Instead, it has consistently been getting worse. I'll miss my trusty old classic Xfce, but I'm done.
One thing that stands out as a potential limitation: Between C++ and the metaobject compiler, I have the impression that higher level language bindings for Qt are more difficult to create (and therefore more scarce) than bindings for C-based toolkits. The Python bindings seem widely used, so that's nice, but I don't know about Nim (which recently piqued my curiosity) or Rust (which is getting popular). I would rather not go back to C++; I used it a lot in the past, but it was never fun or respectful of my time.
On the desktop side, I'm leaning toward KDE. It was too heavyweight for me when I tried it ages ago, but recent Plasma releases seem to have lightened up quite a bit, and allow me to strip out much of the eye candy in favor of a more utilitarian experience. (It's still not what I would call lightweight, but it's closer than it was, and alternatives have been gaining bloat and closing the gap anyway.) LXQt seemed rough when I last checked, but if it ends up developing into something as nice as Xfce used to be, I'll definitely give it another try.
I also intend to keep looking out for new cross-platform GUI toolkits. I have noticed a few in recent years, mostly in the mobile space, but whether they will mature into well-designed cross-platform kits that cover most people's needs remains to be seen. It's not an easy task.
I think Qt and C++ is a very powerful combination; Qt core essentially covers every aspect of the C++ standard libraries so I no longer use the latter; even before C++11 Qt had good solutions to avoid copies of data structures, and to implement efficient callbacks and systematic memory management, and tbh I still use very little of the more recent C++ features; it's also possible to build very fancy looking GUIs using the Qt stylesheets or QGraphics classes if need be. And nearly all code I write runs automatically on all platforms supported by Qt; I even use Qt core on Linux based embedded systems; asynchronous services were supported long before the JS folks got a taste for it. KDE undoubtedly offers some interesting features, but slimness and platform independence are much more important to me.
> but whether they will mature into well-designed cross-platform kits that cover most people's needs remains to be seen. It's not an easy task
I think the mobile use case is too different from the desktop one to provide decent support for both in a single framework. From my point of view Qt (besides Qt core) is only of limited use on mobile platforms, and frameworks like Flutter are (up to now) only of limited use on desktops. Even if the framework would support both in a decent way, the GUI for desktop and mobile must be designed quite differently to be used efficiently; platform-independent GUI code is therefore of little use here.
- Client side decorations: You don't have to use these in a GTK app, it's only common to do this since it saves space. But if you don't like the style then yeah maybe GNOME-styled apps are not for you.
- Themes: I think this is a misconception. GTK doesn't have a real "theming engine", it's just CSS. Changing the CSS has always been unreliable and only meant for advanced users that could keep it updated. If you've ever used one of those "User CSS" web browser extensions then it's kind of like that. I really think you might be chasing rabbits on this one though, I have honestly never seen a desktop that had custom themes that didn't break at some point. The only OS that I've seen that has decent theme support is Android, and it does that by heavily restricting what themes can do.
- System tray icons: The notifications API is meant to replace this.
My prediction is that we should be able to build prod-ready native desktop apps with it within a year or so
There are some "promising new up and comers", including libUI.
If you work in the audio software domain, JUCE is likely your go-to cross-platform toolkit.
I didn't have much luck with libui (crashes, missing features, etc), and various immediate mode alternatives just require too many dependencies and other work that made integration painful. Plus, Lua bindings for these were always stale. In fact, Lua binding quality is pretty poor all around, including GTK, Qt, WxWidgets, and FLTK.
Some other lightweight Electron-like alternatives also exist.
The "rise" of Electron has occured primarily because it allows people to do desktop development using whatever it that they learned in the context of web-centric development. For some people, that's an excellent turn of events, for others, it is a horror show.
Even if I was willing to grant that GTK and Qt etc. are "crap" (which I'm not, but ...), it's notable that there are essentially zero cross-platform alternatives that could be judged any less "crappy". Either you think that nobody smart enough has tried, or this is a much harder problem to solve to your liking than it first appears.
Native, cross platform, tiny binaries, JS transpiler in the works, Android and iOS support in the works. Destroys this...mess.
See MSEIde, which is directly X11: https://github.com/mse-org/mseide-msegui
"MSEgui is a complete independent Free Pascal widgetset. It does not use any other widgetsets like GTK2/GTK3/Qt4/Qt5. MSEgui interacts on Unix directly with X11 server (like other widgetsets do). On Windows, it deals with the low level Windows GDI interface."
Although a separate windowing set than Lazarus, both are enabled by the FreePascal compiler.
Lazarus does have a GTK backend as an option on Linux.
But I'm the author of a substantial cross-platform creative/media application, and not only do we not use any RAD tools, I don't think we could. So if you "destroy this mess", I'm not sure how we could do what we do. Very few "creative" applications use stock toolkits and RAD tools.
I don't use Qt, but QML and its associated tools look to me at least as good as Lazarus.
I am no GTK fanboy but if you actually look through the linked tutorial it's quite straightforward stuff and all you need to know is C. You can't get much simpler than some of the early examples except maybe in Tcl/Tk.
If you look through an Electron tutorial it assumes familiarity with a whole bunch of web technologies and it's not any simpler.
The reason Electron and the like are popular is because developers can take advantage of their pre-existing knowledge of these web technologies and have the option to reuse code between Electron and web projects.