Skip to main content

UncursesBackend

Struct UncursesBackend 

Source
pub struct UncursesBackend<I: Input, O: Write> { /* private fields */ }
Expand description

Backend implementation that drives rendering, input, and lifecycle through one Screen.

§What it wraps

The wrapped screen owns the terminal handle, the cell buffer, and the event source. Keeping those pieces behind one backend means frame rendering, cursor movement, clearing, size tracking, raw-mode setup, and input reads all observe the same terminal state.

§Rendering

[Backend::draw] converts each concrete buffer cell to an uncurses cell and writes it into the screen’s buffer, staging the frame without any I/O. [Backend::flush] then calls Screen::render, which diffs the buffer, stages the minimal escape bytes, and flushes them through the screen.

┌─────────────────────┐
│ Frame buffer        │
└─────────┬───────────┘
          │ buffer cells
          ▼
┌─────────────────────┐
│ UncursesBackend     │
│ draw + conversion   │
└─────────┬───────────┘
          │ Screen::set_cell
          ▼
┌─────────────────────┐
│ Screen (diff render) │
│ diff against output │
└─────────┬───────────┘
          │ flush → Screen::render
          ▼
      terminal

§Viewports

The default viewport is [Viewport::Fullscreen]. The init helpers call set_viewport with the viewport stored in terminal options. Inline viewports keep an absolute origin in inline_origin; drawing subtracts that origin so the screen buffer contains only the inline region.

§Events

Use poll_event, try_read_event, and read_event for synchronous loops, or event_stream with the async feature. Every read is pure, exactly like Screen’s: call observe_event on each event to keep capability tracking alive, or skip it and reads still work.

§Setup

Construction is inert: it does not enter raw mode, enter the alternate screen, hide the cursor, or choose a non-default viewport. Call init or init_with for manual setup, or use the crate-level setup helpers for process stdio. Call restore when the session ends.

Implementations§

Source§

impl UncursesBackend<Stdin, Stdout>

Source

pub fn stdio() -> Result<Self>

Build a backend over process standard input and output.

This constructs a Screen with stdin and stdout, then wraps it in UncursesBackend::new. It does not enter raw mode, hide the cursor, enter the alternate screen, or apply screen options.

§Returns

A backend ready for manual setup or for construction of a widget-library terminal.

§Errors

Returns errors from Screen::stdio, including failures to inspect the terminal size or initialize the input event source.

§Panics

Does not intentionally panic.

§Usage note

Prefer crate-level setup helpers when process stdio and conventional setup are sufficient.

Source§

impl UncursesBackend<TtyInput, TtyOutput>

Source

pub fn open() -> Result<Self>

Build a backend over the controlling terminal instead of process stdio.

This opens the platform controlling terminal (/dev/tty on Unix, console handles on Windows), constructs a Screen, and wraps it in UncursesBackend::new. It is useful when standard input or output is redirected but the application still needs an interactive terminal.

§Returns

A backend ready for manual setup or for construction of a widget-library terminal.

§Errors

Returns errors from opening or initializing the controlling terminal, sizing the buffer, or creating the input event source.

§Panics

Does not intentionally panic.

§Usage note

Like stdio, this constructor is inert; call init or init_with before interactive use.

Source§

impl<I, O> UncursesBackend<I, O>
where I: Input, O: Write,

Source

pub fn new(screen: Screen<I, O>) -> Self

Build a backend over an existing Screen.

Use this when the screen has been constructed by the caller, or when the terminal handles are not process stdio or the controlling terminal. The backend starts with [Viewport::Fullscreen], an inline origin of 0, no remembered terminal size, and no dirty-size flag.

§Parameters
  • screen - the screen facade that will own rendering, input, and terminal lifecycle for this backend.
§Returns

A backend wrapping screen.

§Panics

Does not panic.

§Usage note

This does not call Screen::init. Initialize the screen through the backend or manually before starting an interactive session.

Source

pub fn set_viewport(&mut self, viewport: Viewport)

Record the viewport used by the surrounding terminal.

The setup helpers call this with the viewport from terminal options. The backend uses it to size the screen buffer and, for inline viewports, translate absolute frame rows into the inline buffer region. The default before this method is called is [Viewport::Fullscreen].

§Parameters
  • viewport - the viewport selected for the terminal.
§Panics

Does not panic.

§Usage note

For [Viewport::Inline], the screen buffer is resized immediately to the requested height clamped to the current terminal height. Fullscreen and fixed viewports are stored without resizing here; drawing keeps the screen in step with the current full size.

Source

pub fn screen(&self) -> &Screen<I, O>

Borrow the wrapped Screen facade.

Use this for read-only access to screen state such as cached capability or size information. Rendering and input operations that mutate the screen require screen_mut.

§Returns

A shared reference to the screen owned by this backend.

§Panics

Does not panic.

Source

pub fn screen_mut(&mut self) -> &mut Screen<I, O>

Mutably borrow the wrapped Screen facade.

Use this for screen operations not surfaced by the backend: setting screen modes, using the alternate screen directly, configuring renderer options, or manual rendering. For the async event stream, prefer the backend’s own event_stream paired with observe_event.

§Returns

A mutable reference to the screen owned by this backend.

§Panics

Does not panic.

§Usage note

Avoid mixing manual buffer writes with normal backend drawing unless the ordering is deliberate; both paths affect the same buffer.

Source

pub fn poll_event(&mut self, timeout: Option<Duration>) -> Result<bool>

Poll the wrapped screen’s input source.

This delegates to Screen::poll_event, which drives the underlying event source for at most timeout. It does not remove an event from the queue; call try_read_event or read_event after it reports availability.

§Parameters
  • timeout - Some(duration) to wait up to that duration, or None to use the event source’s blocking poll behavior.
§Returns

Ok(true) if an event is available, Ok(false) if the poll timed out.

§Errors

Returns I/O errors from the input source.

§Panics

Panics if the screen’s internal event-source lock is poisoned.

§Usage note

Polling through the backend keeps capability detection and application input on the same event source.

Source

pub fn try_read_event(&mut self) -> Option<Event>

Try to read the next queued event without blocking.

This delegates to the wrapped Screen’s pure read. Feed the returned event to observe_event if you want capability tracking; skipping it still reads fine.

§Returns

Some(event) when an event was already queued; None when reading would require blocking or additional I/O.

§Panics

Panics if the screen’s internal event-source lock is poisoned.

§Usage note

Pair this with poll_event for timeout-based loops.

Source

pub fn read_event(&mut self) -> Result<Event>

Block until the next event is available.

This delegates to the wrapped Screen’s pure read. Feed the returned event to observe_event if you want capability tracking; skipping it still reads fine.

§Returns

The next decoded terminal Event.

§Errors

Returns I/O errors from the input source.

§Panics

Panics if the screen’s internal event-source lock is poisoned.

§Usage note

Use this for simple blocking event loops. Use event_stream instead when the async feature is enabled and the application is already asynchronous.

Source

pub fn observe_event(&mut self, event: &Event) -> Result<()>

Feed an event back through the wrapped Screen for capability tracking.

Reads on this backend are pure, exactly like Screen’s. Call this once per event, on both the sync (read_event, try_read_event) and async (event_stream) paths, to keep capability detection, resize handling, and discovery-driven defaults alive. Skip it and reads still work, you just forgo those upgrades.

§Errors

Returns I/O errors from applying discovery-driven screen defaults triggered by capability replies.

Source

pub fn event_stream(&self) -> EventStream<I>
where I: 'static,

Build an async EventStream over the wrapped screen’s input.

The stream shares the screen’s decoder, so it does not race the sync read methods on the same file descriptor. Like every read on this backend it yields events without observing them; pair it with observe_event in your select! loop to keep capability tracking alive.

§Returns

An owned EventStream you can hold alongside &mut self (it shares the source by handle rather than borrowing the backend).

Source§

impl<I, O> UncursesBackend<I, O>
where I: Input + Copy, O: Output,

Source

pub fn init(&mut self) -> Result<()>

Begin an interactive session with default ScreenOptions.

This delegates to Screen::init: the screen enters raw mode, applies always-on defaults, and stages its terminal capability queries. It does not enter the alternate screen or hide the cursor by itself; the crate-level setup helpers perform those additional steps.

§Returns

Ok(()) after raw mode and screen initialization have been staged.

§Errors

Returns errors from raw-mode setup, autoresizing, bracketed paste setup, or staging capability queries.

§Panics

Does not intentionally panic.

§Usage note

Pair successful manual initialization with restore.

Source

pub fn init_with(&mut self, options: ScreenOptions) -> Result<()>

Begin an interactive session with explicit ScreenOptions.

This delegates to Screen::init_with, allowing the caller to choose bracketed paste, keyboard enhancements, mouse tracking, in-band resize preference, and pixel-size behavior before capability queries are staged. It does not enter the alternate screen or hide the cursor by itself.

§Parameters
  • options - screen defaults to apply during initialization.
§Returns

Ok(()) after raw mode and screen initialization have been staged.

§Errors

Returns errors from raw-mode setup, autoresizing, always-on mode setup, or staging capability queries.

§Panics

Does not intentionally panic.

§Usage note

Pair successful manual initialization with restore.

Source

pub fn restore(&mut self) -> Result<()>

Restore terminal state after a backend-managed session.

This delegates to Screen::pause. It tears down staged modes, resets buffer-controlled state such as alternate screen and cursor visibility, flushes pending output, and restores the terminal mode while keeping the screen available for future use.

§Returns

Ok(()) after teardown and terminal-mode restoration complete.

§Errors

Returns errors from mode teardown, flushing, or terminal restoration.

§Panics

Does not intentionally panic.

§Usage note

Treat this as the single teardown entry point for backend-managed setup.

Trait Implementations§

Source§

impl<I, O> Backend for UncursesBackend<I, O>
where I: Input + Copy, O: Output,

Source§

fn draw<'a, J>(&mut self, content: J) -> Result<()>
where J: Iterator<Item = (u16, u16, &'a RtCell)>,

Stage a frame’s cells into the wrapped screen buffer.

The iterator supplies absolute buffer coordinates and concrete cells. Each cell is converted to an uncurses cell and written to the screen. This method only stages into the buffer; the buffer diff is computed and written when the surrounding terminal calls [Backend::flush].

§Parameters
  • content - visible frame cells as (x, y, cell) triples.
§Errors

This implementation performs no I/O and returns Ok(()); renderer and output errors surface from [Backend::flush].

§Usage note

Inline viewports translate y by the stored inline origin. A detected terminal-size change invalidates the screen so this frame repaints in full.

Source§

fn hide_cursor(&mut self) -> Result<()>

Hide the terminal cursor immediately.

Delegates to Screen::hide_cursor, which stages cursor visibility on the buffer and flushes before returning.

§Errors

Returns output errors from flushing the visibility change.

Source§

fn show_cursor(&mut self) -> Result<()>

Show the terminal cursor immediately.

Delegates to Screen::show_cursor, which stages cursor visibility on the buffer and flushes before returning.

§Errors

Returns output errors from flushing the visibility change.

Source§

fn get_cursor_position(&mut self) -> Result<RtPosition>

Query the terminal for its current cursor position.

This sends a cursor-position request, then polls input until a Event::CursorPosition report arrives or the short setup timeout expires. Non-report events read while waiting are unread back into the screen in their original order so the application can still consume them. If no report arrives, the backend returns the origin.

§Returns

The zero-based cursor position reported by the terminal, or (0, 0) on timeout. Inline viewports also seed their initial origin from this row.

§Errors

Returns errors from writing the cursor-position request or polling the input source.

§Usage note

The reply parser also accepts the multi-event ambiguity that occurs when the row-1 CPR wire form collides with a modified function key sequence.

Source§

fn set_cursor_position<P: Into<RtPosition>>( &mut self, position: P, ) -> Result<()>

Move the terminal cursor to an absolute position immediately.

The backend writes an absolute CUP escape directly, records the row for inline-viewport bookkeeping, updates the renderer’s tracked cursor position in buffer-relative coordinates, and flushes.

§Parameters
  • position - zero-based absolute cursor position requested by the surrounding terminal.
§Errors

Returns output errors from writing or flushing the cursor movement.

§Usage note

Direct absolute movement keeps the renderer and inline viewport aligned; it intentionally bypasses the renderer’s cost-optimized relative moves.

Source§

fn clear(&mut self) -> Result<()>

Clear the entire backend surface immediately.

This delegates to [Backend::clear_region] with [ClearType::All].

§Errors

Returns output errors from rendering and flushing the staged blank cells.

Source§

fn clear_region(&mut self, clear_type: ClearType) -> Result<()>

Clear part of the backend surface immediately.

The implementation blanks only the cells covered by clear_type in the screen’s staging buffer, invalidates tracked cursor state, renders the diff, and flushes before returning. For inline viewports, [ClearType::AfterCursor] is also the resize/viewport-reanchor path: the last absolute cursor row becomes the new inline origin and the full inline buffer is blanked.

§Parameters
  • clear_type - the clear region requested by the surrounding terminal.
§Errors

Returns output errors from rendering or flushing the clear operation.

§Usage note

Clearing is immediate by backend contract; unlike [Backend::draw], this method does not wait for a later flush call to make output visible.

Source§

fn size(&self) -> Result<RtSize>

Return the current terminal size in cells.

This queries the live window size through the screen. If that query fails or returns zero dimensions, it falls back to the current screen buffer size. Size changes are recorded so the next draw can invalidate and repaint.

§Returns

The full terminal width and height in cells.

§Errors

This implementation falls back on query failure and currently returns Ok with the best available size.

Source§

fn window_size(&mut self) -> Result<WindowSize>

Return the current terminal size in cells and pixels.

This uses the screen’s live window-size query when available. Cell dimensions fall back to the buffer size on failure or zero reports; pixel dimensions fall back to zero when unavailable. Size changes are recorded so the next draw can invalidate and repaint.

§Returns

A [WindowSize] with columns_rows populated from the best available cell size and pixels populated from the query when reported.

§Errors

This implementation falls back on query failure and currently returns Ok with the best available size.

Source§

fn flush(&mut self) -> Result<()>

Diff the staged buffer and write the frame to the output handle.

[Backend::draw] only stages cells into the buffer; this is where the renderer computes the minimal diff against the tracked terminal and flushes the resulting bytes through the wrapped screen.

§Errors

Returns renderer or output errors from the wrapped screen.

Source§

fn append_lines(&mut self, n: u16) -> Result<()>

Append blank lines to the underlying output.

The backend writes n newline-terminated blank lines through the screen and flushes immediately.

§Parameters
  • n - number of lines to append.
§Errors

Returns output errors from writing or flushing the lines.

Source§

fn scroll_region_up(&mut self, _region: Range<u16>, _amount: u16) -> Result<()>

Handle a request to scroll a region upward.

This backend does not use terminal scrolling for region updates; drawing and buffer diffing repaint the resulting cells instead. The method is a no-op that satisfies the backend trait.

§Parameters
  • _region - ignored requested row range.
  • _amount - ignored scroll amount.
§Errors

This implementation is infallible and returns Ok(()).

Source§

fn scroll_region_down( &mut self, _region: Range<u16>, _amount: u16, ) -> Result<()>

Handle a request to scroll a region downward.

This backend does not use terminal scrolling for region updates; drawing and buffer diffing repaint the resulting cells instead. The method is a no-op that satisfies the backend trait.

§Parameters
  • _region - ignored requested row range.
  • _amount - ignored scroll amount.
§Errors

This implementation is infallible and returns Ok(()).

Source§

type Error = Error

Error type associated with this Backend.
§

fn get_cursor(&mut self) -> Result<(u16, u16), Self::Error>

👎Deprecated:

use get_cursor_position() instead which returns Result<Position>

Get the current cursor position on the terminal screen. Read more
§

fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), Self::Error>

👎Deprecated:

use set_cursor_position((x, y)) instead which takes impl Into<Position>

Set the cursor position on the terminal screen to the given x and y coordinates. Read more
Source§

impl<I, O> Write for UncursesBackend<I, O>
where I: Input, O: Write,

Source§

fn write(&mut self, buf: &[u8]) -> Result<usize>

Writes a buffer into this writer, returning how many bytes were written. Read more
Source§

fn flush(&mut self) -> Result<()>

Flushes this output stream, ensuring that all intermediately buffered contents reach their destination. Read more
1.36.0 · Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · Source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · Source§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

§

impl<I, O> !Freeze for UncursesBackend<I, O>

§

impl<I, O> !RefUnwindSafe for UncursesBackend<I, O>

§

impl<I, O> Send for UncursesBackend<I, O>
where O: Send,

§

impl<I, O> !Sync for UncursesBackend<I, O>

§

impl<I, O> Unpin for UncursesBackend<I, O>
where I: Unpin, O: Unpin,

§

impl<I, O> UnsafeUnpin for UncursesBackend<I, O>
where I: UnsafeUnpin, O: UnsafeUnpin,

§

impl<I, O> UnwindSafe for UncursesBackend<I, O>
where I: UnwindSafe, O: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> ErasedDestructor for T
where T: 'static,