1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-21 03:39:16 +03:00

implement answerback for osc 4, 10-18

These codes are used to change the color palette, but if the `?`
string is used in place of a color spec, then we must respond with
the current color value string for that palette entry, so lets
implement that!
This commit is contained in:
Wez Furlong 2019-06-02 12:19:58 -07:00
parent bf719caaf3
commit 99919dc807
2 changed files with 73 additions and 27 deletions

View File

@ -12,7 +12,7 @@ use termwiz::escape::csi::{
Cursor, DecPrivateMode, DecPrivateModeCode, Device, Edit, EraseInDisplay, EraseInLine, Mode,
Sgr, TerminalMode, TerminalModeCode, Window,
};
use termwiz::escape::osc::{ITermFileData, ITermProprietary};
use termwiz::escape::osc::{ChangeColorPair, ColorOrQuery, ITermFileData, ITermProprietary};
use termwiz::escape::{Action, ControlCode, Esc, EscCode, OneBased, OperatingSystemCommand, CSI};
use termwiz::hyperlink::Rule as HyperlinkRule;
use termwiz::image::{ImageCell, ImageData, TextureCoordinate};
@ -2108,35 +2108,56 @@ impl<'a> Performer<'a> {
eprintln!("Application sends SystemNotification: {}", message);
}
OperatingSystemCommand::ChangeColorNumber(specs) => {
eprintln!("ChangeColorNumber: {:?}", specs);
for pair in specs {
eprintln!(
"ChangeColorNumber {} to {}",
pair.palette_index,
pair.color.to_rgb_string()
);
self.palette.colors.0[pair.palette_index as usize] = pair.color;
match pair.color {
ColorOrQuery::Query => {
let response =
OperatingSystemCommand::ChangeColorNumber(vec![ChangeColorPair {
palette_index: pair.palette_index,
color: ColorOrQuery::Color(
self.palette.colors.0[pair.palette_index as usize],
),
}]);
write!(self.host.writer(), "{}", response).ok();
}
ColorOrQuery::Color(c) => {
self.palette.colors.0[pair.palette_index as usize] = c;
}
}
}
self.make_all_lines_dirty();
}
OperatingSystemCommand::ChangeDynamicColors(first_color, colors) => {
eprintln!("ChangeDynamicColors: {:?} {:?}", first_color, colors);
use termwiz::escape::osc::DynamicColorNumber;
let mut idx: u8 = first_color as u8;
for color in colors {
let which_color: Option<DynamicColorNumber> = num::FromPrimitive::from_u8(idx);
if let Some(which_color) = which_color {
macro_rules! set_or_query {
($name:ident) => {
match color {
ColorOrQuery::Query => {
let response = OperatingSystemCommand::ChangeDynamicColors(
which_color,
vec![ColorOrQuery::Color(self.palette.$name)],
);
write!(self.host.writer(), "{}", response).ok();
}
ColorOrQuery::Color(c) => self.palette.$name = c,
}
};
}
match which_color {
DynamicColorNumber::TextForegroundColor => {
self.palette.foreground = color
}
DynamicColorNumber::TextBackgroundColor => {
self.palette.background = color
}
DynamicColorNumber::TextCursorColor => self.palette.cursor_bg = color,
DynamicColorNumber::TextForegroundColor => set_or_query!(foreground),
DynamicColorNumber::TextBackgroundColor => set_or_query!(background),
DynamicColorNumber::TextCursorColor => set_or_query!(cursor_bg),
DynamicColorNumber::HighlightForegroundColor => {
self.palette.selection_fg = color
set_or_query!(selection_fg)
}
DynamicColorNumber::HighlightBackgroundColor => {
self.palette.selection_bg = color
set_or_query!(selection_bg)
}
DynamicColorNumber::MouseForegroundColor
| DynamicColorNumber::MouseBackgroundColor

View File

@ -10,6 +10,21 @@ use std::collections::HashMap;
use std::fmt::{Display, Error as FmtError, Formatter};
use std::str;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ColorOrQuery {
Color(RgbColor),
Query,
}
impl Display for ColorOrQuery {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match self {
ColorOrQuery::Query => write!(f, "?"),
ColorOrQuery::Color(c) => write!(f, "{}", c.to_rgb_string()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum OperatingSystemCommand {
SetIconNameAndWindowTitle(String),
@ -22,7 +37,7 @@ pub enum OperatingSystemCommand {
SystemNotification(String),
ITermProprietary(ITermProprietary),
ChangeColorNumber(Vec<ChangeColorPair>),
ChangeDynamicColors(DynamicColorNumber, Vec<RgbColor>),
ChangeDynamicColors(DynamicColorNumber, Vec<ColorOrQuery>),
Unspecified(Vec<Vec<u8>>),
}
@ -45,7 +60,7 @@ pub enum DynamicColorNumber {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ChangeColorPair {
pub palette_index: u8,
pub color: RgbColor,
pub color: ColorOrQuery,
}
bitflags! {
@ -157,8 +172,14 @@ impl OperatingSystemCommand {
while let (Some(index), Some(spec)) = (iter.next(), iter.next()) {
let index: u8 = str::from_utf8(index)?.parse()?;
let spec = str::from_utf8(spec)?;
let spec = RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?;
let spec = if spec == "?" {
ColorOrQuery::Query
} else {
ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?,
)
};
pairs.push(ChangeColorPair {
palette_index: index,
@ -174,11 +195,15 @@ impl OperatingSystemCommand {
.ok_or_else(|| err_msg("osc code is not a valid DynamicColorNumber!?"))?;
let mut colors = vec![];
for spec in osc.iter().skip(1) {
let spec = str::from_utf8(spec)?;
colors.push(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?,
);
if spec == b"?" {
colors.push(ColorOrQuery::Query);
} else {
let spec = str::from_utf8(spec)?;
colors.push(ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?,
));
}
}
Ok(OperatingSystemCommand::ChangeDynamicColors(
@ -301,13 +326,13 @@ impl Display for OperatingSystemCommand {
ChangeColorNumber(specs) => {
write!(f, "4;")?;
for pair in specs {
write!(f, "{};{}", pair.palette_index, pair.color.to_rgb_string())?
write!(f, "{};{}", pair.palette_index, pair.color)?
}
}
ChangeDynamicColors(first_color, colors) => {
write!(f, "{}", *first_color as u8)?;
for color in colors {
write!(f, ";{}", color.to_rgb_string())?
write!(f, ";{}", color)?
}
}
};