Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
lib: Add local workaround for termion cursor bug
Erik Kundt committed 2 years ago
commit a6cc1643761f83db0af7e559d44ae1133c9fa48c
parent c8e4c752f1c0ee319d47aaa8aee05e761123ce28
2 files changed +81 -1
modified src/flux/terminal.rs
@@ -12,6 +12,85 @@ use super::event::Event;

type Backend = TermionBackendExt<RawTerminal<io::Stdout>>;

+
/// FIXME Remove workaround after a new `ratatui` version with
+
/// https://github.com/ratatui-org/ratatui/pull/981/ included was released.
+
pub struct TermionBackendExt<W>
+
where
+
    W: Write,
+
{
+
    cursor: Option<(u16, u16)>,
+
    inner: TermionBackend<W>,
+
}
+

+
impl<W> TermionBackendExt<W>
+
where
+
    W: Write,
+
{
+
    pub fn new(writer: W) -> Self {
+
        Self {
+
            cursor: None,
+
            inner: TermionBackend::new(writer),
+
        }
+
    }
+
}
+

+
impl<W: Write> ratatui::backend::Backend for TermionBackendExt<W> {
+
    fn draw<'a, I>(&mut self, content: I) -> io::Result<()>
+
    where
+
        I: Iterator<Item = (u16, u16, &'a buffer::Cell)>,
+
    {
+
        self.inner.draw(content)
+
    }
+

+
    fn append_lines(&mut self, n: u16) -> io::Result<()> {
+
        self.inner.append_lines(n)
+
    }
+

+
    fn hide_cursor(&mut self) -> io::Result<()> {
+
        self.inner.hide_cursor()
+
    }
+

+
    fn show_cursor(&mut self) -> io::Result<()> {
+
        self.inner.show_cursor()
+
    }
+

+
    fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
+
        match self.inner.get_cursor() {
+
            Ok((x, y)) => {
+
                let cursor = (x.saturating_sub(1), y.saturating_sub(1));
+
                self.cursor = Some(cursor);
+
                Ok(cursor)
+
            }
+
            Err(_) => Ok(self.cursor.unwrap_or((0, 0))),
+
        }
+
    }
+

+
    fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
+
        self.cursor = Some((x, y));
+
        self.inner.set_cursor(x, y)
+
    }
+

+
    fn clear(&mut self) -> io::Result<()> {
+
        self.inner.clear()
+
    }
+

+
    fn clear_region(&mut self, clear_type: backend::ClearType) -> io::Result<()> {
+
        self.inner.clear_region(clear_type)
+
    }
+

+
    fn size(&self) -> io::Result<Rect> {
+
        self.inner.size()
+
    }
+

+
    fn window_size(&mut self) -> io::Result<backend::WindowSize> {
+
        self.inner.window_size()
+
    }
+

+
    fn flush(&mut self) -> io::Result<()> {
+
        ratatui::backend::Backend::flush(&mut self.inner)
+
    }
+
}
+

pub fn setup(height: usize) -> anyhow::Result<Terminal<Backend>> {
    let stdout = io::stdout().into_raw_mode()?;
    let options = TerminalOptions {
modified src/flux/ui.rs
@@ -19,9 +19,10 @@ use super::event::Event;
use super::store::State;
use super::task::Interrupted;
use super::terminal;
+
use super::terminal::TermionBackendExt;
use super::ui::widget::{Render, Widget};

-
type Backend = TermionBackend<RawTerminal<io::Stdout>>;
+
type Backend = TermionBackendExt<RawTerminal<io::Stdout>>;

const RENDERING_TICK_RATE: Duration = Duration::from_millis(250);
const INLINE_HEIGHT: usize = 20;