chore(wip): experiment with the `floem` GUI library
It is not using the same fonts and the sizes are all hardcoded with overall, looks pretty decent and maintainable IMO.
There is also an example on how to do themes: https://github.com/lapce/floem/blob/main/examples/themes/src/main.rs
### Tasks
- [ ] How will the system tray menu work?
- [ ] exe name would have to match for auto-start
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| firezone | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Sep 4, 2024 7:19pm |
Looks nice. I'd have to know how weird the buttons and callbacks and stuff are before committing to it
Looks nice. I'd have to know how weird the buttons and callbacks and stuff are before committing to it
Have you ever worked with React? It is basically the same model, based on reactivity. You create "signals" that store data and have a read and a write path. By accessing a signal within a certain view tree, that part of the view tree knows it needs to re-render when the data changes. When you change it via the write-path of the signal, things automatically re-render.
Button clicks, checkboxes etc are just Rust-callbacks and you can do whatever you want in them. They are sync and run on the GUI thread though AFAIK but there are interesting adapters like https://lapce.dev/floem/src/floem/ext_event.rs.html#158-196 which allow you to directly link a channel to the GUI and update it every time a new item is sent into a channel.
Oh look at that, Floem exe built in Ubuntu 20.04 running correctly in 24.04
For the bundling to work I may have to override some stuff in Tauri so it knows it no longer needs WebView. Worst case we can do that in the step where we rip up and rebuild the deb.
I pushed a few changes so the Windows MSI will bundle this exe (for production we would ofc replace the Tauri exe but I wanted to have both) and no longer installs the WebView runtime, since Floem doesn't need it
There is also an example on how to do themes: https://github.com/lapce/floem/blob/main/examples/themes/src/main.rs
A thread in the Lapce Discord on how to do tailwind-like styling: https://discord.com/channels/946858761413328946/1275221407470583891
Sharing Floem's internal event loop would be really nice, if it uses GTK+ underneath. tray-icon says it needs that, so that's why I'm using tao, so it's kinda like we sliced off the top half of Tauri (No WebView, no JS, no Tauri) and kept the bottom half (Tao and GTK+) but in a separate thread.
Just got it to run in Windows using that same worker thread pattern
Having to fork the framework sounds like effort.... should we check Iced and others again? I don't recall the results from when I last tried it.
Either way this might be a thing where in one branch I move the Tauri stuff into a central location and abstract it, and in another I try to get another framework working, and then they meet in the middle.
Having to fork the framework sounds like effort.
Well, only to contribute a change back to expose the event loop is what I meant :)
I've found the floem people to be really approachable on Discord. I'll ask them what they think about tray-icons.
If the separate thread works for now, great! I am surprised it does as I thought that GUIs typically fight over who is the GUI thread. But I guess tray-icon and GUI are different enough?
I'm a little surprised too. I think non-main threads are poorly supported, but they happen to work on both Linux and Windows.
I'm using this with_any_thread method which Tao has: https://docs.rs/tao/latest/tao/platform/unix/trait.EventLoopBuilderExtUnix.html#tymethod.with_any_thread
So if we needed a non-Floem non-Tauri window for some odd purpose we could get a Tao window. Drawing in it would be painful.
Other than the tray-menu, are there any other things we need to confirm? We have a file-picker dialog right? That would be another thing to ensure we can get working well before we go full-steam ahead with this. Also, full-disclosure: I didn't do a super deep investigation in all the other GUI approaches. I just found floem to be the most appealing with a "I am gonna spend 15 minutes to try and make something work"-approach:
- Xilem doesn't have any good styling (yet)
- GPUI is way too low-level for us
- I didn't take a deep look into iced but its default design seems kinda ugly
- I really like
floem's cascading styles and similarity to CSS in general. The web community has spent a lot of time on making styling ergonomic and scalable so leaning into that makes a lot of sense IMO.
Modularising the rest of the codebase to make this particular bit easier probably wouldn't hurt much.
Are there any complex GUI elements that we need to draw?
Nothing more complicated than the text boxes in Settings, I think. Yeah there is a native file dialog crate we have. I'll double-check that in the Floem prototype.
I think Iced is pretty popular among Rust devs and Flutter is pretty popular among mobile devs so I'd like to put 15-30 minutes into those.
I've had so much trouble with web stuff over the years, I like Flutter because their layout system is easy to explain and easy to implement. The only big downside is having to write Dart, but maybe it will be like Swift / Kotlin / TS where just learning a little is enough.
(I think Flutter also has a bigger runtime, so it would be nice if Floem or Iced works out)
Bencher
| Report | Wed, September 4, 2024 at 19:25:59 UTC |
| Project | Firezone |
| Branch | feat/floem-gui |
| Testbed | github-actions |
🚨 1 ALERT: Threshold Boundary Limit exceeded!
| Benchmark | Measure (units) | View | Value | Lower Boundary | Upper Boundary |
|---|---|---|---|---|---|
| relayed-tcp-client2server | Throughput (bits/s) | 🚨 (view plot | view alert) | 237,827,714.63 (-4.76%) | 240,202,743.43 (101.00%) |
Click to view all benchmark results
| Benchmark | Throughput | Throughput Results bits/s | (Δ%) | Throughput Lower Boundary bits/s | (%) |
|---|---|---|---|
| direct-tcp-client2server | ✅ (view plot) | 256,020,468.28 (+3.82%) | 238,081,089.97 (92.99%) |
| direct-tcp-server2client | ✅ (view plot) | 254,675,120.00 (+1.34%) | 243,493,685.61 (95.61%) |
| direct-udp-client2server | ✅ (view plot) | 297,626,223.65 (+2.53%) | 271,109,253.23 (91.09%) |
| direct-udp-server2client | ✅ (view plot) | 412,479,075.06 (+2.67%) | 388,388,333.50 (94.16%) |
| relayed-tcp-client2server | 🚨 (view plot | view alert) | 237,827,714.63 (-4.76%) | 240,202,743.43 (101.00%) |
| relayed-tcp-server2client | ✅ (view plot) | 264,111,837.64 (+1.74%) | 249,874,036.61 (94.61%) |
| relayed-udp-client2server | ✅ (view plot) | 224,397,758.18 (-3.27%) | 220,641,783.51 (98.33%) |
| relayed-udp-server2client | ✅ (view plot) | 334,803,116.62 (-0.81%) | 316,688,048.00 (94.59%) |
Bencher - Continuous Benchmarking
View Public Perf Page
Docs | Repo | Chat | Help
Closing as stale. It still needs to be written up in https://github.com/firezone/firezone/issues/6550 but we've decided to go with iced for now.