If you want to choose a single language that can create native GUI's, Rust is probably your best or only choice. Other languages are lacking a good story for either the web or for iOS but Rust works well on both.
https://terhechte.github.io/twitvault/
Here's a review of the experience of using it:
https://www.reddit.com/r/rust/comments/zegv2e/comment/izb6nl...
Started life as a rendering layer for FlowBetween so I could put in whatever looked like it was 'winning' later on but wound up writing my own renderer as there wasn't anything quite there yet. Still has that design so another unique thing is that it's possible to use the same API with whatever rendering layer you want.
Speaking of FlowBetween, one thing I have wanted to do for ages is to get rid of the platform-specific GUIs and use something universal. It should be easy because FlowBetween sends straightforward instructions to an independent GUI layer, but I keep bouncing off for a few reasons:
- it's a big ole task so I definitely want to pick something that's stable and also lets me hedge my bets in terms of being easy to migrate away from
- most commonly, FlowBetween needs pressure data from tablets and a lot of frameworks just don't do that (this is also in a terrible state in browsers)
- lots of GUI crates are designed as frameworks and so try to dictate the entire design of any app that uses them, which is no good for FlowBetween which tries to keep its internal design choices independent of its choice of GUI
At the moment, I suspect that some sort of imgui framework is best along with an entirely manual implementation of tablet pointer data: fits with my existing design and isn't 'contagious' in a way that could make it hard to migrate to something else later on.
I'm not sure this is the prevailing opinion. It may be something of a "vocal minority" opinion, but it does seem more common in the Rust community than elsewhere. The closer you get to traditional native app designers and developers, the more you'll hear the opinion that native look & feel (not to mention accessibility) is important to embrace.
IMO an ideal solution is to offer both: 1. to wrap native toolkits for things like text and UI controls, and 2. to enable canvas-drawn virtual controls, for those who would prefer to create their own widgets. These approaches can be enabled in parallel through an extensible widget/component system.
Writing effective cross-platform application is harder than one would think. Some time ago there was a discussion on HN where a WxWidgets maintainer stepped in to explain why some WxWidget programs were apparently inconsistent across O/S, and the explanation was that they were developed naively (I think one needs to use specific spacing abstractions, but I don't remember with exactness).
For my personal development, I use non-native (which is easier to develop), however, on large scale, it'd be a tough decision.
WxWidget was my favorite in the past (again, for personal development), however, the bindings are very spotty, which prevents adoption for several languages (wiki page: https://en.wikipedia.org/wiki/List_of_language_bindings_for_...).
The listed library only uses the ancient win32 api
It got replaced with C++/WinRT, which basically requires one to code like in the good old days of Visual C++ 6.0 alongside ATL, editing IDL files without any kind of VS tooling support and manually merging generated code.
Even the eldery MFC has better VS tooling support and COM authoring APIs than C++/WinRT.
Rust/WinRT is even years away from the C++/WinRT "productivity" in its current state, let along what .NET tooling provides, which by the way is also worse than UWP with .NET Native (e.g. no designer available, and no AOT support).
The reality is that only WinDev folks actually care enough about WinUI, the rest of us have moved on burned by these rewrites, and only a few hardcore advocates keep showing up their community calls.
I prefer desktop Windows programs to be gdi/win32, they are often the most thought out and optimized for actual desktop paradigms (i.e mouse+keyboard+high res screen) without giant margins, padding and whitespace everywhere and makes use of proper desktop class widgets like treeviews, listviews, tabs, etc.
See also: https://github.com/microsoft/windows-rs/issues/2153#issuecom...
If a person wants a native gui I guess QT would be worth investigating as well (unless one is concerned by the license).
But yes, it means C# UI with cumbersome Rust interop, if you rely on a Rust SDK.
I use macOS, so apps should be written with AppKit. For Linux they should either be GTK or Qt, depending on desktop. Recreating widgets from scratch with GPU rendering is doomed to feel wrong to users.
So following your argument, pretty much all apps I use on macOS are 'wrong' as far as GUI goes.
Off the top of my head from what I use most of the time: Maya, Houdini, Blender, Fusion360, Resolve, Darktable, Slack, Discord, VSCode. Not a single one of them uses native Cocoa widgets. And I couldn't care less.
Some of these are top of the line apps for 2D/3D content creation on that platform.
If the vendors of these apps can afford to not care about UI nativeness, why should any single one or small group of developers working their asses off on GUI crates for Rust? Mostly unpaid no less.
Meanwhile I do care. My main reason being: macOS offers fantastic facilities for inspecting and scripting the native GUIs, think using the web inspector or GreaseMonkey, but across the entire OS - but of course it breaks e.g. on Electron apps. Other people will cite help menu integration, custom key shortcuts, accessibility (not only for the disabled), and - yes, resource usage. I remember being productive on a system with 256M of RAM, and before that - 4M, and before that - 64k. It's frustrating to see so much progress wasted, I shouldn't need to close ALL of the chat apps just to run StableDiffusion more smoothly.
MacOS apps feel pretty wrong to me.
Some don't remember which screen they should be on, and always go to that screen at a predetermined size and geometry (tkdiff).
Others expand incorrectly to full-screen (macvim) when moved to a different screen.
VSCode doesn't behave like the native apps.
The list goes on, I'm short on time.
> And I couldn't care less.
You caring or not doesn't make the problem go away - native widgets always feel less wrong than non-native widgets.
Also Firefox and Chrome and their forks (e.g., Brave).
As a Linux user I really don't care if you use GTK for the UI. I've long given up on customizing the look and feel of my system to the point that application integration matter.
If a smart user here today says that recent network-centric apps are OK with him visually, then maybe they are OK?
Even such "simple" tasks as how to composite a window, a video in that window, and a floating menu over that window are not very well specified in any OS (try resizing that window and watch the fun). Or, for example, your floating menu--should the parent window resize itself and paint with transparent pixels in the extra area or should that menu be a separate "window"? And, what does being a "window" even mean?
Add into that the fact that we really should be making multithreaded GUI systems at this point and it's very clear that GUIs are stuck in a local minimum that's really hard to get out of because GUI systems require so many lines of code.
There are Rust GUI toolkits like Druid with custom controls that have elements outside the bounds of the main window.
* The first time any particular window is opened, Swing draws the contents but then changes its mind about the window size, recalculates the layout and then redraws the contents again slightly differently.
* When Swing creates a window, you can sometimes observe how creates it in the wrong spot and then moves it to where it was supposed to be created.
* Alt-tabbing quickly between two windows in a Swing application doesn't always work. It sometimes just glitches and leaves you in the window you started with. (Confirmed just now on Windows 10 with Java 17. The bug has been there for many, many years.)
* When opening a submenu of a menu, Swing does nothing to handle the problem of the menu closing again as you're moving towards it but accidentally mouse over an adjacent item. Platform GUI toolkits solve this either with a delay or by tracking the direction of the movement. IntelliJ implements its own menu bar to make this work.
* Try to find an example of a window that is resizable in only one direction or only up to a certain maximum size. As far as I can tell, this is not possible in Swing, and applications handle this limitation by designing all UIs to be resizable even when it doesn't make any sense.
And there are non-native behaviors in IntelliJ too. For example you can’t close windows by double-clicking the window icon on Windows (a feature of Windows since Windows 1?).
If the toolkit is good enough it's entirely possible that a platform or platforms may adopt it as their native toolkit. In any case, these are really competing with electron which is already non-native. If Rust toolkits can get to electron-like quality but with lower resource usage and better hooks into the underlying platform then I'd consider that a success.
All of them I glady ignore on private owned computers, or use the browser version, they are anyway Web apps.
Use Electron and you'll get OS-native buttons and other form controls.
Pretty sure that's the wrong metric. Users don't care if the interface doesn't look exactly like the rest as long as it's good looking and feels familiar.
As a heavy VSCode user for example, I don't think it feels out of place on a mac for example. The UI is consistent in itself, and the UX is consistent with the global UX of the OS (more so than some native mac apps like Finder for instance).
The main reason I hated Java Swing apps was that they were ugly as hell, not that they didn't feel native.
You can blame a variety of things for this, but it's the reality. Apple doesn't really make it easier with the newer UI approaches creeping in.
That's bad... ideally there should be a runtime choice between GTK / Qt.
side note... I know many people that would prefer apps on MacOS to behave like Windows/Linux (mostly about the keyboard)... and also the reverse (those are louder to complain, but a minority in my case).
> Recreating widgets from scratch with GPU rendering is doomed to feel wrong to users.
Yes, and no. When these widgets try to mimic platform-native widgets we have the uncanny valley problem which makes everything feel out of place like you describe. But if we drop this constraint and design widgets with their own consistent style within the same app, we don't have this problem. Apps like the JetBrains IDE's and Todoist show that this can be done.
To me the middle-ground solution is a UI toolkit with its own widget style, that has some tie-in with platform-native things and conventions like windows, menus, notification trays and keyboard shortcuts. Essentially GTK or Qt without the focus on pixel-perfect matching of platform-widgets. I think this is what Druid is doing. Rust is in a good place for this as it is a modern language that works well on all of these platforms, with no native UI toolkit yet and a package-manager/build-system that supports multi-platform library configuration.
There will always be a place for platform-native apps but cross-platform apps have different requirements. I don't care that my todo list application or IDE does not look exactly "native" on my Macbook. However I do care that these applications look and feel similar when I use them on my Macbook vs on my Linux machines or Windows laptop. Preferably without dragging in a full web-based rendering engine a la Electron.
Style is just one of many things. And it's extremely hard to properly code your own consistent UI toolkit.
On top of that every platform has a myriad of platform-specific behaviors that people expect and that you will get wrong in yours. Accessibility is the big elephant in the room. But even things like secondary focus in prompts/dialogs on MacOS (that Apple's own Catalyst and Swift forget about) is a bitch and a half to get right.
Which means "unsexy" things like accessibility get left by the wayside. And your users suffer.
Writing a UI kit is a huge task. It's one of those things (like so much else in our industry) where you can fairly quickly climb "stupid mountain" by getting a pile of shiny widgets on the screen; but then you look out over the valley below and realize that, holy, crap there's a whole other mountain range of things that a UI kit has to do.
It's also a tough story for Rust, in particular, because copying what other people have done with other toolkits won't really cut it. Rust's ownership semantics and general opinions don't necessarily accord well with the highly object oriented and event-loop / object-tree structure of most existing GUI toolkits.
Aside: I still don't understand why things like Electron based apps are so bloated. They seem to static link whole chunks of their own (forked) Chromium. But both Windows and Mac OS ship native webview components as part of their system which can be used instead. I've done this myself (used Edge's Chromium webview component in a VST synthesizer, and equiv webkit stuff on Mac) and binary sizes were entirely reasonable. Linux was a slightly more complicated story.
You can also checkout the "feature/ui" branch in GIT [1] to get the UI framework prototype.
[1]: https://github.com/Lichtso/contrast_renderer/tree/feature/ui
UWP is deprecated, althought it keeps being the one mostly used on Windows 11, as WinUI still isn't up to its game and keeps collecting issues across all their repos.
Windows App SDK is not a GUI framework, rather the new marketing name for Project Reunion, the porting of UWP runtime infrastructure on top of standard COM without sandoxing and application identity.
For example, QtWidgets is native and qml is not. WxWidgets is, electron is not.
Pax composites a layer of native text and form elements on top of a canvas drawing layer. This solves accessibility across platforms, as well SEO on the Web.
This approach also enables a lean runtime footprint (<100Kb, particularly useful when targeting Web) because the runtime doesn't need to reinvent text rendering, selection, input, etc.
Still early days — have made very little noise thus far; it's pre-alpha — but you can see what's cooking at https://docs.pax-lang.org/ and https://www.github.com/pax-lang/pax
[1] https://azul.rs/
I think it's much more valuable to look at this from the viewpoint of the Rust GUI ecosystem, and not compare absolute numbers where nothing comes close to JavaScript .
I'm all for RIIR but it will take 30 years before enough has been rewritten for a Rust-only GUI to be viable IMHO.
It seems Rust will be famous for the number of GUI libraries.
1. Rust is growing in popularity, and a compelling GUI solution is needed
2. These solutions take significant time to incubate, so many of the ones we're seeing emerge have been incubating for months or years, started at a time when there were fewer options.
3. The implications for cross-platform app development with Rust are profound, and offer us a way to break free from the pain-points and shortcomings of the local maximum solutions du jour: Web + Electron and Phonegap-style WebView mobile apps.