Skip to content

Commit

Permalink
Don't crash if terminal window size can't be found
Browse files Browse the repository at this point in the history
  • Loading branch information
mfontanini committed Oct 20, 2023
1 parent 0a7d3d6 commit ab6dbc6
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 14 deletions.
6 changes: 1 addition & 5 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,7 @@ impl<'a> PresentationBuilder<'a> {
}
self.needs_enter_column = false;
let last_valid = matches!(last, RenderOperation::EnterColumn { .. } | RenderOperation::ExitLayout);
if last_valid {
Ok(())
} else {
Err(BuildError::NotInsideColumn)
}
if last_valid { Ok(()) } else { Err(BuildError::NotInsideColumn) }
}

fn push_slide_prelude(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ pub mod presentation;
pub mod presenter;
pub mod render;
pub mod resource;
pub mod splash;
pub mod style;
pub mod theme;
pub mod splash;
8 changes: 6 additions & 2 deletions src/render/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ impl Layout {
}

fn fit_to_columns(dimensions: &WindowSize, required_fit: u16, actual_fit: u16) -> u16 {
if required_fit > dimensions.columns { 0 } else { actual_fit }
if required_fit > dimensions.columns {
0
} else {
actual_fit
}
}
}

Expand Down Expand Up @@ -161,7 +165,7 @@ mod test {
Positioning{ max_line_length: 60, start_column: 20 }
)]
fn layout(#[case] alignment: Alignment, #[case] length: u16, #[case] expected: Positioning) {
let dimensions = WindowSize { rows: 0, columns: 100, width: 0, height: 0 };
let dimensions = WindowSize { rows: 0, columns: 100, width: 0, height: 0, has_pixels: true };
let positioning = Layout::new(alignment).compute(&dimensions, length);
assert_eq!(positioning, expected);
}
Expand Down
6 changes: 6 additions & 0 deletions src/render/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl MediaRender {
position: CursorPosition,
dimensions: &WindowSize,
) -> Result<(), RenderImageError> {
if !dimensions.has_pixels {
return Err(RenderImageError::NoWindowSize);
}
let image = &image.0;

// Compute the image's width in columns by translating pixels -> columns.
Expand Down Expand Up @@ -97,4 +100,7 @@ pub enum RenderImageError {

#[error("invalid image: {0}")]
InvalidImage(#[from] InvalidImage),

#[error("no window size support in terminal")]
NoWindowSize,
}
30 changes: 24 additions & 6 deletions src/render/properties.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crossterm::{cursor::position, terminal::window_size};
use std::io;
use crossterm::{cursor::position, terminal};
use std::io::{self, ErrorKind};

/// The size of the terminal window.
///
Expand All @@ -11,13 +11,21 @@ pub struct WindowSize {
pub columns: u16,
pub height: u16,
pub width: u16,
pub has_pixels: bool,
}

impl WindowSize {
/// Get the current window size.
pub fn current() -> io::Result<Self> {
let size = window_size()?;
Ok(size.into())
match terminal::window_size() {
Ok(size) => Ok(size.into()),
Err(e) if e.kind() == ErrorKind::Unsupported => {
// Fall back to a `WindowSize` that doesn't have pixel support.
let size = terminal::size()?;
Ok(size.into())
}
Err(e) => Err(e),
}
}

/// Shrink a window by the given number of rows.
Expand All @@ -31,6 +39,7 @@ impl WindowSize {
columns: self.columns,
height: self.height.saturating_sub(height_to_shrink),
width: self.width,
has_pixels: self.has_pixels,
}
}

Expand All @@ -45,6 +54,7 @@ impl WindowSize {
columns: self.columns.saturating_sub(amount),
height: self.height,
width: self.width.saturating_sub(width_to_shrink),
has_pixels: self.has_pixels,
}
}

Expand All @@ -61,7 +71,13 @@ impl WindowSize {

impl From<crossterm::terminal::WindowSize> for WindowSize {
fn from(size: crossterm::terminal::WindowSize) -> Self {
Self { rows: size.rows, columns: size.columns, width: size.width, height: size.height }
Self { rows: size.rows, columns: size.columns, width: size.width, height: size.height, has_pixels: true }
}
}

impl From<(u16, u16)> for WindowSize {
fn from((columns, rows): (u16, u16)) -> Self {
Self { columns, rows, width: 0, height: 0, has_pixels: false }
}
}

Expand All @@ -86,7 +102,7 @@ mod test {

#[test]
fn shrink() {
let dimensions = WindowSize { rows: 10, columns: 10, width: 200, height: 100 };
let dimensions = WindowSize { rows: 10, columns: 10, width: 200, height: 100, has_pixels: true };
assert_eq!(dimensions.pixels_per_column(), 20.0);
assert_eq!(dimensions.pixels_per_row(), 10.0);

Expand All @@ -97,5 +113,7 @@ mod test {
let new_dimensions = new_dimensions.shrink_columns(3);
assert_eq!(new_dimensions.columns, 7);
assert_eq!(new_dimensions.width, 140);

assert!(new_dimensions.has_pixels);
}
}
1 change: 1 addition & 0 deletions src/render/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ where
fn drop(&mut self) {
let _ = self.writer.queue(terminal::LeaveAlternateScreen);
let _ = self.writer.queue(cursor::Show);
let _ = self.writer.flush();
let _ = terminal::disable_raw_mode();
}
}

0 comments on commit ab6dbc6

Please sign in to comment.