Pretty cool project, seems like it's becoming more realistic to write cross platform native desktop applications with OS-specific GUIs in Rust.
It's not too far from the write-once-run-everywhere philosophy of React native, Electron and similar. One could write their UI state and application logic once while maintaining 3 entry points using the various platform GUI bindings (gtk-rs, cacao, win32?) to represent the UI state.
This has the advantage of a project feeling natural to the platform while still allowing for code reuse between platforms - though you would still need to rewrite widgets/components for each platform independently.
Something that isn't talked about much in the GUI world (outside of mobile development) is how essential multi-threading is to a great application experience. After all, you can't horizontally scale a client device so it's important that an application is able to maximize its use of the available hardware. Rust's borrow checker/ownership model eliminates dangerous multi-threaded code which makes it practical to write highly efficient GUI applications.
Could be good for projects like cross-platform terminal emulators or code editors.
> Something that isn't talked about much in the GUI world (outside of mobile development) is how essential multi-threading is to a great application experience.
Yes it is. Heavyweight desktop GUI applications like DAWs or CAD or image/video editing are old established technology.
> This has the advantage of a project feeling natural to the platform while still allowing for code reuse between platforms
Having written cross platform native applications: This is a pain in the ass to do well - and there isn’t a particular reason this hasn’t been doable in C/C++ since forever - Rust isn’t some silver bullet. “Abstracting” away the native GUI/UX seems to be a common pitfall for junior devs - how hard can it be they think - then they learn why Qt exists.
> It's not too far from the write-once-run-everywhere philosophy of React native, Electron and similar.
Electron is about as far removed from the philosophy of targeting platform native toolkits as one can get.
You can't write good UI apps with cross platform code. The basic idioms of each platform are different.
You can write your core application logic once and share it, but you need to have the interaction with the actual UI/window manager be per-platform. The reason electron apps are so bad on Mac is not that the core application logic is bad, it's that a whole bunch of basic Mac platform behaviors are broken.
"modern" cross platform UI toolkits are no better than Java. To paraphrase Ford: "you can do any platform you like, as long as it's windows".
[edit: to be very clear, I include "catalyst" in the cross platform toolkits that make noticeably worse apps on Mac. Trying to share a single interface "language" for different platforms just leads to what is at best mediocre UI.]
Interesting to see that AppKit is fully supported before UIKit, usually it's the reverse (if AppKit is supported at all). I suppose it kind of makes sense… the case for sharing a Rust core across platforms is stronger on macOS, because on iOS the optimizations you're trading away (such as the native network stack scheduling requests from apps to fire while the antenna is already awake) have a bigger impact on iDevices.
Tangentially related, I'd to dabble in Rust at some point but the syntax and memory management leave me trepidatious, and I'm not sure that it'd be the tool I reach for when developing apps with UIs… from a distance it feels better suited for CLI tools, back ends, and the nuts'n'bolts parts under the hood of UI apps. In comparison it makes some tradeoffs but I really enjoy writing UI apps in Swift (albeit in UIKit/AppKit — SwiftUI needs more time in the oven).
> Tangentially related, I'd to dabble in Rust at some point but the syntax and memory management leave me trepidatious [...]
Assuming your trepidation is because memory management is somehow more manual in Rust I would argue that it's actually not. This isn't something I'm saying because I want to convince you to use Rust; I'm actually of the opinion that Rust doesn't give you enough direct control of memory allocation and has iffy support for custom allocators on top.
Rust's memory management is much more like a garbage collected language in practice, hence why I consider it too indirect.
There’s a proposal to allow C++ and Swift to interact in the same way that objc and C++ interact, and if that were to eventually become part of swift then objc’s days are numbered. Right now, one of the most significant reasons to continue using objc is that you don’t have to wrap everything in a C API.
A tangent: does anyone have recommendations for a library for easy Swift-Rust interop? This is a cool tool, but I’d much rather make a GUI natively with e.g. SwiftUI and then call out to Rust for business logic. The previous times I’ve looked into this, both languages had to communicate through a C intermediate, and handling more complex types became a chore…
Mozilla's uniffi-rs is really good. You write a common IDL and the bindings are generated automatically. It supports Swift, Kotlin, Python, Ruby and JavaScript (not in the official repo).
This is off topic, but thinking about portable desktop apps, why didn’t JavaFx become more popular? What is JetBrains using for its sophisticated GUIs? Is it just Swing? It would be great if Rust could be used to write portable high quality desktop apps.
If you use the Cocoa API with ObjC or Swift, you get Automatic Reference Counting (ARC), generated by the compiler. I guess with this you'd have to retain / release your objects manually again?
No. This is rust bindings to the native apple UI toolkits, UIKit and AppKit (on iOS and macos respectively). Using a library like this, your software will have a fully native look and feel. The result should be indistinguishable from the equivalent Swift or Obj-C app from the point of view of a user. Including all accessibility hooks, fully native widgets and things like that.
The downside is that code written against this api will not work on any other platform.
It could be a Portland reference. The city had a gourmet chocolate shop called Cacao that served "drinking chocolate" from 2005 until 2020. I know because I went in there after getting lost and drenched in a Portland February, and the staff there were kind enough to bring me towels and let me wait out the downpour while I sipped chocolate.
But more than likely it's just a reference to Apple's Cocoa api.
[+] [-] apatheticonion|2 years ago|reply
It's not too far from the write-once-run-everywhere philosophy of React native, Electron and similar. One could write their UI state and application logic once while maintaining 3 entry points using the various platform GUI bindings (gtk-rs, cacao, win32?) to represent the UI state.
This has the advantage of a project feeling natural to the platform while still allowing for code reuse between platforms - though you would still need to rewrite widgets/components for each platform independently.
Something that isn't talked about much in the GUI world (outside of mobile development) is how essential multi-threading is to a great application experience. After all, you can't horizontally scale a client device so it's important that an application is able to maximize its use of the available hardware. Rust's borrow checker/ownership model eliminates dangerous multi-threaded code which makes it practical to write highly efficient GUI applications.
Could be good for projects like cross-platform terminal emulators or code editors.
[+] [-] riceart|2 years ago|reply
Yes it is. Heavyweight desktop GUI applications like DAWs or CAD or image/video editing are old established technology.
> This has the advantage of a project feeling natural to the platform while still allowing for code reuse between platforms
Having written cross platform native applications: This is a pain in the ass to do well - and there isn’t a particular reason this hasn’t been doable in C/C++ since forever - Rust isn’t some silver bullet. “Abstracting” away the native GUI/UX seems to be a common pitfall for junior devs - how hard can it be they think - then they learn why Qt exists.
> It's not too far from the write-once-run-everywhere philosophy of React native, Electron and similar.
Electron is about as far removed from the philosophy of targeting platform native toolkits as one can get.
[+] [-] olliej|2 years ago|reply
You can write your core application logic once and share it, but you need to have the interaction with the actual UI/window manager be per-platform. The reason electron apps are so bad on Mac is not that the core application logic is bad, it's that a whole bunch of basic Mac platform behaviors are broken.
"modern" cross platform UI toolkits are no better than Java. To paraphrase Ford: "you can do any platform you like, as long as it's windows".
[edit: to be very clear, I include "catalyst" in the cross platform toolkits that make noticeably worse apps on Mac. Trying to share a single interface "language" for different platforms just leads to what is at best mediocre UI.]
[+] [-] hot_gril|2 years ago|reply
[+] [-] kitsunesoba|2 years ago|reply
Tangentially related, I'd to dabble in Rust at some point but the syntax and memory management leave me trepidatious, and I'm not sure that it'd be the tool I reach for when developing apps with UIs… from a distance it feels better suited for CLI tools, back ends, and the nuts'n'bolts parts under the hood of UI apps. In comparison it makes some tradeoffs but I really enjoy writing UI apps in Swift (albeit in UIKit/AppKit — SwiftUI needs more time in the oven).
[+] [-] 59nadir|2 years ago|reply
Assuming your trepidation is because memory management is somehow more manual in Rust I would argue that it's actually not. This isn't something I'm saying because I want to convince you to use Rust; I'm actually of the opinion that Rust doesn't give you enough direct control of memory allocation and has iffy support for custom allocators on top.
Rust's memory management is much more like a garbage collected language in practice, hence why I consider it too indirect.
[+] [-] imbnwa|2 years ago|reply
[+] [-] Klonoar|2 years ago|reply
AppKit is first because this was extracted from a cross platform GUI library I was building years ago, and it’s just less cumbersome to iterate on.
[+] [-] kennywinker|2 years ago|reply
Five years would shock me. I’d say more like ten. It’s gonna take a huge concerted effort to get rid of objc in macos, and idk if it’s worth it
[+] [-] jb1991|2 years ago|reply
[+] [-] Klonoar|2 years ago|reply
[+] [-] jashephe|2 years ago|reply
[+] [-] agg23|2 years ago|reply
[+] [-] lukax|2 years ago|reply
https://github.com/mozilla/uniffi-rs
[+] [-] drizze|2 years ago|reply
https://youtu.be/8ApcIOZe9qg?t=1921
[+] [-] todd8|2 years ago|reply
[+] [-] RMPR|2 years ago|reply
Oracle ditched it a long time ago [0]
> What is JetBrains using for its sophisticated GUIs? Is it just Swing?
They use custom Swing components [1]
0: https://www.infoworld.com/article/3261066/javafx-will-be-rem...
1: https://plugins.jetbrains.com/docs/intellij/user-interface-c...
[+] [-] tempodox|2 years ago|reply
[+] [-] xanathar|2 years ago|reply
This is, incidentally, how the servo bindings to core-foundation work (I prefer those bindings where there is overlap).
Servo bindings: https://github.com/servo/core-foundation-rs
Other crates of interest on this topic: - https://crates.io/crates/objc - https://crates.io/crates/block
[+] [-] IshKebab|2 years ago|reply
[+] [-] Klonoar|2 years ago|reply
Nope, retain on create/etc and release on drop happens automatically.
[+] [-] meatjuice|2 years ago|reply
[+] [-] josephg|2 years ago|reply
The downside is that code written against this api will not work on any other platform.
[+] [-] ushakov|2 years ago|reply
[+] [-] Klonoar|2 years ago|reply
[+] [-] nasretdinov|2 years ago|reply
[+] [-] brundolf|2 years ago|reply
[+] [-] tempodox|2 years ago|reply
[+] [-] bitwize|2 years ago|reply
But more than likely it's just a reference to Apple's Cocoa api.
[+] [-] tobinfricke|2 years ago|reply
[+] [-] Klonoar|2 years ago|reply
Never seen Portlandia, so no. Just a Cocoa pun!