The problem is that GtkAda is called a thick binding which means that a lot of C-like code is refactored to Ada-style one.
So it's just not a simple generation.
Thick bindings aren't refactored code, they're a different interface. "Thin binding" means a shallow interface, possibly even autogenerated from C header files. "Thick binding" is usually abstracted, creating proper Ada data types (including the normal restrictions on them), different functions and procedures (perhaps bundling common sets of activities that would be a series of calls in the base C library), adding Ada tasks if its sensible to the system (which it may be, like wrapping around a network library, you can have the network connection handled in its own task).
It’s also worth mentioning that gcc has a command-line flag -fdump-ada-spec that will generate an Ada spec (.ads file - Ada version of a .h) from a C header for easy binding with C libraries.
I really liked this write-up and I'm getting curious about Ada, after completely ignoring it for a very long time.
My impression of the Fyne toolkit was similar to the authors. Overall I'm disappointed in Go's gui situation. After a lot of screwing around with Go's various native gui bindings, I ended up using Webview again, which is a nice package, but has the standard shortcomings of the approach.
A reasonable write-up. I would really like them to elaborate on what GUI libraries besides Fyne they used and what issues they've encountered. Gio[1] has been fairly popular, and Tailscale's Android client is written in it, iirc.
The demo on the Gio page is badly broken for me (Chrome 99 on Windows 10) - it’s mostly black, with what appears to be a text area in the middle with black text on black background. Triple clicking text doesn’t work. There’s no right click menu (as in native text areas) to show copy/paste/select all. There’s no visible scrollbar so it wasn’t obvious I could scroll down to see more UI controls.
Overall it’s a terrible advertisement for the UI toolkit and seems typical of most immediate mode GUIs.
I'm curious why there isn't a push for more support in desktop gui for Go.
Is it because desktop gui is not as supported in modern times and Go is a recent language that is carrying that attitude or is it because Go attracts more web developers in general and they already have web applications as their solution for a gui?
In my opinion, there may be two types of problems.
The first is organizational. Maintaining a cross-platform GUI library takes a lot of time, effort, and reasonable knowledge of the platforms it targets, so that would need a dedicated team of at least a few people. Which is not impossible, but you need to actually do this. The closest thing to such project seems to be Gio, but I haven't tried it, so I don't know if it's any good.
The second is technological. Most ways of interacting with (native) GUIs involve FFI, and in particular C. And cgo has known limitations and performance issues, to say nothing about the fact that using cgo make cross-compilation significantly harder. So a lot of Go projects tend to just avoid any project that involves cgo.
Valid points about FFI. That makes me think if Go devs cared enough about Desktop GUI, then they would try to make that weak point stronger. Their focus is elsewhere (networking, cli tools, web) which doesn't rely on FFI as much.
Eh a lot of people have, the issue is with Go’s memory model and how that maps to the C memory model. It requires what they call “trampolining” which caused a performance hit.
Interestingly, Rust originally used a similar memory model to Go, but then when they hit this problem decided to take another route.
This has the unfortunate side effect of making most machine learning also not practical in Go.
On the other hand, it has had the fortunate side effect of minimizing the amount of code which depends on C, which makes building and packaging software (including cross compilation) super simple.
That said, I'd like to know more about the limitations regarding machine learning. Presumably most machine learning stuff isn't implemented in C?
The ML limitations are that all the low level vector and acceleration libraries are written in C or C++. The GPU libraries are the real kicker, there isn't any great way around this except to trampoline over to C, that trampolining takes time which chews into your acceleration. Ironically Python is much faster than Go for ML because of this.
I've looked into building cross-platform GUI toolkits before and I think you're underselling the difficulty pretty considerably. To build these toolkits, you need expertise in everything from graphics programming to text rendering (which itself is surprisingly pernicious: https://gankra.github.io/blah/text-hates-you/) to accessibility and more. And then there are things which are just "regular hard" like constraint solvers for layout engines, designing a decent API, etc.
IMO, it's because the primary use case for Go isn't GUI programming.
The language absolutely is a generalpurpose language, and making great GUI libs with it is certainly possible, as shown by Fyne (yes, I know it's still new, give it time).
That being said, most people using Go build server side code and frameworks with it, aka. things that live as daemons in some rack or in a docker swarm. If there is an front-end to these kinds of applications, it's usually web based.
I have goofed around a little bit with GUI programming for Go. Fyne is incomplete, but I did find it relatively simple to slap something together. It may turn out to be a good cross-platform toolkit in the future, but I didn't like the requirement on OpenGL. Not my choice, but the utility needed to run on Windows 7 and I don't like updating drivers on the machine (risky).
Webview works ok, and you can get a lightweight Electron-like thing going that uses your existing browser. This reduces binary size greatly. I didn't try any JavaScript frameworks with it, just vanilla JS. You can bidirectional bind between JavaScript and Go too.
What I liked the most was gothic, since Tk looks good enough and runs on Windows 7 easily. Gothic is a Tk binding for Go that is quite simple to use. However, you are writing the GUI in Tk now, and you will either love it or hate it. I do have a bias for Tcl, so it was appreciated.
My use case scenario was supporting an old machine running Windows 7 with mediocre video. I ended up just using Tcl/Tk without Go since it was simpler and reduced a layer (Tcl->Go->C). When it comes to writing small and/or inhouse stuff, I found it easy and fast to just slap out a Tcl/Tk app and call it a day. I can develop on my Linux/BSD box and then just Windows specific bits if necessary and it usually Just Works(tm).
Oh, it should be noted that Python + Tkinter is a decent alternative for those of you needing executables. Pyinstaller is basically a "one-click" and works with bundling Tkinter. Roy Keene has done good work putting together kitcreator for Tcl, but pyinstaller is simpler if you don't understand the magic.
Fyne seems to be the closest thing to cross-platform GUI that Go has.
Fyne-cross is a really nice tool that can cross-compile Fyne applications for most popular systems (including android).
The libGL1 dependency under Linux is a fair tradeoff for wide compatibility - the drivers don't have stable ABI so dynamic linking to libGL1 is a must[0].
Python + Tkinter + Pyinstaller works, but does not support cross-compilation, and I've personally had some portability issues with it (e.g. under Linux, the GUI mainloop doesn't work outside of the main thread; under Windows, if you start a Process after setting up GUI, each process will create its own window, so you must start all the Process-es beforehand).
Cross-compilation would be nice. I have used asyncio to allow the GUI to run in the main thread but have other processing done separately. I am not sure I understand why you are getting a new window on Windows. Were you trying to create new windows separate from the thread the root window is in?
Actually, I didn't remember it right, it wasn't tkinter. It was probably some other popular GUI library. I just tested tkinter + threading/multiprocessing on Python 3.4.3 on Windows 7, and it works fine. I'm sorry for the false information.
I used to like fyne a lot, it is simple yet very extensible, much more approachable than other mainstream GUI binding like QT. however like OP mentioned fyne is not production ready yet, one key issue for me is IME support, it is based on glfw, and glfw doesn't have proper support for IME input.
My Archlinux installer [1] uses fyne and I found it to be quite easy and straightforward to use. My use case is quite trivial though so not sure how that scales.
> There does not seem to be a generally agreed-upon central repository for such information in Ada.
There's https://alire.ada.dev/ which is sort of like NPM or Rust crates for Ada. Obviously the number of libraries is much lower and the quality may be unpredictable.
Lazarus was a great crossplatform GUI framework to have a native GUI on each platform. You put a button on a form window, and then it calls Win32 on Windows, Gtk on Gnome, Qt on KDE, ... to get their native button.
Unfortunately, it is really lacking maintainers. It still works best on Gtk 2. They have been working on a Gtk 3 version for years. I am not sure if they have been making any progress. I guess the modern way for a Linux GUI is to have a Qt5 version or a Win32 version on WINE.
Unfortunately, they seem to have the attitude: we have standard libraries. Any library you need is already bundled with the default install of FPC/Lazarus
Yes, though qbittorrent at least has moved to it / supports it, which is how I found out about it. After an update it started with a completely different theme, and eventually I realized it had switched to Qt6 and I needed to install the Qt6 version of the theme.
You can also use the Qt5 backend for Lazarus, AFAIK many people use it instead of Gtk2 despite the latter being the default. One annoyance with that is that you need to either distribute or depend on the qt5pas library which acts as an intermediate between Qt and Free Pascal, but that might not be that big of a problem since AFAIK it is now available in all major distros.
About Gtk i'm not sure if it is lack of maintainers or simply lack of interest in the Gtk3+ backends, i remember a discussion from not too long ago in the mailing list where people weren't happy with the breakage introduced by Gtk every major versions. It can be very disheartening to spend years building the Gtk2 backend only to have to make a new one for Gtk3 and before that is finished, out comes Gtk4 breaking things yet again.
But IME the Gtk2 backend works fine. At least personally i wouldn't bother with Gtk3 or Gtk4 as these feel like a waste of time now (though personally i did submit a patch recently with fixes for the Gtk1.2 backend[0] that didn't work for some time now :-P but that was mainly for fun - there might be some practical use for it though as all the necessary .so files are like ~2.5MB, so perhaps it could be used for simple GUI apps on Linux to minimize external dependencies).
One benefit of GTK3+ is Wayland support, since GTK2 applications only support X11. But most of your Wayland users also run xwayland, so this may not be a big deal for you.
The state of their website isn't exactly reassuring. Not so much as a screenshot of their toolkit in action.
If I were writing GUI code in Ada I'd probably use the GTK bindings (GtkAda). They're maintained by AdaCore and are used by the GNAT Studio IDE so the 'dogfooding' factor is there.
Since it uses a browser for rendering, new innovations are likely to show up in browser before gtk (can use GNOGA with browser apis for tts, web rts, speach rec, etc) and same with likelihood to a new platform. For example GNOGA can be used on mobile (there is at least one mobile app currently using it) it is used on embedded platforms for UIs etc.
50 comments
[ 2.8 ms ] story [ 117 ms ] threadLanguage bindings for any GObject powered are usually automatically generated from their introspection data (.gir) generated from g-ir-scanner.
So that wouldn't be the issue.
My impression of the Fyne toolkit was similar to the authors. Overall I'm disappointed in Go's gui situation. After a lot of screwing around with Go's various native gui bindings, I ended up using Webview again, which is a nice package, but has the standard shortcomings of the approach.
[1]: https://gioui.org/
Overall it’s a terrible advertisement for the UI toolkit and seems typical of most immediate mode GUIs.
Is it because desktop gui is not as supported in modern times and Go is a recent language that is carrying that attitude or is it because Go attracts more web developers in general and they already have web applications as their solution for a gui?
Maybe something else?
The first is organizational. Maintaining a cross-platform GUI library takes a lot of time, effort, and reasonable knowledge of the platforms it targets, so that would need a dedicated team of at least a few people. Which is not impossible, but you need to actually do this. The closest thing to such project seems to be Gio, but I haven't tried it, so I don't know if it's any good.
The second is technological. Most ways of interacting with (native) GUIs involve FFI, and in particular C. And cgo has known limitations and performance issues, to say nothing about the fact that using cgo make cross-compilation significantly harder. So a lot of Go projects tend to just avoid any project that involves cgo.
Again, that's just my opinion as a Go developer.
Interestingly, Rust originally used a similar memory model to Go, but then when they hit this problem decided to take another route.
This has the unfortunate side effect of making most machine learning also not practical in Go.
That said, I'd like to know more about the limitations regarding machine learning. Presumably most machine learning stuff isn't implemented in C?
The language absolutely is a generalpurpose language, and making great GUI libs with it is certainly possible, as shown by Fyne (yes, I know it's still new, give it time).
That being said, most people using Go build server side code and frameworks with it, aka. things that live as daemons in some rack or in a docker swarm. If there is an front-end to these kinds of applications, it's usually web based.
Webview works ok, and you can get a lightweight Electron-like thing going that uses your existing browser. This reduces binary size greatly. I didn't try any JavaScript frameworks with it, just vanilla JS. You can bidirectional bind between JavaScript and Go too.
What I liked the most was gothic, since Tk looks good enough and runs on Windows 7 easily. Gothic is a Tk binding for Go that is quite simple to use. However, you are writing the GUI in Tk now, and you will either love it or hate it. I do have a bias for Tcl, so it was appreciated.
My use case scenario was supporting an old machine running Windows 7 with mediocre video. I ended up just using Tcl/Tk without Go since it was simpler and reduced a layer (Tcl->Go->C). When it comes to writing small and/or inhouse stuff, I found it easy and fast to just slap out a Tcl/Tk app and call it a day. I can develop on my Linux/BSD box and then just Windows specific bits if necessary and it usually Just Works(tm).
Oh, it should be noted that Python + Tkinter is a decent alternative for those of you needing executables. Pyinstaller is basically a "one-click" and works with bundling Tkinter. Roy Keene has done good work putting together kitcreator for Tcl, but pyinstaller is simpler if you don't understand the magic.
Fyne-cross is a really nice tool that can cross-compile Fyne applications for most popular systems (including android).
The libGL1 dependency under Linux is a fair tradeoff for wide compatibility - the drivers don't have stable ABI so dynamic linking to libGL1 is a must[0].
Python + Tkinter + Pyinstaller works, but does not support cross-compilation, and I've personally had some portability issues with it (e.g. under Linux, the GUI mainloop doesn't work outside of the main thread; under Windows, if you start a Process after setting up GUI, each process will create its own window, so you must start all the Process-es beforehand).
[0] https://github.com/fyne-io/fyne/issues/512
[1]: https://github.com/oxplot/raspberrypi-archlinux-installer
There's https://alire.ada.dev/ which is sort of like NPM or Rust crates for Ada. Obviously the number of libraries is much lower and the quality may be unpredictable.
Lazarus was a great crossplatform GUI framework to have a native GUI on each platform. You put a button on a form window, and then it calls Win32 on Windows, Gtk on Gnome, Qt on KDE, ... to get their native button.
Unfortunately, it is really lacking maintainers. It still works best on Gtk 2. They have been working on a Gtk 3 version for years. I am not sure if they have been making any progress. I guess the modern way for a Linux GUI is to have a Qt5 version or a Win32 version on WINE.
If Lazarus were more popular and had a better library ecosystem, I’d probably use it a lot more.
About Gtk i'm not sure if it is lack of maintainers or simply lack of interest in the Gtk3+ backends, i remember a discussion from not too long ago in the mailing list where people weren't happy with the breakage introduced by Gtk every major versions. It can be very disheartening to spend years building the Gtk2 backend only to have to make a new one for Gtk3 and before that is finished, out comes Gtk4 breaking things yet again.
But IME the Gtk2 backend works fine. At least personally i wouldn't bother with Gtk3 or Gtk4 as these feel like a waste of time now (though personally i did submit a patch recently with fixes for the Gtk1.2 backend[0] that didn't work for some time now :-P but that was mainly for fun - there might be some practical use for it though as all the necessary .so files are like ~2.5MB, so perhaps it could be used for simple GUI apps on Linux to minimize external dependencies).
[0] https://i.imgur.com/OM8bC9i.png
The state of their website isn't exactly reassuring. Not so much as a screenshot of their toolkit in action.
If I were writing GUI code in Ada I'd probably use the GTK bindings (GtkAda). They're maintained by AdaCore and are used by the GNAT Studio IDE so the 'dogfooding' factor is there.
How is GNOGA advantageous with future-proofing?