How to clear screen in terminal in tui and remove previous draw results (still see on scroll top)?

I want to draw some layout using tui-rs and when I do terminal.clear() I see that I still can scroll and see previous render results. This is my code:

pub struct UI;

impl UI {
    pub fn render(mut options: UIOptions) {
        enable_raw_mode().unwrap();

        let backend = CrosstermBackend::new(std::io::stdout());
        let mut terminal = Terminal::new(backend).unwrap();

        terminal.clear().unwrap();
        terminal.hide_cursor().unwrap();

        terminal.draw(|frame| {
            let chunks = Layout::default()
                .direction(Direction::Horizontal)
                .margin(1)
                .constraints(
                    [
                        Constraint::Percentage(25),
                        Constraint::Percentage(75),
                    ].as_ref()
                )
                .split(frame.size());

            DebugPanel::render(frame, chunks[0], options.borrow_mut());

        }).unwrap();
    }
}

async fn handle_ui(&mut self) -> JoinHandle<()> {
	let buffer_redirect = Arc::clone(&self.buffer_redirect);

	tokio::spawn(async move {
		loop {
			let mut buffer_redirect = buffer_redirect.lock().await;
			let mut buffer_output = String::new();

			(&mut *buffer_redirect)
				.as_mut()
				.unwrap()
				.read_to_string(&mut buffer_output)
				.unwrap();

			// drop stdout redirect to allow UI rendering
			*buffer_redirect = None;

			UI::render(UIOptions {
				buffer_output,
			});

			// turn on stdout redirect
			*buffer_redirect = Some(BufferRedirect::stdout().unwrap());

			sleep(Duration::from_millis(REDRAW_TIMEOUT)).await;
		}
	})
}

Could somebody explain how to clear terminal to avoid scrollbar appearing ? There a lot of terminal apps (like htop in linux etc) that seems to be separate terminal app which redraw without scrollbar appearing, so I cannot scroll to top and see what was rendered previously.

UPDATED: just to rephrase: expected result that app should full redraw window, actual result that rendered layout just added on next line and just scrolled to it.

termion has a module to deal with alternate screen buffers, which most terminals support these days. I believe, htop uses something like this.
You an look at the source code from the docs link if you want to manually put in the escape sequences.

Edit: Maybe try the termion backend instead of the crossterm backend.

2 Likes

Thank you, didn't know about this feature. Seems like crossterm also support it. However, it do not work for me (I run this in git bash, windows).

I tried to use flow same as described in tui docs.

Can you try a different terminal emulator? Like Alacritty or Windows Terminal (not cmd or ps, this is a separate application which you need to install).
The terminal emulator used by Git Bash, at least when I last used it, was woefully outdated.

I think app should work the same way everywhere (at least it's what I want to achieve). Need another way.

just tried to test https://github.com/ilaborie/plop-tui and seems like this project draw correctly, need to investigate what's wrong with my app

So, I found what the reason: BufferRedirect from gag-rs. Since TUI rendered using stdout it was an issue. So, I refactored my app to use mspc channel instead of println! and not use gag. Now TUI rendered as expected.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.