aboutsummaryrefslogtreecommitdiff
path: root/src/pane/osc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/pane/osc.rs')
-rw-r--r--src/pane/osc.rs57
1 files changed, 54 insertions, 3 deletions
diff --git a/src/pane/osc.rs b/src/pane/osc.rs
index 217e0c86..1512f336 100644
--- a/src/pane/osc.rs
+++ b/src/pane/osc.rs
@@ -26,6 +26,7 @@ pub(super) enum DefaultColorEvent {
Query(DefaultColorQuery),
Set(DefaultColorQuery),
Reset(DefaultColorQuery),
+ PaletteQuery(u8),
}
#[derive(Debug, Default)]
@@ -240,10 +241,24 @@ fn parse_default_color_event(body: &[u8]) -> Option<DefaultColorEvent> {
b"11;?" => Some(DefaultColorEvent::Query(DefaultColorQuery::Background)),
b"110" | b"110;" => Some(DefaultColorEvent::Reset(DefaultColorQuery::Foreground)),
b"111" | b"111;" => Some(DefaultColorEvent::Reset(DefaultColorQuery::Background)),
- _ => parse_default_color_set_event(body),
+ _ => parse_palette_color_query(body).or_else(|| parse_default_color_set_event(body)),
}
}
+fn parse_palette_color_query(body: &[u8]) -> Option<DefaultColorEvent> {
+ let index = body.strip_prefix(b"4;")?.strip_suffix(b";?")?;
+ if index.is_empty() || index.len() > 3 || !index.iter().all(|byte| byte.is_ascii_digit()) {
+ return None;
+ }
+ let mut value: u16 = 0;
+ for &digit in index {
+ value = value * 10 + u16::from(digit - b'0');
+ }
+ u8::try_from(value)
+ .ok()
+ .map(DefaultColorEvent::PaletteQuery)
+}
+
fn parse_default_color_set_event(body: &[u8]) -> Option<DefaultColorEvent> {
let separator = body.iter().position(|byte| *byte == b';')?;
let query = match &body[..separator] {
@@ -576,13 +591,16 @@ mod tests {
fn default_color_event_tracker_detects_queries_sets_and_resets() {
let mut tracker = DefaultColorEventTracker::default();
- tracker.observe(b"\x1b]10;?\x07\x1b]11;?\x1b\\\x1b]10;rgb:11/22/33\x07\x1b]111\x07");
+ tracker.observe(
+ b"\x1b]10;?\x07\x1b]11;?\x1b\\\x1b]4;0;?\x07\x1b]10;rgb:11/22/33\x07\x1b]111\x07",
+ );
assert_eq!(
tracker.drain_pending(),
vec![
DefaultColorEvent::Query(DefaultColorQuery::Foreground),
DefaultColorEvent::Query(DefaultColorQuery::Background),
+ DefaultColorEvent::PaletteQuery(0),
DefaultColorEvent::Set(DefaultColorQuery::Foreground),
DefaultColorEvent::Reset(DefaultColorQuery::Background),
]
@@ -590,7 +608,7 @@ mod tests {
}
#[test]
- fn default_color_event_tracker_handles_split_queries() {
+ fn default_color_event_tracker_handles_split_default_color_queries() {
let mut tracker = DefaultColorEventTracker::default();
tracker.observe(b"\x1b]11");
@@ -606,6 +624,39 @@ mod tests {
}
#[test]
+ fn default_color_event_tracker_handles_split_palette_color_queries() {
+ let mut tracker = DefaultColorEventTracker::default();
+
+ tracker.observe(b"\x1b]4;25");
+ assert!(tracker.drain_pending().is_empty());
+ tracker.observe(b"5;?\x1b");
+ assert!(tracker.drain_pending().is_empty());
+ tracker.observe(b"\\");
+
+ assert_eq!(
+ tracker.drain_pending(),
+ vec![DefaultColorEvent::PaletteQuery(255)]
+ );
+ }
+
+ #[test]
+ fn default_color_event_tracker_rejects_malformed_palette_color_queries() {
+ let mut tracker = DefaultColorEventTracker::default();
+
+ tracker.observe(b"\x1b]4;;?\x07");
+ tracker.observe(b"\x1b]4;-1;?\x07");
+ tracker.observe(b"\x1b]4;256;?\x07");
+ tracker.observe(b"\x1b]4;0;?;1;?\x07");
+ tracker.observe(b"\x1b]4;0;rgb:1111/2222/3333\x07");
+ tracker.observe(b"\x1b]4;0;?\x07");
+
+ assert_eq!(
+ tracker.drain_pending(),
+ vec![DefaultColorEvent::PaletteQuery(0)]
+ );
+ }
+
+ #[test]
fn default_color_event_tracker_ignores_other_osc_and_dcs_payloads() {
let mut tracker = DefaultColorEventTracker::default();