1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-26 16:34:23 +03:00

term: implement OSC 1337 ReportCellSize

refs: https://github.com/wez/wezterm/issues/2085
This commit is contained in:
Wez Furlong 2022-06-15 18:55:11 -07:00
parent df7c09d760
commit 2c1fc27636
2 changed files with 79 additions and 11 deletions

View File

@ -5,6 +5,7 @@ use crate::terminalstate::{
use crate::{ClipboardSelection, Position, TerminalState, VisibleRowIndex, DCS, ST};
use log::{debug, error};
use num_traits::FromPrimitive;
use ordered_float::NotNan;
use std::fmt::Write;
use std::ops::{Deref, DerefMut};
use termwiz::cell::{grapheme_column_width, Cell, CellAttributes, SemanticType};
@ -630,6 +631,37 @@ impl<'a> Performer<'a> {
}
}
OperatingSystemCommand::ITermProprietary(iterm) => match iterm {
ITermProprietary::RequestCellSize => {
let screen = self.screen();
let height = screen.physical_rows;
let width = screen.physical_cols;
let scale = if screen.dpi == 0 {
1.0
} else {
// Since iTerm2 is a macOS specific piece
// of software, it uses the macOS default dpi
// if 72 for the basis of its scale, regardless
// of the host base dpi.
screen.dpi as f32 / 72.
};
let width = (self.pixel_width as f32 / width as f32) / scale;
let height = (self.pixel_height as f32 / height as f32) / scale;
let response = OperatingSystemCommand::ITermProprietary(
ITermProprietary::ReportCellSize {
width_pixels: NotNan::new(width).unwrap(),
height_pixels: NotNan::new(height).unwrap(),
scale: if screen.dpi == 0 {
None
} else {
Some(NotNan::new(scale).unwrap())
},
},
);
write!(self.writer, "{}", response).ok();
self.writer.flush().ok();
}
ITermProprietary::File(image) => self.set_image(*image),
ITermProprietary::SetUserVar { name, value } => {
self.user_vars.insert(name.clone(), value.clone());

View File

@ -812,10 +812,14 @@ pub enum ITermProprietary {
/// Request that the terminal send a ReportCellSize response
RequestCellSize,
/// The response to RequestCellSize. The height and width are the dimensions
/// of a cell measured in points
/// of a cell measured in points according to the docs, but in practice, they
/// are actually pixels.
/// If scale is_some(), the width and height will be multiplied by scale to
/// get the true device dimensions
ReportCellSize {
height_points: NotNan<f32>,
width_points: NotNan<f32>,
height_pixels: NotNan<f32>,
width_pixels: NotNan<f32>,
scale: Option<NotNan<f32>>,
},
/// Place a string in the systems pasteboard
Copy(String),
@ -1145,8 +1149,18 @@ impl ITermProprietary {
if osc.len() == 3 && keyword == "ReportCellSize" && p1.is_some() {
if let Some(p1) = p1 {
return Ok(ITermProprietary::ReportCellSize {
height_points: NotNan::new(p1.parse()?)?,
width_points: NotNan::new(String::from_utf8_lossy(osc[2]).parse()?)?,
height_pixels: NotNan::new(p1.parse()?)?,
width_pixels: NotNan::new(String::from_utf8_lossy(osc[2]).parse()?)?,
scale: None,
});
}
}
if osc.len() == 4 && keyword == "ReportCellSize" && p1.is_some() {
if let Some(p1) = p1 {
return Ok(ITermProprietary::ReportCellSize {
height_pixels: NotNan::new(p1.parse()?)?,
width_pixels: NotNan::new(String::from_utf8_lossy(osc[2]).parse()?)?,
scale: Some(NotNan::new(String::from_utf8_lossy(osc[3]).parse()?)?),
});
}
}
@ -1216,9 +1230,18 @@ impl Display for ITermProprietary {
}
RequestCellSize => write!(f, "ReportCellSize")?,
ReportCellSize {
height_points,
width_points,
} => write!(f, "ReportCellSize={};{}", height_points, width_points)?,
height_pixels,
width_pixels,
scale: None,
} => write!(f, "ReportCellSize={height_pixels:.1};{width_pixels:.1}")?,
ReportCellSize {
height_pixels,
width_pixels,
scale: Some(scale),
} => write!(
f,
"ReportCellSize={height_pixels:.1};{width_pixels:.1};{scale:.1}",
)?,
Copy(s) => write!(f, "Copy=;{}", base64::encode(s))?,
ReportVariable(s) => write!(f, "ReportVariable={}", base64::encode(s))?,
SetUserVar { name, value } => {
@ -1615,11 +1638,24 @@ mod test {
assert_eq!(
parse(
&["1337", "ReportCellSize=12.0", "15.5"],
"\x1b]1337;ReportCellSize=12;15.5\x1b\\"
"\x1b]1337;ReportCellSize=12.0;15.5\x1b\\"
),
OperatingSystemCommand::ITermProprietary(ITermProprietary::ReportCellSize {
height_points: NotNan::new(12.0).unwrap(),
width_points: NotNan::new(15.5).unwrap()
height_pixels: NotNan::new(12.0).unwrap(),
width_pixels: NotNan::new(15.5).unwrap(),
scale: None,
})
);
assert_eq!(
parse(
&["1337", "ReportCellSize=12.0", "15.5", "2.0"],
"\x1b]1337;ReportCellSize=12.0;15.5;2.0\x1b\\"
),
OperatingSystemCommand::ITermProprietary(ITermProprietary::ReportCellSize {
height_pixels: NotNan::new(12.0).unwrap(),
width_pixels: NotNan::new(15.5).unwrap(),
scale: Some(NotNan::new(2.0).unwrap()),
})
);