Question: Is there anyway to use Servo as a Rust GUI library?
Pre-emptive comments:
1. Why would you want to do that?
A: Of all the GUI libraries out there, I dislike HTML/DOM least.
2. Why not just use rust/wasm32, stdweb, yew?
A: I like debugging Rust more than I like debugging rust/wasm32.
3. Why Servo ?
A: It basically has all the GUI components I could ever want. If only there was a way to use it as a GUI library.
In other words, you are searching for an electron that uses servo as display engine rather than whatever chrome and safari are using?
I can tell you that there are frameworks that want to make working with electron easier, but all of them require you to compile at least parts of your code to wasm.
Then they connect via abstracted IPC to a server process running in ânativeâ rust binary.
Iâm not aware of something similar that uses servo, but even if there were, Iâm pretty sure it would rely on wasm as well.
It seems with an Electron based approach, one ends up either:
- writing lots of rust/wasm32 OR
- building something similar to http://hackage.haskell.org/package/threepenny-gui where the logic is in server-side-rust, and the âguiâ is a very thin rust/wasm32/dom layer which does communication over websockets
Why do you believe that using servo would rely on wasm? Servo itself is able to display DOM elements, despite being only in rust. It seems like there should be some layer there that we can hijack and use.
Servo is a rendering engine for HTML and not a GUI Toolkit like GTK or wx. I have not looked at its exposed interface and if it provides necessary types, functions etc to directly inject gui elements and listen for their events.
But taking the idea of electron and porting it to servo seems to be the most obvious thing.
Have a look at âAzulâ it is specifically working on this idea. Now, it doesnât bring in the whole âServoâ but rather uses the âWebrenderâ part of servo as a lightweight library to create a GUI framework. Personally, I think this is the best idea Iâve seen for a Rust GUI library that can gain real traction.
@gbutler69 : Azul looks amazing. Is there by chance a way to toggle the Azul output, i.e.
one code base
mode 1 = outputs desktop app, panics = stack traces, debug as desktop app
mode 2 = uses wasm32-unknown-*, and outputs a wasm32 that I can run in the browser?
This would be amazing.
Not that Iâm aware of, but, it doesnât seem like something that couldnât fit with its overall design. I do know that the developer of Azul (last I heard) is not accepting PRâs as he wants to get something âworkingâ before he opens it up to a lot of discussion. He has a particular vision himself and wants to see his vision through to a 1.0 release before trying to incorporate othersâ visions (which I find a reasonable position). That being said, it couldnât hurt to open and issue or start a discussion with him, or, alternatively, fork it and try building a fork with your own ideas.
Electron apps can link to native libraries, so you can also use neon (and neon-serde) rather than wasm or websockets. See https://keminglabs.com/blog/building-a-fast-electron-app-with-rust/
The point is that with Electron, short of something like ThreePenny, the code that manipulates the DOM has to be in JS.
Which means Rust -> wasm32.
Are you telling me that in Rust/Electron, it is possible to directly manipulate the DOM in Rust, without going through JS?
No, azul doesnât support WASM, at least right now - while you can theoretically re-route the OpenGL to WebGL, this is really not a practical solution as custom rendering generally will result in a worse performing application (azul is essentially a mini-browser engine, youâd be running a browser in a browser, which wonât be performant). You can however, re-use CSS stylesheets on the web (with some minor adjustments, the layout works the same - absolute / relative layout, padding / margin, flexbox, styling, etc.). In a distant future, there might be a azul-to-DOM compiler and a XML-ish loader (see this discussion). While it would be technically possible to compile Azuls DOM model to HTML, itâs not really practical right now.
Once WASM has DOM access and is better supported (i.e. something like <script type="wasm">
- getting WASM to run is currently a pain), it would be feasible to re-use azuls DOM renderer + the business logic in Rust to the web, however, this needs some serious re-architecting and is not a 0.1 goal.
However, webview-rs might fit your description (very similar to threepenny) - essentially business logic in Rust and UI in HTML (communicating between Rust and JS via a JSON rpc). This would be portable to WASM with a bit of effort.
About the PRs: Sure, I do accept PRs and bug fixes, but yeah I do have a plan / architecture in mind. Feel free to open issues about things, thatâs what theyâre there for.
Yep. It doesnât have any friendly wrappers like stdweb, but itâs definitely possible. I made you an example repo - https://github.com/jamii/neon-dom
The only tricky part is that you canât store js values on the rust side between neon calls, so you need a couple of lines of javascript to call require
and pass all the necessary modules into rust and then you can do the rest directly in rust.
@jamii : Thanks for taking the time to put this together. I canât believe it works.
The only ugliness is the untyped Rust/JS interaction of things like:
let create_text_node = document
.get(&mut cx, "createTextNode")
.unwrap()
.downcast::<JsFunction>()
.unwrap();
let click_me_string = cx.string("click me");
let button_text = create_text_node
.call(&mut cx, document, vec![click_me_string])
.unwrap();
let append_child = button
.get(&mut cx, "appendChild")
.unwrap()
.downcast::<JsFunction>()
.unwrap();
append_child
.call(&mut cx, button, vec![button_text])
.unwrap();
Howrver, there only seems to a be a finite # of such calls we need to make, so if we had a library to wrap this, this would be a really cool gui library.
Itâs pretty mechanical, so I think you could make a macro like let button_text = js!(cx, document.createTextNode("click me"))?;
that would handle all the casting and error conversion.
so to clarify , in the future there could be a mode where azul is used like a virtual dom to interface with the browserâs ; the xml loader is an unrelated effort and wont be needed it or be part of the infraestructure requiered for a hypothetical web browser version
Yes, thatâs the idea. Azul has (internally) DOM diffing (not finished yet, though), so that could run as WASM (and then instead of rendering the DOM to the screen, it renders the DOM to the webpage).
i have been reading the docs to see if there are any glaring difference between standard css and azulâs that would cause the latter to be difficult to run on a web browser . I havenât been able to find any , which makes me question why the toolkit is implementing its own engine instead of using stylo
Stylo is heavily dependent upon the JS execution model, which, in a compiled desktop app that doesnât have JS, doesnât make much sense. There is no concept of âimmutable CSSâ for example, because on the web, JS can change every CSS property.
Second, cascading CSS is very easy, itâs just one function (which can be easily parallelized if needed, but right now cascading isnât a bottleneck).
Third, while there are no differences between azul-css and stylo, there are differences in the type of things that azul supports. Azul does not have any concepts of âbuttonsâ or âinput fieldsâ as a browser does, for example. So there is little need for [attribute = "x"]
selectors, because azul doesnât have attributes.
Fourth, stylo handles errors very differently - azul just fails to parse the CSS while stylo gracefully fails. Which means that azul-css will be valid CSS, but not necessarily the other way around. Plus, CSS cascading and selection is probably the easiest part, the hardest part is state management and rendering, not CSS parsing.
And last, but not least, stylo has hundreds upon hundreds of dependencies that slow down compile and link time (azul already has 145 dependencies minimum, and it used to have more than 280, Iâve already cut everything down as much as possible). I donât want to go back to 10-minute compile times and minute-long debug build times, I really donât.
So yeah⌠stylo does not really offer any advantages, imports hundreds of extra dependencies and is generally not that useful outside of Firefox.
Azul looks really interesting, but I have a hard time knowing what state itâs in. The features described sound great, but theyâre all covered by a giant boldface caveat that suggests none of it necessarily works. An aspirational list is fine, but some clarity on what does work would really help decide whether itâs time to dive in.
I check back in every so often to see if the caveat has gone or been updated. However, this time I checked in and thereâs more detail in an issue, which has been left open specifically for visibility and noted as a FAQ.
Since Iâm clearly not the only one, I thought Iâd highlight it here too.
No, azul doesnât support WASM, at least right now - while you can theoretically re-route the OpenGL to WebGL, this is really not a practical solution as custom rendering generally will result in a worse performing application (azul is essentially a mini-browser engine, youâd be running a browser in a browser, which wonât be performant).
I donât think that it matters that Azul would be less performant on WASM than native. If there is one code base, then users can op-in to the native experience by getting the app. However, having most (or just some) of the app on the web still be completely functional is still very beneficial.