Open prabirshrestha opened 4 years ago
I've had no luck with nested widgets either. Adding a blank MainScreen and then embedding the Buffer as a child will work, but drastically slow down rendering with visible flashes as mouse events propagate. If I switch it back to being the root, it works fine. I guess it somehow forces the UI to continually redraw even though there was no change.
I also tried to add a 100% width, height 1 status line, together with a 100%/100% buffer but it messes up the rendering, the buffer becomes 1 char wide and continually flashes. I saw there was a child direction field there (and also valign) but neither seemed to work for me.
(I think the layout system could potentially be more flexible if we embedded https://github.com/vislyhq/stretch which is built on top of cassowary, instead of cassowary directly)
@archseer thanks for looking at this!
I took your example and used it to debug things and found a couple of issues:
I've tweaked your example and added it to the repo; don't forget to run it in release mode!:
cd termwiz
cargo run --example widgets_nested --features widgets --release
there was some missing optimization for nested widgets that meant that the whole screen would be re-rendered on each pass; I've added a surface to absorb those changes and then compute a diff to improve the render performance.
Makes sense, I thought it had to be something like that. Thanks for the fix!
Also, I noticed that the layout gets recalculated on every render_to_screen
call:
https://github.com/wez/wezterm/blob/81683bd898f5059ff453f52c4a7be3a88deeb7b2/termwiz/src/widgets/mod.rs#L456-L457
Since this is already handled by the resize event handler, I think you should be able to remove that call as well, as long as it's called once on init (I noticed the surfaces default to (1, 1)
).
The recompute on render is deliberate: the rationale is that a widget's size may have changed to fit text that got updated. It may be possible to make that more optimal though!
Cool, I played around with it a bit today and it's quite neat! I had some more thoughts about nested widgets, for implementing something like a popup it would be useful to:
Segfault on resize if the terminal is resized to a smaller area:
thread 'main' panicked at 'assertion failed: x + width <= self.width', ~/.local/share/cargo/git/checkouts/wezterm-6425bab852909cc8/58686f9/termwiz/src/surface/mod.rs:731:9
Seems to happen on a single widget too.
(I hope you don't mind me reusing this same issue, I figured might as well put all nested widget issues here as I find them)
Removing widgets: I think there's no bindings for that at the moment. There's only add
which is proxied by add_child
/add_root
.
In the meantime I sent a PR for tui-rs https://github.com/fdehau/tui-rs/pull/300 to support wezterm backend. But not working as expected on windows.
Here is sort of an example I was thinking off. When would one add or remove the widget.