Skip to content

Rust 2021 GUI blog post#32

Merged
raphlinus merged 3 commits into
masterfrom
rust-2021
Sep 29, 2020
Merged

Rust 2021 GUI blog post#32
raphlinus merged 3 commits into
masterfrom
rust-2021

Conversation

@raphlinus
Copy link
Copy Markdown
Owner

No description provided.

Copy link
Copy Markdown

@CreepySkeleton CreepySkeleton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they most often consist of a statement more of wishes than actual requirements

That reads weird.

Copy link
Copy Markdown
Contributor

@hecrj hecrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really enjoyed the article overall!

I am not sure how to directly improve it, but I left some of my thoughts here and there.

Comment thread _posts/2020-09-22-rust-2021.md Outdated

We are developing the font editor [Runebender] as the primary motivating application, but, while a lot of pieces are in place, it is sadly not yet usable for day to day font creation work. One of my goals for the rest of the year is to start creating a font in it.

That said, I am very proud of the work that's been done in the last year. To hit on some of the highlights, we're just landing basic but capable [rich text layout]. The keyboard event is close to browser quality (based on [keyboard-types]). There is incremental painting based on damage regions. Multi-window support is solid, with support for controlling window placement and dynamic hi-dpi. There is tab-focusing between text boxes. All of these are hard problems. Even more so, I am pleased that a lot of the work came from the community.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's indeed very impressive! 🎉

iced is missing all of these features. Looks like I have some reading to do!

Comment thread _posts/2020-09-22-rust-2021.md Outdated

That's about where we are today with GUI toolkits. In many ways, I think converging on a single vision in GUI is a harder problem than for async. For one, people have different things they want to do. I'm personally most interested in things that resemble document editors. Others want 3D or video content. In the future, there might be commercial interest in enterprise line-of-business apps or interfaces for medical devices. These all have quite different requirements in the best ways to express UI logic, and how to build them. Not to mention the endless opportunities to bikeshed.

I am not (yet) proposing Druid as the singular vision that the Rust community should converge on. I'm enjoying reading codebases and learning from other Rust GUI projects. In particular, I'm finding lots to like about [Iced]: it has good solutions to async, 3D graphics (through wgpu), being able to function in a guest window (important for VST plug-ins), among other problems. And I'm getting the sense that it's easier for developers. The Elm-like reactive architecture maps nicely to Rust, and it's not hard to figure out how to express your app-specific logic. By contrast, Druid's reactive model, while efficient and powerful in many ways, has complex concepts such as Haskell-like lenses, and places a burden on the developer to carefully design the "app data" to fit the Druid model. We are actively exploring ways to make that simpler, and are thankful to Iced (and other toolkits) for being a model.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really grateful for the kind words here! Very glad you like it 😄

And I'm getting the sense that it's easier for developers. The Elm-like reactive architecture maps nicely to Rust, and it's not hard to figure out how to express your app-specific logic.

I agree that the Elm architecture fits Rust nicely and works very well to model GUIs once you get used to it. That said, it does generate some friction for new users, especially if they are used to other object-oriented, callback-based toolkits.

I frequently get asked questions about how to organize code in reusable "components" or how to deal with deeply nested data structures. These are also very common questions in the Elm community. However, I am not sure how much of this is due to the architecture rather than the language (Rust itself) not being object-oriented.


Imagine a thought experiment for a bit. Obviously Rust is promising for implementing async, but there isn't a consensus on the best way to do it. Some people feel it should be done with callbacks, and invest considerable effort into overcoming the serious problems with that approach. Others feel it should be done with a polling future trait, but there are multiple versions of that trait: some get the context from thread local storage, others pass it into the poll method. And of course some people feel the syntax should be `future.await` while others insist on `await!(future)`. Every couple of months somebody pops up on /r/rust with a new crate that promises to solve "the async problem," complete with a nice-looking echo server demo.

That's about where we are today with GUI toolkits. In many ways, I think converging on a single vision in GUI is a harder problem than for async. For one, people have different things they want to do. I'm personally most interested in things that resemble document editors. Others want 3D or video content. In the future, there might be commercial interest in enterprise line-of-business apps or interfaces for medical devices. These all have quite different requirements in the best ways to express UI logic, and how to build them. Not to mention the endless opportunities to bikeshed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think converging on a single vision is necessary or inevitable in the long run?

I believe having a bunch of different approaches to GUI could be a good thing. Users can choose the approach they resonate the most with and build communities around them. This makes each community stronger and more cohesive.

As you pointed out, building a GUI toolkit is an insane amount of work, so it's probably not realistic to expect a lot of serious solutions to exist in the Rust ecosystem in the long run. However, I am not sure we need to actively focus on converging a vision.


## Learning and community

Many Rust projects these days come with what's basically a marketing pitch: "adopt this codebase, it's awesome." I am starting to see the Druid project in a somewhat different light. I consider its primary mission to be *teaching and learning* the knowledge required to build GUI. To that extent, the community we're building, hosted on [our Zulip instance,][the xi Zulip] is just as important as the code.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great mission! I personally need to learn a lot, so I should try to participate actively in the Zulip instance.

When I started working on piet-window, I was planning to start a conversation about finding ways to cooperate, but I eventually got dragged into other things... I promise to start that conversation during the next few days.


First, I'd love for wgpu to become more mature, as I think it is the most promising approach to GPU for the future. Our [roadmap for 3D] basically depends on it. Much love to that community for the progress they've made so far and hope for the future.

Second, while we generally find Windows platform bindings to be straightforward, thanks to the excellent winapi bindings (and hopefully a stable [com-rs] shortly), the situation on macOS is not as good. There are real problems interoperating with Objective-C code, including type-safety in wrappers that also allow subclassing, and continual friction around autorelease pools. There are also different, incompatible conventions around wrapping foreign types (foreign_object vs TCFType). None of this is blocking, but it makes developing macOS platform integration less fun. (See [this HN thread](https://news.ycombinator.com/item?id=24309565) for a bit more background)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Dealing with macOS bindings has been quite a painful experience for me too when working on winit.

This situation is also one of the main reasons I stopped working on piet-window.


Second, while we generally find Windows platform bindings to be straightforward, thanks to the excellent winapi bindings (and hopefully a stable [com-rs] shortly), the situation on macOS is not as good. There are real problems interoperating with Objective-C code, including type-safety in wrappers that also allow subclassing, and continual friction around autorelease pools. There are also different, incompatible conventions around wrapping foreign types (foreign_object vs TCFType). None of this is blocking, but it makes developing macOS platform integration less fun. (See [this HN thread](https://news.ycombinator.com/item?id=24309565) for a bit more background)

Third, some perhaps surprisingly good news. I prefer Rust crates when possible rather than relying on C++, but for OpenType font shaping, we would have to call into HarfBuzz. Now not one but two Rust solutions are on the horizon: [Allsorts] from YesLogic, and [rustybuzz] from RazrFalcon. Both are young, but I can see adopting them (primarily for use on Linux, which is still work in progress; on Windows and macOS we use the platform text layout capabilities). I know of no other language besides C++ that has working OpenType font shaping. Almost every language community has its own language-native GUI toolkit project, and most fall short. I do believe that Rust will be different, and seeing projects like this is to me evidence why.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also agree! Rather than converging on a single vision, I believe building great crates that tackle direct use cases of a GUI toolkit should be one of our main focuses.

For instance, I took a lot of inspiration from druid when I rewrote the layout engine in iced. If we converged our visions here, we could maybe end up with a nice crate that could benefit other parts of the ecosystem. For example, Bevy is working on their UI implementation and they may consider adopting a similar layout engine.

I think there is a lot of space for great crates here: layout, text caching, accessibility, windowing, etc. Collaboration is hard, however!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also agree. I've been focused on other areas so we haven't moved forward much in the UI department yet, but I would love to collaborate on as many areas as we can here. I'm not a UI toolkit development expert (nor do I have the bandwidth to be), so it makes way more sense to me to lend my project's development energy to ecosystem crates with a lot of brainpower and experience behind them. Ideally these crates would be modular in a way that lets us bring our own windowing and renderering.

As a small tanget, I really want to discover good ways to do reactive UI in Bevy ECS, but its possible that every solution we come up with is significantly more cumbersome than just fully adopting a druid/crochet/iced/elm-like dataflow. If that ends up being the case, it would be great to be able to just pull in the relevant ecosystem crates instead of re-inventing the wheel.

Responding to review comments, and more thoughts.

WIP
Incorporates feedback from @hecrj among others.
@raphlinus raphlinus merged commit 96e14e8 into master Sep 29, 2020
@raphlinus raphlinus deleted the rust-2021 branch September 29, 2020 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants