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:
parent
df7c09d760
commit
2c1fc27636
@ -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());
|
||||
|
@ -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()),
|
||||
})
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user