
Cross-Platform GUI Toolkit Trainwreck (2016) - aparashk
https://blog.johnnovak.net/2016/05/29/cross-platform-gui-trainwreck-2016-edition/
======
phtrivier
So many sub-debates hidden in this "cross-platform native GUI":

1) I want to write a GUI code _once_

2) I want to ship _something_ that works on Windows / Linux / MacOS

2.1) I want to ship _something_ that looks the _same_ on Windows / Linux /
MacOS

3) I want to ship a _binary_ that works on Windows, a _binary_ that works on
Linux, a _binary_ that works

3.1) I want to ship a _small_ and _efficient_ binary

4) I want to ship _something_ that looks like a Windows app on Windows, a
Linux app on Linux, a MacOS app on MacOS, etc...

(By definition, "I want to ship something that looks the same everywhere _and_
looks like an app of my host" is meaningless, right ?)

The "holy grail" seems to be:

5) "I want to write a GUI code _once_ that generates small efficient binaries
that looks exactly like an app of the host OS, and if possible looks the same
everywhere, and let me go back to writing my business logic rather than
agonize over drawing a button."

It's seems from the debate that nothing obvious fulfills 4 and 5.

Then it comes to which requirement you're ready to drop.

If you're ready to drop requirement 2) , I suspect you're doing MacOS
specific, go for it ;)

If you're ready to drop requirement 1) , I suspect your managers /
salespersons disagree.

I suspect your manager / salespersons do not care about requirement 3.1), but
it's debatable. Use Qt/Electron, and ship _something_.

I suspect your manager / salespersons do not care about requirement 4), and I
suspect they're esthetics, which can not be defended.

I gave up waiting for someone to make 5, and don't have the resources / skill
/ time to do it myself. And maybe we should stop caring and watch the sky
instead.

I hope someone is able to get to 1 + 2.1 + 3.1 someday.

I'll use that.

~~~
Wowfunhappy
> 2.1) I want to ship something that looks the same on Windows / Linux / MacOS

Why?

I want my macOS apps to use Mac-native UI elements, and Windows apps to use
Windows-native UI elements. (There is no one native Linux UI, so we can leave
that one aside...)

~~~
jcelerier
I want the complete opposite. I use the three systems almost daily, and I
freaking hate to have to context-switch to the platform's look-and-feel.
Thankfully KDE apps work mostly everywhere nowadays.

Most of the users of the FOSS software I'm developing also switch platforms
depending on the project they're in, but they want the software to be the same
everywhere for instance.

~~~
Wowfunhappy
Are differently-styled UI elements really a mental burden? I'm not advocating
for wholly different UI's on each platform—just that if your application uses
checkboxes, and I'm on a Mac, I should see Mac checkboxes.

~~~
Retra
It's probably more the behavior things. Keyboard shortcuts, focus behaviors,
menu placement, file dialogs, etc. Settings panels in MacOs should take effect
immediately, while in windows you have to click ok/apply... inconsistencies
like this can lead to frustration.

~~~
Wowfunhappy
But _not_ doing this brings about an even worse kind of context
switching—between apps on the same platform.

As annoying as it is to switch form cmd+C to ctrl+C when I go from Mac to
Windows, it's even worse when a Mac app uses ctrl+C.

------
saagarjha
To date, the best solution to this problem that I have seen is to write all
your core code in a shared library using something like C++, and then hooking
it up to a thin layer of completely native, platform-specific code for the UI.
It’s fast, lightweight, looks good, and requires minimal extra code if you do
it right.

~~~
ashsys
Shameless plug:
[https://github.com/AshampooSystems/boden](https://github.com/AshampooSystems/boden)
We are working on providing exactly that thin native wrapper in modern C++
without much bloat.

~~~
zerr
Are you associated with [https://www.ashampoo.com](https://www.ashampoo.com) ?

~~~
ashsys
Yes we are a subsidiary of
[https://www.ashampoo.com](https://www.ashampoo.com)

------
deathtrader666
Wonder how the author didn't come across Qt or wxWidgets in his research?

~~~
glangdale
I have the same question. There are many things that are problematic about Qt
(personally, I loathe anything that feels the need to interject itself in the
middle of the build process) but to completely ignore Qt without explanation -
and subsequently post detailed experiences with libraries I've never even
heard of - led me to believe the author exists in some uninteresting-to-me
parallel plane of existence.

~~~
bunderbunder
There was plenty of explanation for me when I first encountered this article
(in the context of trying to solve the same problem):

> what cross-platform libraries are available for Nim!

Things might have changed over the past couple years, but, at least at the
time, there weren't any (usable) Nim bindings for either.

~~~
glangdale
Fair enough, but I think that the onus of proof is on the weird-language-user
here. That is, a discussion of how cross-platform GUI toolkits are a
'trainwreck' takes on a different vibe if you're insisting on using Nim or
Left-Handed Pure Phenomenological Haskell or the like.

~~~
bunderbunder
I think you're maybe over-interpreting the article.

There is no (grammatical) article in its title. You seem to be assuming the
article is implicitly "the", which would imply that it's intended for a more-
or-less universal audience. It could just as easily be "a", which would then
mean that it's more of a personal rant about the author's specific situation.
I'd argue that the leading two sentences in the italicized portion of the
article imply that it's the latter.

For the sake of throwing my own $0.02 in, I also have a historical habit of
blithely ignoring wxWidgets and QT for my hobby projects. Their being written
in C++ bit is a bit of a deal-breaker for me. The quagmire of interacting with
C++ code from a language that isn't itself C++ in a cross-platform way results
in me shaving my fill of yaks during working hours; I have little taste for
doing even more of it during time that's supposed to be reserved for fun.

~~~
glangdale
Yes, I guess so. I suppose I'm startled that someone would write such an
elaborate article about such a remarkably specific situation without some
intent to make a general statement, but whatever floats his boat I guess.
You're definitely right that interacting with C++ outside of C++ (unlike the C
ABI) is _painful_ even before Qt's weird moc stuff gets going.

------
hguhghuff
Anyone got experience with this?
[https://webkit.org/wpe/](https://webkit.org/wpe/)

Here it is in use on raspberry pi [https://medium.com/@decrocksam/building-
wpe-webkit-for-raspb...](https://medium.com/@decrocksam/building-wpe-webkit-
for-raspberry-pi-3-cdbd7b5cb362)

A long video on it:
[https://m.youtube.com/watch?v=klfE6m1oCkg](https://m.youtube.com/watch?v=klfE6m1oCkg)

A short video on it:
[https://m.youtube.com/watch?v=wVSwkj9McCU](https://m.youtube.com/watch?v=wVSwkj9McCU)

It says: "WPE is the reference WebKit port for embedded and low-consumption
computer devices. It has been designed from the ground-up with performance,
small footprint, accelerated content rendering, and simplicity of deployment
in mind, bringing the excellence of the WebKit engine to countless platforms
and target devices."

I'd be interested to know how to use it.

------
awalton
"GTK2 is too big"

"Just use Java or Electron"

I'm sorry, I just can't reconcile the logic here.

------
oblio
For the Java bit, I imagine that with modern Java versions with modules the
app would be a lot smaller. The new Java versions are modular so you can
include just what you use and I think it can even create a native package for
installation. It should bring NodeNox 3 down from that 220MB package.

------
resoluteteeth
One warning: if you try to implement your own gui widgets in opengl, unless
you're really careful you're not going to support accessibility tools such as
screenreaders or Japanese/Chinese text input at all.

~~~
AnIdiotOnTheNet
If people cared about those things they wouldn't be making crappy webapps with
custom look n feel and no accessibility.

------
almostarockstar
We already have browsers installed that are designed to render arbitrary
cross-platform GUIs based on HTML/CSS.

Why can't I write a desktop application that just asks the OS for the users
preferred browser and provides it with HTML/CSS and UI interaction callbacks /
events? Render it in a native looking window.

We shouldn't _need_ Electron at all! It's like we all have this fantastic rail
transport network but insist on riding in our own trains.

~~~
monksy
Why do I need a browser just to show components on a screen? It's overkill to
do that.

~~~
almostarockstar
I agree, but we're not really talking about simple components on a screen. If
that was the case, everybody would be happy to use tcl/tk, or swing or
whatever.

Plus, it's not overkill when you get the browser for free.

~~~
rkeene2
Well, I'm happy to use Tcl/Tk -- although using it on a mobile device doesn't
result in a usable touch-based interface.

Really, that's the crux of the problem is that there are different paradigms
that are not just a little bit different but fundamentally different. This is
especially annoying on my Chromebook running Android apps -- they very often
expect you to be using a touch-based system without a keyboard. The way this
works with a docked Chromebook and a mouse is the mouse is treated as a VERY
precise finger touch.

Additionally, on Android and other touch-based systems you're usually not
using a Window Manager so, for example, using an Android mail client on my
Chromebook, I can't start the reply in a new window so that I can read the
message in one window while simultaneously replying... and I especially can't
have a bunch of unfinished replies while reading other emails to gather
information for the reply.

Creating a meta-layer that can represent the fundamentally different modes
from the same data is VERY difficult. HTML and CSS do a terrible job as well
unless you model your HTML in a very specific way, which cannot accommodate
all GUI semantics.

------
FraKtus
I think he got it wrong when he quickly ruled out IMGUI, as you can use it to
create a small app with next to no dependencies. He complains that you need to
redraw your GUI at 60 FPS, but this is wrong, you should be able to draw with
it only when needed. I am a big fan of Nuklear. I can write a tiny C app that
compiles on macOS, Windows, iOS, and Android with it. The look and feel of
Nuklear can be something you don't like, however.

~~~
ScottFree
> He complains that you need to redraw your GUI at 60 FPS, but this is wrong,
> you should be able to draw with it only when needed.

Yep, he did that, as stated here from TFA:

> The solution was to redraw only when needed: as a quick hack I introduced a
> global boolean doRedraw and set it to true only when an input event was
> received or the internal application state had been changed (e.g. the
> framebuffer had been updated). Then the drawing would only happen when
> doRedraw was set to true. Surely this could be done in a nicer way, but the
> general concept would be the same.

His issue was this...

> The second issue with text rendering was a harder nut to crack.

> I really don’t want to do a Donald E. Knuth here and spend too much time on
> a problem that has already been solved on the OS graphics library level in a
> perfectly satisfactory manner. I just want to call drawText() and be done
> with it!

How does Nuklear handle text rendering, layouts, fonts, etc?

~~~
FraKtus
He speaks about the 60 FPS when he tried NanoVG... I think he did not realize
he could do that trick with IMGUI. For text rendering with Nuklear, you make a
font atlas from a true type font, rasterizing the font is built in Nuklear
with stb_truetype. That gives you a lot of freedom. You can load as many fonts
as you need. There is also support to load a binary resource such as the TTF
file from a base85 string; it's very handy. For layout it's immediate mode, so
you describe it with code such as

nk_layout_row_dynamic(ctx, (float) row_height, 3); // a row of 3 buttons if
(nk_button_label(ctx, "Previous")) ... if (nk_button_label(ctx, "Next")) ...

Here is small app I made with Nuklear:
[https://www.youtube.com/watch?v=MycIYcutlMA](https://www.youtube.com/watch?v=MycIYcutlMA)

------
vortico
If you need native look and feel:
[https://github.com/andlabs/libui](https://github.com/andlabs/libui)

If you need HTML5 canvas-style drawing: I propose building an (abstract) SVG
document and render with Skia. When part of the SVG document changes, that
part will be redrawn by Skia, just like an interactive SVG in your browser.
Disclaimer: I haven't tested this idea.

------
vram22
Adding my 2c (of anecdote) to this thread:

Andy Brice of successfulsoftware.net has a long-time product, Perfect Table
Plan (computes seating plan for weddings, given various inputs) that used Qt
(and C++), I've read, on his blog. PTP has been there for years now. Seems to
be doing well, based on what he says about it. Don't know how good the Windows
vs. Mac versions are, but at least they are there. His newer product HyperPlan
may also be on the same stack.

[https://www.perfecttableplan.com/html/about_us.html](https://www.perfecttableplan.com/html/about_us.html)

No connection, just have followed the blog for long.

------
dysoco
I know the author focused on Nim, but I wonder how Lazarus (or Delphi I guess)
would fare.

Sadly it's FreePascal, but it really does look like the less bullshit platform
to make cross-platform desktop applications.

~~~
lbruder
Delphi was, and Lazarus is, amazingly well designed. Lazarus comes pretty
close to a Swiss army GUI tool, and once you get to know it a little better,
Object Pascal is actually a very nice language that rivals C++ (!) in power.
It's still my secret weapon at work. If only the docs were better. Still
keeping around a VM with Delphi 7 from 1999 just because documentation was
sooo good then.

------
ryanmarsh
This is exactly why I say Electron is going to “win” in the cross platform GUI
toolkit space. I do not think this is good thing. Cross platform GUI dev has
been a train wreck as far back as I can remember. Contrast that with the
immense amount of human years invested in making the browser a cross platform
GUI runtime.

I’m sorry folks, 198MB menu bar apps is what we’re going to have unless a
cross platform GUI effort equivalent to that of Chromium comes about.

------
analognoise
FreePascal/Lazarus : cross platform native GUIs out of the box. Super small
executables. No bloat.

For the love of God, check it out.

------
TJSomething
To add a little data on my experience last time I tried this, using UPX [0],
you can get GTK+ 3 down to 9 MB. Most of the size of Qt comes from ICU, which
can be feature selected to decrease its size [1]. With that and UPX, Qt can
get down to 16 MB. And those can both be compressed another 30% with ZIP files
for shipping.

While those aren't great numbers, I personally think it's tolerable for most
usages.

[0] [https://upx.github.io/](https://upx.github.io/)

[1] [https://ssl.icu-project.org/datacustom/index.html](https://ssl.icu-
project.org/datacustom/index.html)

------
NikGeeonx
I like the idea of having one c-sourcecode compiling on Linux, macOS and
Windows. Hence, I have developed a platform independet GUI called Geeonx
[https://www.geeonx.org](https://www.geeonx.org) .

Versions for Linux and MacOS X are ready for download. The version for Windows
will follow soon - I will speed up development if someone claps in his hands.

------
ianharrigan
Hi all, one option might be HaxeUI (full disclosure, im the author!) :)

Its essentially a UI abstraction that delegates certain things "backends"

site: [http://haxeui.org/](http://haxeui.org/) github:
[https://github.com/haxeui/haxeui-core](https://github.com/haxeui/haxeui-core)
discourse: [https://community.haxeui.org/](https://community.haxeui.org/)

It uses the Haxe language (haxe.org), here is a very small/simple/dumb sample
of it "in action":
[https://www.youtube.com/watch?v=cijUTbMKMHI](https://www.youtube.com/watch?v=cijUTbMKMHI)

It can use native components (wxWidgets, android, html5) but you can fairly
easily extend it to use other "backends" (like Qt for example - i havent
written that backend yet, but its something ill almost certainly do)... It can
also handle drawing the components in a variety of methods (so called
"composite backends").

Im currently aiming to get it out of alpha asap, and most work goes into "new-
component-method" branches (these will become master shortly). Documentation
is pretty slim at the moment, but something im actively working on, two
examples that i just wrote up today in fact are:

[https://github.com/haxeui/haxeui-
guides/blob/master/custom-c...](https://github.com/haxeui/haxeui-
guides/blob/master/custom-components.md)

and

[https://github.com/haxeui/haxeui-
guides/blob/master/modules....](https://github.com/haxeui/haxeui-
guides/blob/master/modules.md)

Let me know if you have any questions! Ian Harrigan

Heres some other links / screens that may be useful:

[https://twitter.com/IanHarrigan1982/status/11113481164338503...](https://twitter.com/IanHarrigan1982/status/1111348116433850368)

[https://twitter.com/IanHarrigan1982/status/10905353905980416...](https://twitter.com/IanHarrigan1982/status/1090535390598041600)

------
netrap
Weird article. Why write an entire cross-platform GUI toolkit when he could
port IUP to OS X? :)

------
Timothycquinn
These days, Xamarin looks interesting. Can target windows, Linux, Mac, Android
and IOS. I have not used it yet but if I get a project that needs full Cross
platform distribution, I would probably use xamarin with a F# code base where
possible.

------
Wyndtroy2012
Given the other applications you chose to look at, I'm surprised you didn't
also look at Audacity. It uses wxWidgets, which is a nice C++ cross-platform
GUI framework. It wraps native controls on each platform it supports, and also
has a "Generic" variant where it draws its own. It's not very heavy as these
things go, and has a nice python binding called wxPython.

I'd check it out before rolling my own :)

~~~
panemic
By personal experience, wxWindows is "OK", but it's not a panacea. There are a
ton of little quirks that will burn you when doing cross-platform development
simply because native controls do not behave in the same way. HiDpi is a major
pain with wxWindows (but then again, the way HiDpi is managed is a pain
irrespective of the toolkit).

But if you do some forms and basic UI controls, wxWindows does the job
egregiously. Looks the way it should be on all platforms.

It's funny an article from 2016 mentions issues about text rendering, because
certainly we've been regressing in this area. I can spot QML and Electron apps
by the broken text rendering alone. FF60+ with quantum has incorrect subpixel
hinting and does not correctly hint at all sometimes.

Many of the mentioned apps int the article are "broken" in my eyes: I don't
have perfect vision, and I do _expect_ apps to follow the system text scaling
(and they don't). For a "broken by design" example, see Darktable, which is
awesome, and _should_ do this by default, but the authors hard-coded a theme
where literally every widget is styled for looks and not for function.

Nobody speaks about how the widgets should feel and interact, but that's
exactly what feels off about "GTK" on windows or macos. QML, Electron and
partly GTK3 brings that feeling to all platforms. My biggest letdown is QML,
as many QT developers see it as the future so it has a larger adoption than it
should have.

It breaks just about any rule in the book: poor behavior on any platform,
noticeably slower, style not consistent with the platform, broken scrolling,
broken text editing, broken text rendering...

~~~
weberc2
Why does electron have broken text rendering? Surely the Chrome browser’s
tendering does a good job? Or do you mean something like “it doesn’t match
system defaults”?

~~~
badsectoracula
Not matching system settings (not just defaults, but the setting, i set the
settings for a reason) _is_ broken!

~~~
blattimwind
This. It's a bug to use a different text renderer than the system, because it
will never look the same and with text this is very noticeable and irritating
even to some people. You do _not_ want your core visual to be irritating.

------
paulcarroty
[https://proton-native.js.org/](https://proton-native.js.org/)

------
_pmf_
Oh, are we having this discussion again?

~~~
ScottFree
If anybody's interested in the previous discussion, which (imho) was pretty
darned good:
[https://news.ycombinator.com/item?id=13952007](https://news.ycombinator.com/item?id=13952007)

------
_bxg1
Mostly good article, but I don't appreciate the gratuitous dunking on web devs
towards the bottom:

"so developers can use hipster technologies like HTML, CSS and JavaScript"

"the vast armies of newskool web developers who grew up on JavaScript and the
DOM"

...especially when the author doesn't really appear to know what he's talking
about in that space:

"And when things don’t quite work as expected, you can’t do much about
it—short of maybe just switching to a different framework as a last attempt."

"and long-term maintenance will be a nightmare."

"web development technologies—which technically don’t provide any advantages
over more traditional approaches"

There are legitimate criticisms of Electron as a choice for desktop apps, but
that doesn't invalidate an entire domain's worth of developers.

~~~
_bxg1
In reality, JavaScript in 2019 on V8 - thanks to innovations like JIT
compiling - is in almost the same ballpark as Java itself when it comes to
performance. JavaScript itself is not what slows down JavaScript UIs.

What does slow down Web UIs is the DOM (whose rendering engine in Chromium is
written in C++). The DOM is the _most advanced layout engine ever created_. It
does an unbelievable amount of work to make interfaces resizable-by-default
and adaptable-by-default, and yet is enormously flexible, allowing one to
build virtually any box-based interface imaginable. This isn't simply so
newcomers have an easier time. It frees application code to focus on the
control logic and the structural side of the view, instead of messing with
things like pixels and manual sizing, which makes application code more
maintainable and reusable. I can place a piece of DOM in wildly different
contexts, with wildly different amounts and types of content, and for the most
part it will just respond as expected. This significantly reduces code
complexity, which improves long-term maintainability and avoids bugs.

This of course comes with a cost. All of those implicit layout adjustments
have overhead. The ability for your code to handle content you never thought
it would encounter requires CPU time. That cost isn't worth it for certain
applications. But it isn't a waste, or a sign of the moral decline of "kids
these days". It's a conscious tradeoff that any good developer can weigh and
consider for what it is.

------
lmm
What is this ridiculous obsession with executable size? How much time did this
author spend chasing down alternatives to a measly 120MB? If they're working
on art project then fair enough, but if they're working on a useful program
then surely anything else they could have done with that time would have
brought more value to end users than shaving off 3 cents' worth of disk space.

~~~
alxlaz
It's not ridiculous. We write off executable size as something that's
irrelevant in an age where you can get a 4 TB drive for (what most of the HN
audience would consider) peanuts, but it's not just disk space budget that's
affected. Larger executables also mean:

\- Longer start-up times (ridiculous things in 2019: a) SSD prices, b) the
fact that it takes longer for an Electron todo app to load off a high-speed
SSD than it took for basically the same application to load off my old Amiga's
floppy drive)

\- Fewer applications that you can run at the same time, higher chance of disk
thrashing when resuming from suspend (bloated frameworks still have to make it
to RAM, which yes, is also cheap and abundant, but load up a few VMs and see
how abundant it seems _then_ )

\- Additional bandwidth used for delivering application updates

\- Higher battery consumption if you use antivirus software and the like,
because all those bits still need to be looked at.

\- Sometimes it's just security theater, but not always -- a complex framework
still has an attack surface even if your application doesn't use all of it.

These things save way more than a few cents' worth of disk space.

~~~
lmm
Sure. However long it takes to read 120mb off a disk (most likely less, if the
application is only using some of the GTK dlls). 120mb of RAM. 120mb more to
read when restoring from suspend. 120mb extra data use over your home internet
connection. (I'm not going to talk about antivirus time because if you're
using antivirus in 2019 you deserve whatever happens to you). _It 's still all
irrelevant_. Put a monetary or human-time value on it and compare to the cost
of the application, or the development time, or a single crashing bug. Our
programming culture's priorities are so far skewed from whats' actually
important.

~~~
alxlaz
> I'm not going to talk about antivirus time because if you're using antivirus
> in 2019 you deserve whatever happens to you

If you develop enterprise applications (which many Electron applications are,
in fact :-) ), you really have to talk about antivirus time. It's not
something you can wish away. And it's not something that you should ascribe to
customers being irrational, either. If malware compromises your users' data
and it turns out you're not running antivirus software on your computers
you're gonna pay _way_ more than you'll ever save by using a big fancy
framework.

Sure, it's a bad idea (in strictly technical terms) but you can't just go to
your customers with a straight face and ask them to stop running antivirus
software because it's 2019.

> Put a monetary or human-time value on it and compare to the cost of the
> application, or the development time, or a single crashing bug

You say it as if these were independent, but they're not. Debugging
performance issues (the critical kind, that make customers yell at you and
utter words like "money" and "back") in Electron applications is a mini-
project in and of itself. Complex frameworks (I'm not picking on Electron in
particular) are cool to quickly develop against, but not cool to troubleshoot,
and once you start going off the beaten path, it's not as fun.

Of course, sometimes it's a justified choice, I'm not in the "Real Programmers
don't use Electron" camp. But the non-technical aspect of this engineering
choice is slippery, as non-technical aspects always are. Sometimes it's the
right choice in terms of organization expertise and whatnot, but sometimes it
just appeases executive impatience, at the expense of customer experience.

~~~
AnIdiotOnTheNet
> If you develop enterprise applications (which many Electron applications
> are, in fact :-) ), you really have to talk about antivirus time. It's not
> something you can wish away.

In enterprise applications you totally can just wish AV away by turning it
off. It's useless at best and mostly serves to just gum up the works and slow
things down without providing tangible benefit. There are much better ways to
handle security in an org.

