Current state of GUI development in Rust?

This more or less reflects the focus that was agreed upon for 2018: clean up the growing backlog of "mostly finished but unstable" functionality by polishing and shipping what is already almost there, to increase the surface area of production-ready Rust.

GUI in Rust is clearly an area that requires more exploration before it can be pushed through the finish line like this: you can certainly already build stuff, but further ownership model and general API design groundwork are needed before it becomes an enjoyable and natural activity.

15 Likes

I'm a C++ dev, been exploring the potential of Rust for over a year now, patiently waiting for the GUI side to look like it's ready for a full desktop application. Looks like Servo would be a great solution once it's ready. I mainly use the JUCE framework to build desktop apps and its mostly great, not perfect for GUI stuff but certainly more than good enough for the majority of apps. It does take the approach of rendering most widgets rather than using native components (A problem for screen readers).

Looking forward to the day I can jump into Rust development knowing that its possible to build a cross platform desktop app without too much bleeding edge pain!

5 Likes

I'm new to Rust and only just beginning to explore the language and its possibilities. I love it so far!

As regard to GUI I'm thinking of using the web stack to build a modern, discoverable, extendable web app powered by Rust that runs at near native speed. I read the comments on Electron / Atom with interest but now that we live in a Service Worker world I don't think we need them. How about buidling with the following stack?

Front End:
HTML
CSS (Generated using PostCSS + CSSNext so we can use future CSS standards now)
Javascript (Transpiled from TypeScript) for native Web Components
Service Workers

Backend
Rust + Web Assembly

This would have to run in browser which I tend to think of as a container for the apps GUI.

1 Like

I'm still hesitant to go the electron route. Rust apps should be accessible - that means usable on high-end and low-end computers. Including the bloat of an entire web engine makes certain apps very frustrating on lower end hardware. Even Discord (which has been fairly optimized) struggles to run on a cheaper laptop of mine.

I believe we can exploit the power of rendering engines like WebRender without needing to include a full HTML/CSS/JS rendering engine.

6 Likes

This sounds sensible, but, you'll likely find that for any GUI, you end up re-creating something along the lines of HTML/CSS. I don't see any need for something like JS in the discussion. Completely orthogonal concern. Qt/QML is a good model I think to start as a point for moving forward. I think something like XUL/XAML/QML only in Rust and for Rust built atop WebRender would be the right way forward.

1 Like

Sounds exactly like what @huytd did by building on top of zserge and @Boscop’s work: GitHub - huytd/kanban-app: Kanban board built with Rust and Elm

1 Like

My interest in a GUI is something more like the Gnome library than GTK.

I started an application with C and GTK. Both were too low level for what I wanted. Rust would remove some of the junk you have to do in C and perhaps reduce the development time when the compiler can spot a mistake instead of waiting for run time. Rust may make it easy for my application to update in the background while working with the display in the foreground.

For the GUI, GTK requires building everything in detail. The Gnome version has functions for creating lists and similar higher levels of interaction. I tested Vala plus Gnome but both have problems. I am looking at the libraries mentioned in this topic to see if any have an equivalent higher level and work across the major desktop operating systems.

As an example, is it easy in Relm or any of the other Rust compatible GUIs to create a scrollable window showing part of a list? Are there examples of doing it in Rust plus Conrod/etc?

1 Like

Rust is great for a lot of things, but it's pretty much fundamentally incompatible with GUI development IMO. Despite what people might think of OOP, there are some things you do need inheritance for.

This is reflected in the source of every Rust GUI lib I've seen so far: they pretty much all just do their best to simulate the inheritance that the language simply doesn't have, because there's no other logical way to represent visual components that are directly based on (or "descended from", if you will) other visual components.

4 Likes

Respectfully, I would not be so negative on the count of Rust GUI. We are yet to see GUIs NOT based on OOL paradigm, once right piece of mind sets in. Otherwise, we would find ourselves locked into self-fulfilled prophecy of not being able to shift the paradigms. However, history shows otherwise - paradigms do get shifted. If that was not the case, we would still struggle with goto statement :wink:

8 Likes

For a very interesting approach, see Victor Porof's rsx work: https://github.com/victorporof/rsx-primitives

2 Likes

I am still exploring Rust as an option, but the reasoning behind its design is something I feel promising. So, I would not brag about what Rust can or cannot do. I just want to add some mental peanuts to chew on when GUI is in question.

1st, I believe GUI is not Rust problem per se, rather, it is much greater problem than being seen from the angle of one particular language.

We have recently changed our perspectives on information technology we use (recently means less than a decade). If we talk about GUI - which GUI we talk about? We have a spectrum of devices starting from relatively small mobiles (that may not be 'smart' ones), going over number of mobile variants, then we have 'desktop' variants (even when desk is your lap) and on the other side we have 'smart' TVs and even larger info panels - and that is just in terms of screen size.

To this we can add vertical diversity in the terms of functionality: are you after GUI that is used for rendering 3D game, stereoscopic VR or it is a GUI for business or general application or it is a GUI for embedded systems, controllers (home or industry or space rocket or your car or your watch or nuclear plant)? Is your GUI driven by buttons, mouse, touch or virtual sensors? Therefore, when we say GUI we can think of wildly different appearances and functionality depending of the type of application.

Now we have playing field. Choose your game. This is baseline of GUI pondering.

2nd. Taking this in account I cannot but get impression that if Rust attempts to be a systemic language (maybe better said system programming language) How come that it would not be suitable for making GUI systems?

The problem lies elsewhere as I have mentioned before. OO paradigm has caused GUI's to become OO inclined, but nothing stop us in general to write new GUI that is NOT OO inclined. Perhaps Rust could go forward with that.

Producers of IT nowadays do something that one of thinkers named De Bono call surpetition. Surpetition is superior to competition. What we have today is trench war of technologies. Each major industry leader is trying to wrap up its users (hence developers) into its own paradigm of OS, languages and GUI that goes with it (Apple, Google, Oracle, Microsoft ...) so struggle to squeeze one concept into another or trying to be trans-concept is causing much pain. Not impossible but problematic.

I am not really sure what Mozilla wants to do with Servo (did not really explored that venue). But one thing is sure, they will probably not go out of what current expectation of web based system is.

Question now becomes something else: Would Rust bear a different type of GUI? (Lets say that another language - Go - who boldly went not to be OO IMHO is also still struggling/suffering with lack of GUI, perhaps for same reasons). I would expect that these two system languages do define new GUI playing field - NON OO inclined GUIs. How they would look like?

I think we have chance to see something radically new and shift the paradigms.

8 Likes

There are two GUI toolkits I know of that I would expect to work well with rust. One is iup for which rust bindings have been written a couple of times (and now seem abandoned?). The other is Tcl's Tk library.

The Tk library is much maligned because it isn't pretty on Linux (although using a theme helps) & probably wouldn't satisfy Mac purists. But it looks fine (i.e., native) on Windows 7 (Tk 8.5 or later). Tk uses inheritance in the conventional GUI sense that if you create say a frame (e.g., a window), you pass that frame as the parent of the widgets you create inside it. But Tk being originally for Tcl, everything is really passed purely as text strings. So if you do (in pseudo-code) frame = ttk.Window(options), the frame is not an object but just a string that is used internally by Tk to identify the frame (e.g., ".frame"). So if you then do checkbox = ttk.Checkbox(frame, options), the frame is still just a string, as is the checkbox (e.g., ".frame.checkbox"). So this should be "easily" translatable into Rust. I should mention however, that I don't know of anyone succeeding in writing bindings for Tk directly; I think most bindings are to Tcl and access Tk through that. Again, there are a couple of rust bindings for Tcl (and again, both seem to be abandoned).

For Windows-only, an interesting prospect seems the pure rust xi-win-shell library, part of https://github.com/google/xi-win; this uses the win32/directx bindings so seems to `just work'.

I have written a command line tool in rust that I'm very happy with. This is aimed at technical users. But I also want a GUI that offers similar functionality for non-technical users. I only need this on Windows. I looked at the win32 API but that seems intimidatingly large (& I'm not familiar with it). I tried Conrod but it won't run on Win-7-64 with rust 1.2[4-6]. I tried SDL2 but it doesn't have widgets and creating them all would be too time consuming. Gtk only seems to work with the mingw compiler on windows & I'm using the msvc toolchain; and in any case Windows seems to be a second-class citizen for Gtk which seems to model the Mac rather than Windows-style GUIs. I also tried sciter which does work, but it doesn't have many widgets (e.g., no tab widget), and although you can make them, I prefer to write all my GUI code in code not a mixture of code/HTML/CSS. I also tried the rust bindings for imgui and libui, again without success.

So, in the end I've started to create the GUI using Python 3/Tkinter (Python's Tk bindings) & will use std::process::Command to execute a rust app that I've created that wraps the same functionality as the command line tool provides. (I didn't use Qt because it would double the download size to 20+MB and because Qt 5's license isn't suitable for my needs.)

I really hope that rust gets good GUI bindings (or better still its own native GUI toolkit). But clearly it isn't easy or quick to do.

4 Likes

I can also elaborate my experience with various GUIs and languages that is collected over number of years on Linux, Windows and OSX (I use them all with various degree of involvement). I have recently gone away of OSX because I do not consider them fair option any more (OSXs post 2010 and OSXs before 2010 are two different animals to me).

If I do fail in the pit of waging different option I may get into long elaboration of likes and dislikes, pros and cons (of which some are very subtle). But there are some general trends of GUIs that are IMHO crucial when pondering which kind of GUI to use (or create).

I have learned over time that GUI for desktop and GUI for mobile are to be considered differently much because of underlying abilities of OS on top of which GUI sits on. Major desktop OS are fully multitasking and context preserving while mobile platform can even be quasi multi-tasked or not context preserving after application switching (hence I find mobile OSes largely crippled - we are see what Ubuntu Touch will say to that).

Yet, major desktop OSes have no single GUI that I know of, that is not single process. You are to fail into event loop and anything that needs to work in concurrent fashion is pain to implement because you are in the event loop and have no control over the process or your program. With native threading both Go and Rust can redefine the way how GUI works or how event loop works. If we talk about web based tech from another side (apps in browser or apps that use browser - e.g. electron) we also have issue of JavaScript being single threaded (non blocking, async - yes, but essentially single threaded - otherwise whole web will go nuts with crazy bugs). Web apps (server side) as much as they can rent multitasking from OS fail into similar pattern, you are to fail not in event loop but in router loop, and story repeats. We seem to be bound by single threaded understanding of systems while we have fantastic new multi-threaded languages. We are not using them properly.

So if we are to write new GUI that is not single-threaded we have to redefine playing field. How many people are ready to change their mind?

3 Likes

I would not be surprised if a React like UI framework would appear for Rust. Probably not exactly like React, because Rust and JavaScript are too different in some places, but with a similar philosophy. It doesn't really need inheritance, because it's more composition based, and state handling is done in a way that goes well with immutability. Well enough for many projects to enforce immutability with libraries, in fact.

I played around with a proof of concept for a web frontend framework that uses the same kind of event -> update -> render pipeline some time ago and it feels like it could be something to look closer at. Sure, it would have to fit into the "native"/OS event loops and such, but I think it's an interesting concept that I would like to play around with again some day.

3 Likes

Anyone try out libui?

It looks like there are Rust bindings:

You don't need OOP inheritance at all for GUIs, that's just one paradigm of many.
E.g. PureScript has no inheritance either (its type system is like Haskell's) but it's very nice for writing GUIs in it, e.g. with the Halogen framework.
E.g. here is a Todo-List component example in PureScript.
https://github.com/Boscop/web-view/blob/master/examples/todo-ps/src/Component/Todo.purs#L43
This is the example that is shown on the screenshot in the Readme.

The Yew framework has a similar architecture as Halogen.
A similar architecture could be used for non-web GUIs in Rust, too.

The lack of OOP inheritance is not holding Rust back in the GUI area.

It's just that writing a cross-platform GUI lib (like Qt) that can compete with an embedded browser (for making pretty production-grade UIs) takes a lot of work and would require users to re-learn a lot of things just to be able to make those competitive UIs, that they wouldn't have to learn when embedding a browser.

Servo will probably become properly embeddable before we have a native cross-platform GUI lib in Rust, but not because of the lack of OOP inheritance.

OOP inheritance is a bad can of worms that infects everything, the lack of it is a good thing.

6 Likes

Alright please excuse the self-promotion, but I've been working on azul for a while now. It was supposed to be the successor to limn - I talked to the author of limn and limn simply has the problem of verbosity - while it's possible to develop GUIs in it, it's buggy as hell and not really easy or straightforward to do. limn has serious state management problems.

For some reason, people thought that azul was already finished, hence the big warning in the header. But for anyone needing ideas on how to practically implement a GUI toolkit without inheritance in a MVVM style, read through the README.

Servo won't become embeddable, that's something I can say with confidence. I tried. Servo is even more bloated than electron, the JS parts are heavily tied in with the rest. A servo app takes 70MB of disk space (stripped) and 300MB RAM - which is fine for a browser, but not for a desktop app. azul, which just uses webrender (the rendering engine from servo), uses only 5MB binary size and 39MB RAM - quite a difference. azul has its own CSS engine, because crates like html5ever and stylo are heavily tied to the Firefox architecture, which is simply way too complex and doesn't fit my design goals.

There are things that aren't finished yet, notably the layout and compositing system. I use this at work to create a desktop application, so.. yeah, I'll just continue developing it and tell people when I'm done with a 0.1 release. But I haven't hit large roadblocks yet... I just need time.

I already have a half-working GUI system in my production app, however that app is proprietary - I'm trying to "outsource" as many components to azul as I can, in order to keep the app lightweight (currently 10k lines and that's already too much for me). The more I can put in azul and forget about, the better. In order to use it at work however, at least the layout system + the SVG system should work, so that's what I'll mostly focusing on. I'll probably finish a 0.1 release this summer.

Sorry if this is against the rules, but I just saw this thread pop up and wanted to tell people - things are in progress.

21 Likes

This looks really promising and it definitely in-line with what I imagined I would like to build for a GUI library.

Have you thought about taking some time to create issues with tags like, "Intro, Easy, Hard, Advanced" and "Luxury, Mandatory, Critical, etc" (or something like that) to assist those who would like to help out with your project to start by contributing to your project in the most useful way that they can?

4 Likes

@mark you should perhaps look again at the win32 interface. It's actually not that complicated as it's pure-C all the way, and the state is stored in the widgets, so it works well with immutability (it uses message passing to change the state of widgets). The first few widgets take a while to get your head around, but after that it's pretty rote.

You end up with a very small binary that's as efficient as possible; and for some reason, win32 is a multithreaded GUI so you can utilise more than one core.

2 Likes

Cool, I already had the repo starred but I took a second look. Really awesome work so far! It's exactly the kind of thing I've been looking for. Definitely want to give it a try.

Seems like a lot of stuff is gonna get cooler once async stabilizes in Rust :wink:

I've noticed the biggest problem with GUI libs (and rust libs in general) is keeping them active. Do you have any plan to accept contributors/start a patreon/etc?

1 Like