Hacker News new | past | comments | ask | show | jobs | submit login

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.


> Rust isn't some silver bullet

Rust codebases extend in size and scale to larger teams fundamentally better than C++ / C. Rust offers more leverage in building ambitious system software.

Since you mention Qt, imagine writing all of Qt in x86 assembly, vs. C++. "There's not particular reason this isn't doable." C++ to Rust is a similar jump. No silver bullets; just leverage.

Cross-platform toolkits — especially those aiming to abstract over native UI/UX patterns — are an ambitious, if not Sisyphean domain. Qt was about the best we could do in the C++ era, but a new era has dawned.


> Qt was about the best we could do in the C++ era, but a new era has dawned.

Based on the way the Rust community has been spinning its wheels for years in getting something even within a light year of feature parity with Qt, if a new era has truly dawned you might need to wait for the next one.

> Rust codebases extend in size and scale to larger teams fundamentally better than C++ / C. Rust offers more leverage in building ambitious system software.

I like Rust - but this is classic RSF/RIIR copypasta.


> getting something even within a light year of feature parity with Qt.

Qt is also old as Jesus, and making a cross OS GUI is extremely hard.

And you can non-ironically say the same about non-Qt toolkit written in C++.

What grandparent probably means something that leverages parallelism and/or GPU acceleration.


> And you can non-ironically say the same about non-Qt toolkit written in C++.

Maybe. Gtk and its related libraries don’t cover everything Qt does, but they’re not small either. It’s also fair to include the native toolkits themselves on their respective platforms that are written in a mixture of C++/C/Objective C.

I also will point out that one of the cross platform toolkits with some traction in the Rust world is amusingly fltk.

> What grandparent probably means something that leverages parallelism and/or GPU acceleration.

You mean like QtQuick/QML, skia (basically this is the effective underpinning of electron and flutter) or Dear Imgui, etc. There are a handful of widely used GPU based GUI libraries. The above examples are all C++.

> leverages parallelism

The memory model of Rust is still whatever C++ does. I get that Rust has some nice features and C++ makes it easy to fuck your self but people have been doing large scale parallel software development for years in C++.

> Qt is also old as Jesus, and making a cross OS GUI is extremely hard.

The claim was we are in a new era of “leverage” that will make the hard very easy (that’s what it sounded like at least). I found the claim at best vague and low on specifics or evidence - hence the mention of RESF.


> Maybe. Gtk and its related libraries don’t cover everything Qt does

And therein lies the problem. Qt is semi-open (the parent company tried to close source it[1]). If a commercial company has no interest in maintaining it, there is even less hope for other open source approaches.

Best cross OS system are almost always backed by a commercial supporter. See Skia - Google, Java Swing - Oracle, Qt - QtCompany, etc.

OSS offerings were always runner ups (e.g. Gtk - Gnome).

> The memory model of Rust is still whatever C++ does. I get that Rust has some nice features and C++ makes it easy to fuck your self but people have been doing large scale parallel software development for years in C++.

Memory model of Rust is undefined[2]. It might be anything Rust does to accomodate C++ bindings, but I don't think they really settled on one.

I'd like to add - people have been doing large scale parallel software development for years in C++, in spite of C++. What is a line of comment in C++ in Rust is a type system constraint.

It's a difference between having a seatbelt (Rust) and holding a piece of seatbelt (C++).

Rust was literally made to address C++ shortcomings when it comes to parallelism.

> You mean like QtQuick/QML, skia (basically this is the effective underpinning of electron and flutter) or Dear Imgui, etc. There are a handful of widely used GPU based GUI libraries. The above examples are all C++.

No. I mean like WebRenderer[3], Lyon[4]. Most things should be parallelized and done on GPU/SIMD. Layout, font shaping, etc.

[1]https://news.ycombinator.com/item?id=25656932

[2]https://doc.rust-lang.org/reference/memory-model.html

[3]https://github.com/servo/webrender

[4]https://docs.rs/lyon/latest/lyon/


> No. I mean like WebRenderer[3], Lyon[4]. Most things should be parallelized and done on GPU/SIMD. Layout, font shaping, etc.

https://www.reddit.com/r/rust/comments/vwdxim/announcing_lyo...

https://www.reddit.com/r/rust/comments/vwdxim/announcing_lyo...

Also neither of your examples do any text shaping on the GPU. Lyon doesn’t do text and Webrender (which depends on freetype) does regular old glyph cache built in CPU texture rendering. Neither involve GPU shaping.

https://github.com/servo/webrender/blob/master/wr_glyph_rast...

Still trying to understand what earth-shattering, "leverage" levering feature this brings compared to Skia.

> Memory model of Rust is undefined[2]. It might be anything Rust does to accomodate C++ bindings, but I don't think they really settled on one.

> I'd like to add - people have been doing large scale parallel software development for years in C++, in spite of C++.

Do you not see at least some level of contradiction to these statements?

This is probably the more relevant explanation: https://doc.rust-lang.org/nomicon/atomics.html. "At very least, we can benefit from existing tooling and research around the C/C++ memory model."

Perhaps respect your elders a bit more?


> Also neither of your examples do any text shaping on the GPU.

Sorry, font rendering. I thought font shaping is part of it. Pathfinder and Lyon were libs.

> Do you not see at least some level of contradiction to these statements?

No? They are discussing Simd and generic interactions.


> Sorry, font rendering. I thought font shaping is part of it. Pathfinder and Lyon were libs.

They don't do GPU font rendering either.

Pathfinder isn't widely used -- see my original post about "spinning wheels".

GPU font rendering hasn't demonstrated much real world value for GUIs. Where it does get used a bit is games - an industry that is overwhelmingly C++ for the foreseeable future.

> No? They are discussing Simd and generic interactions.

I was responding to this: "I'd like to add - people have been doing large scale parallel software development for years in C++, in spite of C++."

Regardless, Rust still depends entirely on the years of research and development in C++ for a memory model which is a core underpinning of parallel programming.


> Pathfinder isn't widely used

Ofc. Servo was shut down before anything could happen with it. Making production-ready GPU font rendering is hard.

It's not spinning wheels anymore than OSS life cycle is spinning wheels (author needs functionality X author makes a useful lib for X -> it becomes popular -> amount of work increases -> due to pressure/changes in life author abandons lib -> another author has needs functionality X -> ...)

> I was responding to this: "I'd like to add - people have been doing large scale parallel software development for years in C++, in spite of C++.

Saying Rust has issues doesn't negate C++ having massive issues but also a bigger mindshare.


Qt is fully open source. The LTS version is closed source, but other framework don't even have a LTS version.


Open source for now. Qt seems dedicated to making it close source.


> Rust codebases extend in size and scale to larger teams fundamentally better than C++ / C

There are about 3-4 orders of magnitude more large C++ projects developed by large teams compared to Rust projects as of now.

This might change in future, but your claim seems a bit premature.

In a previous company I worked at, we were forced to rewrite a greenfield project in C++ because it was going too slow with Rust. The team managed to ship the thing in a few months, compared to spending a month getting nowhere with Rust.


> Qt was about the best we could do in the C++ era, but a new era has dawned.

Nope, the best is C++ Builder with VCL, Visual Basic/Delphi like experience with C++.

However very few have tried it out unless they work for big corporations.


C++ to Rust is not a similar jump as assembly to C++.

Qt may be the best toolkit so far. If Rust is going to let us make a big jump, I can’t wait to see that happen. What are the best contenders so far?


I do have a naive view on native GUI development because I have little real experience in it - I very much appreciate your insight.

> “Abstracting” away the native GUI/UX seems to be a common pitfall for junior devs

I would like to know more about what you mean here; my description of a "virtual UI" that you bind to from the native toolkit is an abstraction to the UI - but it's not an abstraction like Flutter which tries to merge all native widgets into abstracted widgets. My concept still requires you to write multiple native entry points using the UI kits of the target platforms.

` (GTK entry || Cacao entry || Win entry) => Virtual UI => application logic `

The idea is that the virtual UI would be an in-memory representation of the UI (have virtual buttons, labels, etc). It would be the job of the entry to correctly represent/bind to that virtual UI with the relevant presentation tool kit. The output binary would be specialised to the platform/UI kit used in the source entry point.

It seems sensible on the surface to decouple the UI from the native presentation as it minimizes the requirements of the native side to constructing the UI and binding to the virtual UI - but I would love to hear your thoughts.

I have not tested this architecture outside of web development but I imagine adding new UI targets (like web assembly, QT, etc) would be easier as it wouldn't require any changes to the virtual UI or application logic and would be a matter of creating a new entry point representing the UI for the new target.

> then they learn why Qt exists

Does QT feel native on MacOS, Windows and Gnome?

> Yes it is [talked about]

Could be my personal echo chambers talking here - but multithreading is almost never spoken about and/or often intentionally disregarded in modern web/electron applications.

It sucks because so many applications are written using Electron or other similar web wrappers.

> there isn’t a particular reason this hasn’t been doable in C/C++ since forever - Rust isn’t some silver bullet

Not dismissing this, I was more impressed that Rust offers a thread safety guarantee through its ownership model making it interesting from a contributor scalability standpoint.

I was thinking that it might make it easier to have more engineers working on a high performance GUI project because it would be significantly harder to break.

As an example; I could imagine if a company assigned a team of TypeScript/JavaScript developers with different experience levels onto a GUI project written in something like Go, there would be a lot of thread safety issues and seniors would spend a lot of time combing PRs for thread safety issues.

Rust, while perhaps not as simple from a syntax/types/symbols standpoint, offers an interesting development modality for these sorts of projects. I would expect that it would result in a more hands off contributor experience.

> Electron is about as far removed from the philosophy of targeting platform native toolkits as one can get.

Sorry I wasn't describing Electron as targeting platform native decorations - just that it promises an OS agnostic UI framework (write once run anywhere) at the expense of a diminished native experience and poor performance.

My point was that it might be interesting to explore the idea that a multi-entry native toolkit application fulfils the same "write once run 'anywhere'" promise but without the downsides.


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.]


Can you give an example of something can only be done in a native app?

And why wouldn't a hybrid approach work? I.e. the majority of the code using the cross platform toolkit, and a small amount of code per platform using the native API.


> Can you give an example of something can only be done in a native app?

Accessibility, text field behaviors, control animations looking right, window resizing behaviors, any system settings related to UI applying properly, printing, export to PDF, rich text copy and paste, normal power and memory use, the engineers working on the next OS release being able to fix your app if they break it, your app updating to the next OS version's UI changes automatically…


afaik not a problem with apps written in something like react native which use platform specific widgets and common business logic.


There's more to a UI layer than individual controls. Like spacing between them fitting platform conventions, and window resizing and text size needs them to coordinate.


It actually is. Fortunately, the quality of apps dropped significantly, allowing these technologies to compete.


To the contrary. Developing native apps is so painful that the average S&P500 company will treat it like a root canal. Given how meaningless native functionality is to them, they won't hesitate at the opportunity to serve you a shitty Electron app. Many of them are only successful because they didn't waste time writing native apps for each platform.


why should it? it makes no sense to me; you can do anything

It just might be that you don't go all the way, because you think a 80% sufficient result is enough for you


First off, I was not talking about native vs non-native, I was talking about toolkits. native vs non-native is a different though related problem.

> And why wouldn't a hybrid approach work? I.e. the majority of the code using the cross platform toolkit, and a small amount of code per platform using the native API.

I literally said you could/should do that?

Answering your actual question though. The issue is not "something can only be done" in X, it's a "is your app consistent with the platform it is on". And that's where "cross platform" apps are invariably annoying - none of the electron apps correctly do find on the Mac (this is largely because chrome/blink intentionally removed the correct logic from webkit and as these apps just do whatever blink does that's what we get).

The problem is that cross platform toolkits (Qt, Wx, etc) primarily target windows so all the behaviors are geared to that platform. It is very obvious whenever you are using a Mac app that is written using a cross platform toolkit, as their are just many different little ways that things behave incorrectly - a death by a thousand cuts problem.

Electron is just a special case of this: because your "app" is just a web page you don't have an actual ui toolkit, cross platform or otherwise, to handle all the usual UI behavior and have to reimplement it all yourself. That's a lot of work and very hard to get right, so generally electron apps don't even attempt to, but they're "popular" because there's literally no choice. People on Mac use discord, slack, teams, etc because there is no option - if your employer decides they're using slack or teams, that's what you have to use. The fact that the UI is janky, the cpu is high, basic key commands don't work, it doesn't handle drag and drop correctly, etc is not relevant: it's what you have to use.


Cross platform toolkits are a way of getting something good enough, quickly. Our standards may be different, but I would say you can get something good. You likely won’t get something great though.

I agree with your statement about modern toolkits being no better than Java, but Java is pretty good. I’d have no problem starting a new project with it today.

All that said, I’d much rather have a well written native application than a well written cross platform application.


If anything, many of them are much worse in capabilities.

https://www.oreilly.com/library/view/filthy-rich-clients/978...


Yet among the most used apps a lot of them are cross platforms: chrome, ableton live, vscode, figma, any game under the sun, slack, discord, … I would even argue that very few still develop directly with native ui toolkits directly.


You mean the slew of electron apps that are well known to be annoying to use and inconsistent with the rest of the software on a Mac? Games not so much because they aren't using any platform toolkit.

But also "developers using cross platform toolkits because it's cheaper" does not undermine my argument "you can't make good apps", I could make the exact same argument about cross platform Java apps.


You can write "good enough" ones though, and I've been doing it for years.


The GUI bindings are usually the hard part.


Speaking of, does anyone know how Qt bindings for Rust are these days? Last time I looked, there were several awkward Rust APIs for Qt, suffering in part from the fact that Qt's API is inheritance-based.


I think it's pretty difficult mapping the Qt memory management model to Rust, for the same reason we haven't seen working Golang bindings for Qt either. I have some experience with the Python bindings (PySide or PyQt) and both of them use pretty extensive wrapper generator frameworks specially developed for the task (SIP in the case of PyQt, Shiboken in the case of PySide), coming up with something like that is not an easy task at all. And Python is a language that was pretty much intended to act as a foreign function wrapper around low-level languages, while Rust & Golang are not primarily intended to be wrappers for other languages.


> https://github.com/therecipe/qt

Do these not work? (Not a rhetorical question - I haven’t tried them.)


They used to work until the big modules change a few golang releases ago. Now, nothing works anymore unless you exhume a sufficiently old golang compiler.

The project also seems dead since 2020 or so, a current fork is https://github.com/bluszcz/cutego/ But I haven't tried that one.


I see what you mean about this particular project, but more generally, you can certainly use pre-modules Go code with current Go compilers. See e.g. https://github.com/golang/go/issues/37797 (a case of someone not RTFMing, but the response illustrates how it's done).

If you just want to pretend modules never happened, then export GO111MODULE=off and use the latest Go compiler.


In most cases, these things would work, but not here. Tried everything, nothing works except using a pre-modules-compiler.

In general, golang seems to work best with golang-only projects. As soon as there are other languages in the mix, like C++ here, things get very ugly very fast.


Ah, I think I misinterpreted what you meant by "nothing works anymore". I thought you were saying that no old Go projects were usable with new Go compilers. I believe you that this particular project may not work with the current toolchain.


Ah, yes, that wasn't sufficiently clear in my text. In almost all projects I've done/used, go modules work fine and are nice. It is just this one library that I know ceased to work.


There is a recent article about this on r/rust https://blog.logrocket.com/build-desktop-app-qt-rust/




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: