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.
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.
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.
And if you are on macOS doing any kind of design work, this is your mode of working. People using Photoshop or any 2D/3D DCC etc. You use all the screen space real estate on any number of screens you have. But even if I write code I run VSCode in full screen. If I have a dual screen setup I usually have one screen with two code editors, mini map & folders + terminal on screen two. But that's it.
But even assuming you run apps side by side/stacked whatever so you could actually visually see how non-native/different they look. Is that the real issue on macOS today? Personally the main gripe I have is that -- and kindly pardon the tangent -- macOS native window management is shite. One of the first things people that come from a *nix desktop buy/install, when they switch to macOS, is a proper (possibly tiling) window manager.
But back to widgets/look: in DCC apps the main sort of dialog you interact with are attribute editors where you change properties of an object or node.
I like to refer to an issue on the egui crate which has some of the best out-of-the-box support for this kind of widget composition[1].
Apple Human Interface (AHI) guidelines do not have any handrails on how these attribute editors should look or be done. The best you can do is go with dialog AHI guidelines and these fall short for this sort of window. I can go into great detail here why but it's beside the point. If you read my comment on the egui issue I linked above (same handle I use on HN) you may get an idea where I am coming from.
Most Human Computer Interface (HCI) guidlines for various platforms are based on typical late 90's early 2k desktop apps.
They were never updated to reflect on newer paradigmns for UX that evolved in recent years. Blame the fragmentation of the desktop and Electron & co.
IMHO this is the first problem the OS vendors need to solve before we can blame developers of UI libs to not make them look 'native enough'.
can you provide some examples on desktop? Touch maybe, but that is not used on desktop, afaik.
I mean stuff that is common enough to deserve a defintion and a best practice laid out in a human computer interface (HCI) guideline document for a platform/OS.
Off the top of my head:
Tab closing behaviour on Chrome/FF. Close a tab, other tabs shift but don't change size immediately so you the next tab's close button is directly under the mouse and can bel clicked to close another tab (and another, and ...).
Another one: the typical chat app with servers/groups/contacts on a list on the left and the chat on the right (and possibly threads on the far right).
There is no good standard for this, everyone cooks their own soup so stuff you learned for Slack doesn't apply in Discord etc. I.e. it's a pattern of some sort but there are no Windows/macOS/Qt/GTK interface guidelines covering this case and/or suggesting best practices. This includes e.g. platform standard keybindings to select stuff in such apps (at best Tab switching works).
Another one is use of (some) Markdown-inspired stuff in chat apps. I.e. `monospaced` ```monospaced multline``` or even ```<language for syntax highlighting> ...```.
In Slack ``` works but ```<lang> doesn not (but does in Discord, used to work in Slack in the past, I think).
I think there are many such patterns that are maybe not as groundbreaking than the invention of tabs (90's?), combo boxes/menus (also 90's? When there are too many choices for radio buttons) etc.
But beause they are used in some form (or another, unfortunately) by many apps now, the OS vendors should define a best practice for implementing their end-user facing functionality/behavior in their HCI guidelines.
Even if the platform itself doesn't provide a ready-made widget for each such case.
Hope that makes sense and explains what I meant.
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.
In its current state is only useful for CLI or services, unless you feel like doing WinUI team's work for free.
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?
On the topic of Rust GUIs on Mac, this was recently in the news:
https://github.com/emilk/egui/commit/e1f348e4b24c2fa83d25c6a...
There are Rust GUI toolkits like Druid with custom controls that have elements outside the bounds of the main window.
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.
I don’t really see the reason for multithreaded UIs either. A single UI thread works perfectly fine if you move your business logic off to a separate thread. Most people are just too lazy to do that, and start developing their app with the business logic running synchronously on the UI thread; which works for a while, but eventually reaches a point where it starts blocking the UI event loop; then they try bandaging it by moving certain pieces to a background thread and they shoot themselves in the foot with thread-safety issues. The way to solve this is not by making the UI framework multi-threaded… Simply be disciplined with UI ↔ business logic separation from the get go and all these problems go away. Yes, I know it’s so tempting to call the database directly from the button click handler - but don’t do it.
First of all, up-to-date official packages are now published to Maven Central as part of the release process, so you can just add it as a dependency as easily as with any other library. Until recently you would have had to either fiddle around with Eclipse's alternative package management system, download it manually or use someone's unofficial Maven artifact. But that's now resolved.
Secondly, if you bundle a Java runtime customized with jlink (as is recommended these days), an SWT application is actually smaller than a Swing application. When you don't use Swing, you can exclude the entire "java.desktop" module, which is slightly larger than the SWT libraries.
It looks mostly ok, but on Linux it doesn’t support smooth scrolling (even though this is supported by gtk). You also can’t use the meta key (windows key / cmd) as a modifier key for keyboard shortcuts. So I can’t configure intellij to use all the keyboard bindings I’m used to from macos. Again, this isn’t a problem with other gtk apps. It’s just (apparently) a platform limitation of whatever Java toolkit they’re using.
So in my experience it’s 95% of the way there. I certainly prefer it over Xcode, but it has issues that native apps don’t have.
It's amazing the amount of work JetBrains has put into this.
* 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.
Use Electron and you'll get OS-native buttons and other form controls.
As far as I know Electron is based on Chromium. And Chromium doesn't use native controls, it has its own custom controls that sometimes look similar to native controls.
All of them I glady ignore on private owned computers, or use the browser version, they are anyway Web apps.
Granted these applications boast a ridiculous amount of features and are incredibly complex putting them on the opposite end of the spectrum compared to simple GUIs and chat/productivity applications.
To me, it's nice that platforms provide native toolkits* to provide this level of integration. But I don't view any app as "native" unless it comes from the party making the platform, as they are really the only ones that actually have to adhere to their human interface guidelines to the fullest extent.
* On Linux this is more up-in-the-air. I personally don't consider GTK and Qt as native toolkits, but the foundational pairing for things like libadwaita and KDE Frameworks which provide the associated platform widgets and HIG. Using the toolkits directly is fine and will mostly work, but it's not the same as a "native" application.
With C code often being unreadable, I found that Vala applications often have readable examples of how to use UI components. However, tooling support for Vala is extremely limited so experimenting with existing code may be a annoying. That said, I've had good experiences with opening these projects in Gnome Builder (once it got updated to work on my computer again).
If your component of choice doesn't have a Vala example, I'd resort to reading the documentation. Reverse engineering the API from the docs is often quite doable if you first look at how a component you do understand.
I've had similar problems, but worse, when I tried mixing Rust and Qt. I've never used Qt before so that doesn't help, but I found the API even less predictable in many cases, with some docs and examples several versions out of date.
I'd seriously consider just shipping a WINE'd Windows binary (using a tool like https://winepak.github.io/) for Linux targets with the current state of Rust GUI platforms. The amount of game UI/custom UI libraries out there is impressive but they all feel terribly wrong when I try to use them, in the same way most Flutter apps are terrible to use on desktop.
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.
Rust is a nice language for that since it is already a "next-generation" language in terms of memory safety and its momentum is still building. Projects like Druid, while far from ready, are a good starting point.
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.
This is why Rusts' "Are we GUI yet?" and posts like this are a good thing. Eventually some new toolkit will arise that ticks all the boxes. We are not there yet and it will require a huge amount of work.