Thoughts and impression of LibUI - would GTK be able to learn something from LibUI in regards to cross-platform support?

Hey there GTK/GNOME folks.

This is about LibUI and, indirectly, GTK. I hope to be able to
convince in particular the GTK devs to consider LibUI as the
idea. Not so much the implementation, but the idea.

If you are more interested in GNOME than GTK then this thread
is probably not hugely interesting for you. And if you already
know LibUI then I am probably not telling you anything new,
either. But others may still learn something new.

So, first, what is LibUI?

It is a GUI, more or less, that attempts to be quite cross-plattform
supportive. Aka write once, run everywhere.

The github repository is at:

I think it was started in 2016 with Go-bindings, but it is
still actively maintained. Unfortunately Pietro does not
have a lot of time so it’s going quite slowly … but anyway,
don’t focus on the activity issue - focus on the IDEA behind
it.

The general idea is to have cross-OS platform support for
GUIs. I am using it only via the ruby-bindings, but it works
fine. I was able to run my widgets that I wrote in ruby-gtk3
on libui too, and it worked on windows. I can even create
.exe files (cheating a bit, via the ocra gem). Yes, this is
nowhere near on the level of simply compiling proper C and
C++ applications, I know that - but it is super-simple really.
I get things done quickly. And I suppose, one day in the
future, I may pick up C/C++ properly and create “real”
applications. But for the time being I am having fun
creating tons of small, specialized widgets over functionality
available in my gems.

The huge benefit is that it works very well on windows.

And this is where it ties indirectly into GTK. Actually,
it uses GTK on linux, but my point here is more that
I failed to compile GTK on windows. This is probably due
to my lack of knowledge, but after I tried to compile it,
I had missing symbols error on the commandline. I gave
up. Perhaps one day I will try again but it’s way too
complicated IMO.

This is where GTK could learn from libui. Create something
that is small, portable, efficient. It’s an area GTK
neglected a lot.

Libui does not use GTK on windows as far as I know, so
my comparison is not completely fair. But I am comparing
the SIMPLICIY here. On windows, I just installed the
libui gem and ocra … that’s it, sort of! There goes
my new shiny .exe file (ok, cheating a bit too via
the ruby interpreter bundled into it, but again, the
IDEA is what I am referring to).

Wouldn’t it be great if GTK would be super-simple to
get on windows as well?

I am not referring to all of GTK, mind you. LibUI does
not support all of GTK as far as I know. CSS support
is not there as far as I know, to show one example.
But the simplicity … now that is existing.

I’ll continue to use ruby-gtk3 just fine, but I am mostly
limited to linux. I’d love if GTK would become as simple
to use on windows too.

If a single man can do so (in regards to LibUI and windows)
even if it is not using GTK on windows, then I challenge
the notion that the GTK stack is simple. I think it became
too complicated. I’d even suggest radically bundling
together tongs of things - pango, glib, cairo, atk …
and so on. I am aware that this is not easily possible
right now but in the long run it would be so cool if
GTK would be super-simple to build and get running on
windows as well. Personally I failed due to the missing
symbols issue; perhaps I will solve this one day in
the future. But for now I am on a libui-driven rush,
where I’ll port my widgets to libui in addition - probably
using a DSL that abstracts this away, so that I can
more easily replace the GUIs (ruby-tk is an additional
option; tk works for me on windows too but it is soooooo
ugly and the ruby API to ruby-tk is HORRIBLE. The ruby
API to ruby-gtk is much better on the other hand.)

3 Likes

I think you raise some good points about compilation of GTK being sometimes a bit tricky.

(It’s funny you mention windows, actually - when I tried compiling GTK in MSYS2 on windows it worked first try, much to my surprise, after some hours of headaches followed by giving up on Linux (it compiled, and I could use it to compile programs, but I couldn’t run anything, since programs refused to link with the produced .so file))

On the other hand though, I’d say that GTK is a vastly more complex project than it looks like LibUI is, so it’s fair that the build process is a bit more complex too, and in addition, most users will never see the complexity of building gtk, since they can install it via a package manager. (Even on windows, if you use MSYS2, there are packages available via pacman for gtk2, 3 and 4, and I assume the same works for Cygwin, though I don’t have experience there.)

Overall I’d say GTK does a lot of things right, including good wrappers for many languages and fairly good cross-platform support - it does function, and integration is improving, though I do agree it could look a lot more native on non-Linux systems. If you value LibUI’s simplicity, that’s great, and I wish you the best of luck developing programs using it. On the other hand, GTK is still very capable and with a bit of perseverance or a package manager, one can get it working very nicely.

EDIT: also, to the point about GTK should try to make something small, simple, and efficient - I do not think this is really the aim of GTK. It is designed to be very versatile, and it is very difficult to achieve that without adding complexity.

EDIT 2: I actually just tried building gtk on linux and it worked perfectly first try. Turns out it always has, just I didn’t know I needed to update the dynamic library cache after installation to make the new dynamic libs work using sudo ldconfig /usr/local/lib

1 Like

I guess I’m just confused, because you’re presenting this as if it’s some sort of revolutionary, groundbreaking idea. Which… um…

  • Have you never heard of Qt?

  • Or a little thing called Java? (AFAIR Sun literally gave us the term “write once, run everywhere”.) Java’s Swing & SWT are undeniably very cross-platform, however negatively I might feel about them otherwise.

  • If you want to go older-school, how about Tk? Don’t hear much about Tk anymore, though Python still supports it for some reason.

  • For the Eiffel language, there’s EiffelVision, which has a familiar story:

    The EiffelVision library addresses all major needs of developers of systems supporting modern graphical interfaces. EiffelVision runs on Microsoft Windows 95/98/Me/XP/NT/2000, all major Unix platforms (including Linux) and VMS. All versions are fully source-compatible; with only a recompile, applications will run on every supported platform with the native look-and-feel.

    ( If you’re feeling bad that they didn’t mention macOS, don’t: I’m pretty sure OS X didn’t exist yet, when that was written. There’s a newer EiffelVision2 which might support OS X via Gtk. It’s not super clear, but it doesn’t sound like they ever produced a native GUI layer there.)

Believe me, I’m not trying to knock libUi, and if it works for you then that’s great. But what they’re trying is not new, it’s something that’s been done a hundred times over. Those attempts have, for the most part, not been super successful.

Qt has probably come the closest, but QtWidgets jumps through a lot of hoops to look as native as possible on each platform. They even have hooks in their file, font, and color picker dialogs that will show the native, platform ones directly, instead of one built using the Qt interface. Flatpak had to do the same thing, punching a hole in their application sandbox and building a Portals interface that lets them launch the native file dialog for the user’s platform. Because the number one thing that gives away a non-native app is a wonky file chooser dialog that doesn’t let you get at some resource your system’s dialog supports.

So the major issue is, as it turns out, that users don’t want cross-platform apps. (Why would they care? They’re only running it on one system at a time.) And when they’re running an app on a system, they want it to be one that’s designed for that system.

There are too many differences between Windows, OS X, and Linux (heck, even between GNOME and KDE). Apps designed to fit “all of the above” never quite feel truly native on any of them, and — even worse — they fail to take advantage of each platform’s unique strengths.

Brian Wilson @ Backblaze presented it well in his “Brian’s 10 Rules for How to Write Cross-Platform Code” (even if I called him out a bit in the comments on one point):

Rule #2: Factor out the GUI into non-reusable code—then develop a cross-platform library for the underlying logic.

Some engineers think “cross-platform” means “least common denominator programs” or possibly “bad port that doesn’t embrace the beauty of my favorite platform.” Not true! You should NEVER sacrifice a single bit of quality or platform specific beauty! What we’re shooting for is the maximum re-use of code WITHOUT sacrificing any of the end user experience. Towards that end, the least re-useable code in most software programs is the GUI. Specifically the buttons, menus, pop-up dialogs or slide down panes, etc. On Windows the GUI is probably in a “.rc” Windows specific resource file laid out by the Visual Studio dialog editor. On the Mac the GUI is typically stored in an Apple specific “.xib” laid out by Apple’s “Interface Builder.” It’s important to embrace the local tools for editing the GUI and just admit these are going to be re-implemented completely from scratch, possibly even with some layout changes.

Yes, you can use Gtk on Windows… but that doesn’t mean you should.

Great for whom? What use is Gtk to the average Windows user? None at all, all by itself.

Gtk used to be available as a packaged download for Windows, complete with an installer and everything. Here’s a 2005 Wayback Machine capture of the download page for Gtk+ 2.4.14 to prove it.

The reason those packages existed was because they were required to run GIMP on Windows. But very quickly everyone involved realized that it just makes more sense to bundle Gtk into the GIMP installer, and install them both together. On Windows, that’s the preferred model, and it’s how GIMP for Windows is still distributed to this day. (Along with a small “MS-Windows engine for Gtk+” that’s supposed to give it a more native look-and-feel.)

That “works” for GIMP, and since Gtk was literally created for it, I suppose it makes some amount of sense for it to use Gtk even on Windows. But it would still be better (IMHO) if it had a native Windows GUI built on native Windows APIs.

Gtk doesn’t need to run everywhere. And I’m skeptical of the idea that it could even try, without becoming worse at the things it’s GOOD at right now.

1 Like

Also, holy wow. In 2005, Gtk+ 2.4.14 for Windows clocked in at just under 4 MB, and the GIMP installer was another 7 MB.

The current GIMP for Windows installer is 226 MB, which makes a 2000% size increase in 16 years.

Fortunately, hard drives have grown even faster. These days 226 MB is nothing — I’m pretty sure Photoshop is measured in gigabytes by now.

@FeRDNYC makes some good points about the disadvantages of cross-platform UIs. It would make things a lot easier for developers though, and some users use multiple OSs and would like to have the same programs available on both/all and more than vaguely resembling each other. Without a good portable native UI library available, everything’s going to end up being a web app, or perhaps Flutter.

There’s a new cross-platform UI about to be released, .NET MAUI. Unfortunately, Microsoft aren’t actively supporting Linux with this, leaving it up to the “community”. There’s likely to be resistance, but I think people should get over it. MS is rather different now from their Steve Ballmer days. There is a Linux fork of MAUI on github, but I don’t know if it works yet. It says it uses GtkSharp. So that’s a dead end unless someone replaces it with a GTK4 version, preferably automatically generated from GI for future-proofing, and opening up things like gstreamer.

I’m personally against the Windows-native look of cross-compiled GTK applications. Because I like Gnome’s design. Windows and KDE UI designs demonstrate a lack of taste/aesthetics.

But GTK-based apps can be cross-compiled, example: gImageReader, and even automatically; integrated into CI. After the CI process finishes - you get your shiny .exe Installer. And once launched it looks exactly like on Gnome, i.e. - nice! This particular example also demonstrates why “users do want cross-platform apps”: gImageReader is probably the best GUI for Tesseract, and if it were not cross-compiled - Windows users were loosing out.

I do think that the cross-compilation process should be made much more easier - at least as it is the case with Qt.

Both Qt and Electron *cringes* have a number of platform-specific features to help make applications feel more native. The thing is… most developers don’t bother with using them. The sort of developer who uses Qt or Electron on macOS tends to disdain Qt’s macOS-specific features like QMacToolBar or Electron’s systemPreferences.getColor(color) because they hate platform-specific code. The problem is cultural (and a pragmatic, if user-hostile, approach to limited labor resources). The problem is not technical. The technical problem has been solved for decades.

(IMHO Qt has much more wasted potential than Electron. We’ve gotten so used to React websites in Electron wrappers that we’ve kind of lowered the bar for anything that isn’t, say, 100% Adwaita or 100% SwiftUI. It takes much, much more effort to make a native-feeling Mac app in Electron than in Qt, while Electron lets you recycle your weird, janky React web app with a minimum of fuss.)

In my limited experience with GTK apps on macOS, it seems like it would be significantly more work to make them feel “Mac-like” than it would be with Qt. In part this is because of the Qt company’s business model (ie they have a financial incentive to maintain respectable platform support), but in part it’s also because of the divergence of GNOME’s and Apple’s Human Interface Guidelines over the past decade or so. (KDE, by contrast, seems to be a bit of a free-for-all, without strongly prescriptive big-picture user-interface concepts.) Even non-GNOME Linux users can apparently readily identify Linux apps that feel “GNOME-y”, so it’s unsurprising that the same effect would transfer over to Windows and macOS.

1 Like

Actually what lacks is a properly documented example (from 0% to 100%) of the cross-compilation process in the official GTK docs. Technologically it is definitely possible for a long time. For now, those who are interested in the topic - may take a look on the above mentioned gImageReader CI pipeline to understand how it may work.