Skip to content

Commit

Permalink
drop font_size, just add window_size() -> WindowSize
Browse files Browse the repository at this point in the history
  • Loading branch information
benjajaja committed Jun 13, 2023
1 parent de0e627 commit 797e732
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 37 deletions.
4 changes: 2 additions & 2 deletions examples/is_tty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crossterm::{
execute,
terminal::{font_size, size, SetSize},
terminal::{size, window_size, SetSize},
tty::IsTty,
};
use std::io::{stdin, stdout};
Expand All @@ -10,7 +10,7 @@ pub fn main() {
execute!(stdout(), SetSize(10, 10)).unwrap();
println!("resized: {:?}", size().unwrap());

println!("font_size: {:?}", font_size().unwrap());
println!("pixel size: {:?}", window_size().unwrap());

if stdin().is_tty() {
println!("Is TTY");
Expand Down
17 changes: 14 additions & 3 deletions src/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,20 @@ pub fn size() -> io::Result<(u16, u16)> {
sys::size()
}

/// Returns the terminal font size in pixels.
pub fn font_size() -> io::Result<(u16, u16)> {
sys::font_size()
#[derive(Debug)]
pub struct WindowSize {
pub rows: u16,
pub columns: u16,
pub width: u16,
pub height: u16,
}

/// Returns the terminal size `[WindowSize]`.
///
/// The width and height in pixels may not be reliably implemented and default to 0, as
/// https://man7.org/linux/man-pages/man4/tty_ioctl.4.html documents them as "unused".
pub fn window_size() -> io::Result<WindowSize> {
sys::window_size()
}

/// Disables line wrapping.
Expand Down
2 changes: 1 addition & 1 deletion src/terminal/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
pub use self::unix::supports_keyboard_enhancement;
#[cfg(unix)]
pub(crate) use self::unix::{
disable_raw_mode, enable_raw_mode, font_size, is_raw_mode_enabled, size,
disable_raw_mode, enable_raw_mode, window_size, is_raw_mode_enabled, size,
};
#[cfg(windows)]
#[cfg(feature = "events")]
Expand Down
51 changes: 23 additions & 28 deletions src/terminal/sys/unix.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! UNIX related logic for terminal manipulation.
use crate::terminal::sys::file_descriptor::{tty_fd, FileDesc};
use crate::terminal::{
sys::file_descriptor::{tty_fd, FileDesc},
WindowSize,
};
use libc::{
cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDOUT_FILENO, TCSANOW,
TIOCGWINSZ,
Expand All @@ -20,36 +23,19 @@ pub(crate) fn is_raw_mode_enabled() -> bool {
TERMINAL_MODE_PRIOR_RAW_MODE.lock().is_some()
}

#[allow(clippy::useless_conversion)]
pub(crate) fn size() -> io::Result<(u16, u16)> {
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
let mut size = winsize {
ws_row: 0,
ws_col: 0,
ws_xpixel: 0,
ws_ypixel: 0,
};

let file = File::open("/dev/tty").map(|file| (FileDesc::new(file.into_raw_fd(), true)));
let fd = if let Ok(file) = &file {
file.raw_fd()
} else {
// Fallback to libc::STDOUT_FILENO if /dev/tty is missing
STDOUT_FILENO
};

if wrap_with_result(unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut size) }).is_ok()
&& size.ws_col != 0
&& size.ws_row != 0
{
return Ok((size.ws_col, size.ws_row));
impl From<winsize> for WindowSize {
fn from(size: winsize) -> WindowSize {
WindowSize {
columns: size.ws_col,
rows: size.ws_row,
width: size.ws_xpixel,
height: size.ws_ypixel,
}
}

tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
}

#[allow(clippy::useless_conversion)]
pub(crate) fn font_size() -> io::Result<(u16, u16)> {
pub(crate) fn window_size() -> io::Result<WindowSize> {
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
let mut size = winsize {
ws_row: 0,
Expand All @@ -67,12 +53,21 @@ pub(crate) fn font_size() -> io::Result<(u16, u16)> {
};

if wrap_with_result(unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut size) }).is_ok() {
return Ok((size.ws_xpixel / size.ws_col, size.ws_ypixel / size.ws_row));
return Ok(size.into());
}

Err(std::io::Error::last_os_error().into())
}

#[allow(clippy::useless_conversion)]
pub(crate) fn size() -> io::Result<(u16, u16)> {
if let Ok(window_size) = window_size() {
return Ok((window_size.columns, window_size.rows));
}

tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
}

pub(crate) fn enable_raw_mode() -> io::Result<()> {
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock();

Expand Down
13 changes: 10 additions & 3 deletions src/terminal/sys/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,16 @@ pub(crate) fn size() -> io::Result<(u16, u16)> {
))
}

pub(crate) fn font_size() -> io::Result<(u16, u16)> {
let size = ScreenBuffer::current()?.font_info()?.size();
Ok((size.width as u16, size.height as u16))
pub(crate) fn window_size() -> io::Result<WindowSize> {
let (columns, rows) = size()?;
let font_size = ScreenBuffer::current()?.font_info()?.size();
Ok(WindowSize {
columns,
rows,
// `(columns,rows)` start at index 1.
width: (columns - 1) * font_size.0,
height: (rows - 1) * font_size.1,
})
}

/// Queries the terminal's support for progressive keyboard enhancement.
Expand Down

0 comments on commit 797e732

Please sign in to comment.