fix(compatibility): respond to bg and fg color ansi queries (#1358)

* fix(compatibility): respond to background/foreground queries

* style(fmt): rustfmt

* style(clippy): make clippy happy

* style(fmt): rustfmt

* style(fmt): remove unused code
This commit is contained in:
Aram Drevekenin 2022-04-28 17:26:44 +02:00 committed by GitHub
parent 188febfc05
commit 0dc136ec5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 433 additions and 275 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -4,6 +4,7 @@ use std::sync::{Arc, Mutex};
use zellij_server::panes::{LinkHandler, TerminalPane}; use zellij_server::panes::{LinkHandler, TerminalPane};
use zellij_utils::pane_size::{Dimension, PaneGeom, Size}; use zellij_utils::pane_size::{Dimension, PaneGeom, Size};
use zellij_utils::vte; use zellij_utils::vte;
use zellij_utils::zellij_tile::data::Palette;
use zellij_utils::zellij_tile::prelude::Style; use zellij_utils::zellij_tile::prelude::Style;
use ssh2::Session; use ssh2::Session;
@ -162,6 +163,7 @@ fn read_from_channel(
String::new(), String::new(),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
Rc::new(RefCell::new(Palette::default())),
); // 0 is the pane index ); // 0 is the pane index
loop { loop {
if !should_keep_running.load(Ordering::SeqCst) { if !should_keep_running.load(Ordering::SeqCst) {

View file

@ -10,7 +10,7 @@ use zellij_utils::{
use crate::{ use crate::{
os_input_output::ClientOsApi, os_input_output::ClientOsApi,
pixel_csi_parser::{PixelCsiParser, PixelDimensionsOrKeys}, stdin_ansi_parser::{AnsiStdinInstructionOrKeys, StdinAnsiParser},
ClientInstruction, CommandIsExecuting, InputInstruction, ClientInstruction, CommandIsExecuting, InputInstruction,
}; };
use zellij_utils::{ use zellij_utils::{
@ -71,15 +71,19 @@ impl InputHandler {
if self.options.mouse_mode.unwrap_or(true) { if self.options.mouse_mode.unwrap_or(true) {
self.os_input.enable_mouse(); self.os_input.enable_mouse();
} }
// <ESC>[14t => get text area size in pixels, <ESC>[16t => get character cell size in pixels // <ESC>[14t => get text area size in pixels,
let get_cell_pixel_info = "\u{1b}[14t\u{1b}[16t"; // <ESC>[16t => get character cell size in pixels
// <ESC>]11;?<ESC>\ => get background color
// <ESC>]10;?<ESC>\ => get foreground color
let get_cell_pixel_info =
"\u{1b}[14t\u{1b}[16t\u{1b}]11;?\u{1b}\u{5c}\u{1b}]10;?\u{1b}\u{5c}";
let _ = self let _ = self
.os_input .os_input
.get_stdout_writer() .get_stdout_writer()
.write(get_cell_pixel_info.as_bytes()) .write(get_cell_pixel_info.as_bytes())
.unwrap(); .unwrap();
let mut pixel_csi_parser = PixelCsiParser::new(); let mut ansi_stdin_parser = StdinAnsiParser::new();
pixel_csi_parser.increment_expected_csi_instructions(2); ansi_stdin_parser.increment_expected_ansi_instructions(4);
loop { loop {
if self.should_exit { if self.should_exit {
break; break;
@ -89,9 +93,9 @@ impl InputHandler {
match input_event { match input_event {
InputEvent::Key(key_event) => { InputEvent::Key(key_event) => {
let key = cast_termwiz_key(key_event, &raw_bytes); let key = cast_termwiz_key(key_event, &raw_bytes);
if pixel_csi_parser.expected_instructions() > 0 { if ansi_stdin_parser.expected_instructions() > 0 {
self.handle_possible_pixel_instruction( self.handle_possible_pixel_instruction(
pixel_csi_parser.parse(key, raw_bytes), ansi_stdin_parser.parse(key, raw_bytes),
); );
} else { } else {
self.handle_key(&key, raw_bytes); self.handle_key(&key, raw_bytes);
@ -123,7 +127,7 @@ impl InputHandler {
.get_stdout_writer() .get_stdout_writer()
.write(get_cell_pixel_info.as_bytes()) .write(get_cell_pixel_info.as_bytes())
.unwrap(); .unwrap();
pixel_csi_parser.increment_expected_csi_instructions(2); ansi_stdin_parser.increment_expected_ansi_instructions(4);
} }
Err(err) => panic!("Encountered read error: {:?}", err), Err(err) => panic!("Encountered read error: {:?}", err),
} }
@ -140,14 +144,26 @@ impl InputHandler {
} }
fn handle_possible_pixel_instruction( fn handle_possible_pixel_instruction(
&mut self, &mut self,
pixel_instruction_or_keys: Option<PixelDimensionsOrKeys>, pixel_instruction_or_keys: Option<AnsiStdinInstructionOrKeys>,
) { ) {
match pixel_instruction_or_keys { match pixel_instruction_or_keys {
Some(PixelDimensionsOrKeys::PixelDimensions(pixel_dimensions)) => { Some(AnsiStdinInstructionOrKeys::PixelDimensions(pixel_dimensions)) => {
self.os_input self.os_input
.send_to_server(ClientToServerMsg::TerminalPixelDimensions(pixel_dimensions)); .send_to_server(ClientToServerMsg::TerminalPixelDimensions(pixel_dimensions));
} }
Some(PixelDimensionsOrKeys::Keys(keys)) => { Some(AnsiStdinInstructionOrKeys::BackgroundColor(background_color_instruction)) => {
self.os_input
.send_to_server(ClientToServerMsg::BackgroundColor(
background_color_instruction,
));
}
Some(AnsiStdinInstructionOrKeys::ForegroundColor(foreground_color_instruction)) => {
self.os_input
.send_to_server(ClientToServerMsg::ForegroundColor(
foreground_color_instruction,
));
}
Some(AnsiStdinInstructionOrKeys::Keys(keys)) => {
for (key, raw_bytes) in keys { for (key, raw_bytes) in keys {
self.handle_key(&key, raw_bytes); self.handle_key(&key, raw_bytes);
} }
@ -281,4 +297,4 @@ pub(crate) fn input_loop(
#[cfg(test)] #[cfg(test)]
#[path = "./unit/input_handler_tests.rs"] #[path = "./unit/input_handler_tests.rs"]
mod grid_tests; mod input_handler_tests;

View file

@ -2,7 +2,7 @@ pub mod os_input_output;
mod command_is_executing; mod command_is_executing;
mod input_handler; mod input_handler;
mod pixel_csi_parser; mod stdin_ansi_parser;
mod stdin_handler; mod stdin_handler;
use log::info; use log::info;

View file

@ -1,146 +0,0 @@
use zellij_utils::pane_size::SizeInPixels;
use zellij_utils::{ipc::PixelDimensions, lazy_static::lazy_static, regex::Regex};
use zellij_tile::data::Key;
pub struct PixelCsiParser {
expected_pixel_csi_instructions: usize,
current_buffer: Vec<(Key, Vec<u8>)>,
}
impl PixelCsiParser {
pub fn new() -> Self {
PixelCsiParser {
expected_pixel_csi_instructions: 0,
current_buffer: vec![],
}
}
pub fn increment_expected_csi_instructions(&mut self, by: usize) {
self.expected_pixel_csi_instructions += by;
}
pub fn decrement_expected_csi_instructions(&mut self, by: usize) {
self.expected_pixel_csi_instructions =
self.expected_pixel_csi_instructions.saturating_sub(by);
}
pub fn expected_instructions(&self) -> usize {
self.expected_pixel_csi_instructions
}
pub fn parse(&mut self, key: Key, raw_bytes: Vec<u8>) -> Option<PixelDimensionsOrKeys> {
if let Key::Char('t') = key {
self.current_buffer.push((key, raw_bytes));
match PixelDimensionsOrKeys::pixel_dimensions_from_keys(&self.current_buffer) {
Ok(pixel_instruction) => {
self.decrement_expected_csi_instructions(1);
self.current_buffer.clear();
Some(pixel_instruction)
}
Err(_) => {
self.expected_pixel_csi_instructions = 0;
Some(PixelDimensionsOrKeys::Keys(
self.current_buffer.drain(..).collect(),
))
}
}
} else if self.key_is_valid(key) {
self.current_buffer.push((key, raw_bytes));
None
} else {
self.current_buffer.push((key, raw_bytes));
self.expected_pixel_csi_instructions = 0;
Some(PixelDimensionsOrKeys::Keys(
self.current_buffer.drain(..).collect(),
))
}
}
fn key_is_valid(&self, key: Key) -> bool {
match key {
Key::Esc => {
// this is a UX improvement
// in case the user's terminal doesn't support one or more of these signals,
// if they spam ESC they need to be able to get back to normal mode and not "us
// waiting for pixel instructions" mode
if self
.current_buffer
.iter()
.find(|(key, _)| *key == Key::Esc)
.is_none()
{
true
} else {
false
}
}
Key::Char(';') | Key::Char('[') => true,
Key::Char(c) => {
if let '0'..='9' = c {
true
} else {
false
}
}
_ => false,
}
}
}
#[derive(Debug)]
pub enum PixelDimensionsOrKeys {
// TODO: rename to PixelDimensionsOrKeys
PixelDimensions(PixelDimensions),
Keys(Vec<(Key, Vec<u8>)>),
}
impl PixelDimensionsOrKeys {
pub fn pixel_dimensions_from_keys(keys: &Vec<(Key, Vec<u8>)>) -> Result<Self, &'static str> {
lazy_static! {
static ref RE: Regex = Regex::new(r"^\u{1b}\[(\d+);(\d+);(\d+)t$").unwrap();
}
let key_sequence: Vec<Option<char>> = keys
.iter()
.map(|(key, _)| match key {
Key::Char(c) => Some(*c),
Key::Esc => Some('\u{1b}'),
_ => None,
})
.collect();
if key_sequence.iter().all(|k| k.is_some()) {
let key_string: String = key_sequence.iter().map(|k| k.unwrap()).collect();
let captures = RE
.captures_iter(&key_string)
.next()
.ok_or("invalid_instruction")?;
let csi_index = captures[1].parse::<usize>();
let first_field = captures[2].parse::<usize>();
let second_field = captures[3].parse::<usize>();
if csi_index.is_err() || first_field.is_err() || second_field.is_err() {
return Err("invalid_instruction");
}
match csi_index {
Ok(4) => {
// text area size
Ok(PixelDimensionsOrKeys::PixelDimensions(PixelDimensions {
character_cell_size: None,
text_area_size: Some(SizeInPixels {
height: first_field.unwrap(),
width: second_field.unwrap(),
}),
}))
}
Ok(6) => {
// character cell size
Ok(PixelDimensionsOrKeys::PixelDimensions(PixelDimensions {
character_cell_size: Some(SizeInPixels {
height: first_field.unwrap(),
width: second_field.unwrap(),
}),
text_area_size: None,
}))
}
_ => Err("invalid sequence"),
}
} else {
Err("invalid sequence")
}
}
}

View file

@ -0,0 +1,199 @@
use zellij_utils::pane_size::SizeInPixels;
use zellij_utils::{ipc::PixelDimensions, lazy_static::lazy_static, regex::Regex};
use zellij_tile::data::{CharOrArrow, Key};
pub struct StdinAnsiParser {
expected_ansi_instructions: usize,
current_buffer: Vec<(Key, Vec<u8>)>,
}
impl StdinAnsiParser {
pub fn new() -> Self {
StdinAnsiParser {
expected_ansi_instructions: 0,
current_buffer: vec![],
}
}
pub fn increment_expected_ansi_instructions(&mut self, to: usize) {
self.expected_ansi_instructions = to;
}
pub fn decrement_expected_ansi_instructions(&mut self, by: usize) {
self.expected_ansi_instructions = self.expected_ansi_instructions.saturating_sub(by);
}
pub fn expected_instructions(&self) -> usize {
self.expected_ansi_instructions
}
pub fn parse(&mut self, key: Key, raw_bytes: Vec<u8>) -> Option<AnsiStdinInstructionOrKeys> {
if let Key::Char('t') = key {
self.current_buffer.push((key, raw_bytes));
match AnsiStdinInstructionOrKeys::pixel_dimensions_from_keys(&self.current_buffer) {
Ok(pixel_instruction) => {
self.decrement_expected_ansi_instructions(1);
self.current_buffer.clear();
Some(pixel_instruction)
}
Err(_) => {
self.expected_ansi_instructions = 0;
Some(AnsiStdinInstructionOrKeys::Keys(
self.current_buffer.drain(..).collect(),
))
}
}
} else if let Key::Alt(CharOrArrow::Char('\\')) = key {
match AnsiStdinInstructionOrKeys::color_sequence_from_keys(&self.current_buffer) {
Ok(color_instruction) => {
self.decrement_expected_ansi_instructions(1);
self.current_buffer.clear();
Some(color_instruction)
}
Err(_) => {
self.expected_ansi_instructions = 0;
Some(AnsiStdinInstructionOrKeys::Keys(
self.current_buffer.drain(..).collect(),
))
}
}
} else if self.key_is_valid(key) {
self.current_buffer.push((key, raw_bytes));
None
} else {
self.current_buffer.push((key, raw_bytes));
self.expected_ansi_instructions = 0;
Some(AnsiStdinInstructionOrKeys::Keys(
self.current_buffer.drain(..).collect(),
))
}
}
fn key_is_valid(&self, key: Key) -> bool {
if self.current_buffer.is_empty()
&& (key != Key::Esc && key != Key::Alt(CharOrArrow::Char(']')))
{
// the first key of a sequence is always Esc, but termwiz interprets esc + ] as Alt+]
return false;
}
match key {
Key::Esc => {
// this is a UX improvement
// in case the user's terminal doesn't support one or more of these signals,
// if they spam ESC they need to be able to get back to normal mode and not "us
// waiting for ansi instructions" mode
!self.current_buffer.iter().any(|(key, _)| *key == Key::Esc)
}
Key::Char(';')
| Key::Char('[')
| Key::Char(']')
| Key::Char('r')
| Key::Char('g')
| Key::Char('b')
| Key::Char('\\')
| Key::Char(':')
| Key::Char('/') => true,
Key::Alt(CharOrArrow::Char(']')) => true,
Key::Alt(CharOrArrow::Char('\\')) => true,
Key::Char(c) => {
if let '0'..='9' | 'a'..='f' = c {
true
} else {
false
}
}
_ => false,
}
}
}
#[derive(Debug)]
pub enum AnsiStdinInstructionOrKeys {
PixelDimensions(PixelDimensions),
BackgroundColor(String),
ForegroundColor(String),
Keys(Vec<(Key, Vec<u8>)>),
}
impl AnsiStdinInstructionOrKeys {
pub fn pixel_dimensions_from_keys(keys: &Vec<(Key, Vec<u8>)>) -> Result<Self, &'static str> {
lazy_static! {
static ref RE: Regex = Regex::new(r"^\u{1b}\[(\d+);(\d+);(\d+)t$").unwrap();
}
let key_sequence: Vec<Option<char>> = keys
.iter()
.map(|(key, _)| match key {
Key::Char(c) => Some(*c),
Key::Esc => Some('\u{1b}'),
_ => None,
})
.collect();
if key_sequence.iter().all(|k| k.is_some()) {
let key_string: String = key_sequence.iter().map(|k| k.unwrap()).collect();
let captures = RE
.captures_iter(&key_string)
.next()
.ok_or("invalid_instruction")?;
let csi_index = captures[1].parse::<usize>();
let first_field = captures[2].parse::<usize>();
let second_field = captures[3].parse::<usize>();
if csi_index.is_err() || first_field.is_err() || second_field.is_err() {
return Err("invalid_instruction");
}
match csi_index {
Ok(4) => {
// text area size
Ok(AnsiStdinInstructionOrKeys::PixelDimensions(
PixelDimensions {
character_cell_size: None,
text_area_size: Some(SizeInPixels {
height: first_field.unwrap(),
width: second_field.unwrap(),
}),
},
))
}
Ok(6) => {
// character cell size
Ok(AnsiStdinInstructionOrKeys::PixelDimensions(
PixelDimensions {
character_cell_size: Some(SizeInPixels {
height: first_field.unwrap(),
width: second_field.unwrap(),
}),
text_area_size: None,
},
))
}
_ => Err("invalid sequence"),
}
} else {
Err("invalid sequence")
}
}
pub fn color_sequence_from_keys(keys: &Vec<(Key, Vec<u8>)>) -> Result<Self, &'static str> {
lazy_static! {
static ref BACKGROUND_RE: Regex = Regex::new(r"11;(.*)$").unwrap();
}
lazy_static! {
static ref FOREGROUND_RE: Regex = Regex::new(r"10;(.*)$").unwrap();
}
let key_string = keys.iter().fold(String::new(), |mut acc, (key, _)| {
match key {
Key::Char(c) => acc.push(*c),
_ => {}
};
acc
});
if let Some(captures) = BACKGROUND_RE.captures_iter(&key_string).next() {
let background_query_response = captures[1].parse::<String>();
Ok(AnsiStdinInstructionOrKeys::BackgroundColor(
background_query_response.unwrap(),
))
} else if let Some(captures) = FOREGROUND_RE.captures_iter(&key_string).next() {
let foreground_query_response = captures[1].parse::<String>();
Ok(AnsiStdinInstructionOrKeys::ForegroundColor(
foreground_query_response.unwrap(),
))
} else {
Err("invalid_instruction")
}
}
}

View file

@ -81,8 +81,8 @@ impl FakeStdoutWriter {
} }
} }
impl io::Write for FakeStdoutWriter { impl io::Write for FakeStdoutWriter {
fn write(&mut self, mut buf: &[u8]) -> Result<usize, io::Error> { fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
self.buffer.lock().unwrap().extend_from_slice(&mut buf); self.buffer.lock().unwrap().extend_from_slice(buf);
Ok(buf.len()) Ok(buf.len())
} }
fn flush(&mut self) -> Result<(), io::Error> { fn flush(&mut self) -> Result<(), io::Error> {
@ -188,7 +188,7 @@ fn extract_pixel_events_sent_to_server(
let events_sent_to_server = events_sent_to_server.lock().unwrap(); let events_sent_to_server = events_sent_to_server.lock().unwrap();
events_sent_to_server.iter().fold(vec![], |mut acc, event| { events_sent_to_server.iter().fold(vec![], |mut acc, event| {
if let ClientToServerMsg::TerminalPixelDimensions(pixel_dimensions) = event { if let ClientToServerMsg::TerminalPixelDimensions(pixel_dimensions) = event {
acc.push(pixel_dimensions.clone()); acc.push(*pixel_dimensions);
} }
acc acc
}) })
@ -319,8 +319,7 @@ pub fn pixel_info_queried_from_terminal_emulator() {
let events_sent_to_server = Arc::new(Mutex::new(vec![])); let events_sent_to_server = Arc::new(Mutex::new(vec![]));
let command_is_executing = CommandIsExecuting::new(); let command_is_executing = CommandIsExecuting::new();
let client_os_api = let client_os_api = FakeClientOsApi::new(events_sent_to_server, command_is_executing.clone());
FakeClientOsApi::new(events_sent_to_server.clone(), command_is_executing.clone());
let config = Config::from_default_assets().unwrap(); let config = Config::from_default_assets().unwrap();
let options = Options::default(); let options = Options::default();
@ -353,7 +352,9 @@ pub fn pixel_info_queried_from_terminal_emulator() {
let extracted_stdout_buffer = client_os_api_clone.stdout_buffer(); let extracted_stdout_buffer = client_os_api_clone.stdout_buffer();
assert_eq!( assert_eq!(
String::from_utf8(extracted_stdout_buffer), String::from_utf8(extracted_stdout_buffer),
Ok(String::from("\u{1b}[14t\u{1b}[16t")), Ok(String::from(
"\u{1b}[14t\u{1b}[16t\u{1b}]11;?\u{1b}\\\u{1b}]10;?\u{1b}\\"
)),
); );
} }
@ -465,8 +466,7 @@ pub fn pixel_info_sent_to_server() {
receive_input_instructions, receive_input_instructions,
); );
let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone()); let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone());
let pixel_events_sent_to_server = let pixel_events_sent_to_server = extract_pixel_events_sent_to_server(events_sent_to_server);
extract_pixel_events_sent_to_server(events_sent_to_server.clone());
assert_eq!(actions_sent_to_server, vec![Action::Quit]); assert_eq!(actions_sent_to_server, vec![Action::Quit]);
assert_eq!( assert_eq!(
pixel_events_sent_to_server, pixel_events_sent_to_server,
@ -588,8 +588,7 @@ pub fn corrupted_pixel_info_sent_as_key_events() {
receive_input_instructions, receive_input_instructions,
); );
let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone()); let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone());
let pixel_events_sent_to_server = let pixel_events_sent_to_server = extract_pixel_events_sent_to_server(events_sent_to_server);
extract_pixel_events_sent_to_server(events_sent_to_server.clone());
assert_eq!( assert_eq!(
actions_sent_to_server, actions_sent_to_server,
vec![ vec![
@ -716,8 +715,7 @@ pub fn esc_in_the_middle_of_pixelinfo_breaks_out_of_it() {
receive_input_instructions, receive_input_instructions,
); );
let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone()); let actions_sent_to_server = extract_actions_sent_to_server(events_sent_to_server.clone());
let pixel_events_sent_to_server = let pixel_events_sent_to_server = extract_pixel_events_sent_to_server(events_sent_to_server);
extract_pixel_events_sent_to_server(events_sent_to_server.clone());
assert_eq!( assert_eq!(
actions_sent_to_server, actions_sent_to_server,
vec![ vec![

View file

@ -287,7 +287,7 @@ pub struct Grid {
scroll_region: Option<(usize, usize)>, scroll_region: Option<(usize, usize)>,
active_charset: CharsetIndex, active_charset: CharsetIndex,
preceding_char: Option<TerminalCharacter>, preceding_char: Option<TerminalCharacter>,
colors: Palette, terminal_emulator_colors: Rc<RefCell<Palette>>,
output_buffer: OutputBuffer, output_buffer: OutputBuffer,
title_stack: Vec<String>, title_stack: Vec<String>,
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>, character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
@ -328,7 +328,7 @@ impl Grid {
pub fn new( pub fn new(
rows: usize, rows: usize,
columns: usize, columns: usize,
colors: Palette, terminal_emulator_colors: Rc<RefCell<Palette>>,
link_handler: Rc<RefCell<LinkHandler>>, link_handler: Rc<RefCell<LinkHandler>>,
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>, character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
) -> Self { ) -> Self {
@ -357,7 +357,7 @@ impl Grid {
clear_viewport_before_rendering: false, clear_viewport_before_rendering: false,
active_charset: Default::default(), active_charset: Default::default(),
pending_messages_to_pty: vec![], pending_messages_to_pty: vec![],
colors, terminal_emulator_colors,
output_buffer: Default::default(), output_buffer: Default::default(),
selection: Default::default(), selection: Default::default(),
title_stack: vec![], title_stack: vec![],
@ -1553,16 +1553,23 @@ impl Perform for Grid {
self.link_handler.borrow_mut().dispatch_osc8(params); self.link_handler.borrow_mut().dispatch_osc8(params);
} }
// Get/set Foreground, Background, Cursor colors. // Get/set Foreground (b"10") or background (b"11") colors
b"10" | b"11" | b"12" => { b"10" | b"11" => {
if params.len() >= 2 { if params.len() >= 2 {
if let Some(mut dynamic_code) = parse_number(params[0]) { if let Some(mut dynamic_code) = parse_number(params[0]) {
for param in &params[1..] { for param in &params[1..] {
// currently only getting the color sequence is supported, // currently only getting the color sequence is supported,
// setting still isn't // setting still isn't
if param == b"?" { if param == b"?" {
let color_response_message = match self.colors.bg { let saved_terminal_color = if dynamic_code == 10 {
PaletteColor::Rgb((r, g, b)) => { Some(self.terminal_emulator_colors.borrow().fg)
} else if dynamic_code == 11 {
Some(self.terminal_emulator_colors.borrow().bg)
} else {
None
};
let color_response_message = match saved_terminal_color {
Some(PaletteColor::Rgb((r, g, b))) => {
format!( format!(
"\u{1b}]{};rgb:{1:02x}{1:02x}/{2:02x}{2:02x}/{3:02x}{3:02x}{4}", "\u{1b}]{};rgb:{1:02x}{1:02x}/{2:02x}{2:02x}/{3:02x}{3:02x}{4}",
// dynamic_code, color.r, color.g, color.b, terminator // dynamic_code, color.r, color.g, color.b, terminator
@ -1586,6 +1593,10 @@ impl Perform for Grid {
} }
} }
b"12" => {
// get/set cursor color currently unimplemented
}
// Set cursor style. // Set cursor style.
b"50" => { b"50" => {
if params.len() >= 2 if params.len() >= 2

View file

@ -1,4 +1,4 @@
mod alacritty_functions; pub mod alacritty_functions;
mod floating_panes; mod floating_panes;
pub mod grid; pub mod grid;
pub mod link_handler; pub mod link_handler;

View file

@ -21,7 +21,7 @@ use zellij_utils::{
position::Position, position::Position,
shared::make_terminal_title, shared::make_terminal_title,
vte, vte,
zellij_tile::data::{InputMode, PaletteColor}, zellij_tile::data::{InputMode, Palette, PaletteColor},
}; };
pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10; pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10;
@ -489,12 +489,13 @@ impl TerminalPane {
pane_name: String, pane_name: String,
link_handler: Rc<RefCell<LinkHandler>>, link_handler: Rc<RefCell<LinkHandler>>,
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>, character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
terminal_emulator_colors: Rc<RefCell<Palette>>,
) -> TerminalPane { ) -> TerminalPane {
let initial_pane_title = format!("Pane #{}", pane_index); let initial_pane_title = format!("Pane #{}", pane_index);
let grid = Grid::new( let grid = Grid::new(
position_and_size.rows.as_usize(), position_and_size.rows.as_usize(),
position_and_size.cols.as_usize(), position_and_size.cols.as_usize(),
style.colors, terminal_emulator_colors,
link_handler, link_handler,
character_cell_size, character_cell_size,
); );

View file

@ -21,7 +21,7 @@ fn vttest1_0() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -39,7 +39,7 @@ fn vttest1_1() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -57,7 +57,7 @@ fn vttest1_2() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -75,7 +75,7 @@ fn vttest1_3() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -93,7 +93,7 @@ fn vttest1_4() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -111,7 +111,7 @@ fn vttest1_5() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -129,7 +129,7 @@ fn vttest2_0() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -147,7 +147,7 @@ fn vttest2_1() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -165,7 +165,7 @@ fn vttest2_2() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -183,7 +183,7 @@ fn vttest2_3() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -201,7 +201,7 @@ fn vttest2_4() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -219,7 +219,7 @@ fn vttest2_5() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -237,7 +237,7 @@ fn vttest2_6() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -255,7 +255,7 @@ fn vttest2_7() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -273,7 +273,7 @@ fn vttest2_8() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -291,7 +291,7 @@ fn vttest2_9() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -309,7 +309,7 @@ fn vttest2_10() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -327,7 +327,7 @@ fn vttest2_11() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -345,7 +345,7 @@ fn vttest2_12() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -363,7 +363,7 @@ fn vttest2_13() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -381,7 +381,7 @@ fn vttest2_14() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -399,7 +399,7 @@ fn vttest3_0() {
let mut grid = Grid::new( let mut grid = Grid::new(
41, 41,
110, 110,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -417,7 +417,7 @@ fn vttest8_0() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -435,7 +435,7 @@ fn vttest8_1() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -453,7 +453,7 @@ fn vttest8_2() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -471,7 +471,7 @@ fn vttest8_3() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -489,7 +489,7 @@ fn vttest8_4() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -507,7 +507,7 @@ fn vttest8_5() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -525,7 +525,7 @@ fn csi_b() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -543,7 +543,7 @@ fn csi_capital_i() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -561,7 +561,7 @@ fn csi_capital_z() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -579,7 +579,7 @@ fn terminal_reports() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -597,7 +597,7 @@ fn wide_characters() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -615,7 +615,7 @@ fn wide_characters_line_wrap() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -633,7 +633,7 @@ fn insert_character_in_line_with_wide_character() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -651,7 +651,7 @@ fn delete_char_in_middle_of_line_with_widechar() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -669,7 +669,7 @@ fn delete_char_in_middle_of_line_with_multiple_widechars() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -687,7 +687,7 @@ fn fish_wide_characters_override_clock() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -705,7 +705,7 @@ fn bash_delete_wide_characters() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -723,7 +723,7 @@ fn delete_wide_characters_before_cursor() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -741,7 +741,7 @@ fn delete_wide_characters_before_cursor_when_cursor_is_on_wide_character() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -759,7 +759,7 @@ fn delete_wide_character_under_cursor() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -777,7 +777,7 @@ fn replace_wide_character_under_cursor() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
104, 104,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -795,7 +795,7 @@ fn wrap_wide_characters() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
90, 90,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -813,7 +813,7 @@ fn wrap_wide_characters_on_size_change() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
93, 93,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -832,7 +832,7 @@ fn unwrap_wide_characters_on_size_change() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
93, 93,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -852,7 +852,7 @@ fn wrap_wide_characters_in_the_middle_of_the_line() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
91, 91,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -870,7 +870,7 @@ fn wrap_wide_characters_at_the_end_of_the_line() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
90, 90,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -888,7 +888,7 @@ fn copy_selected_text_from_viewport() {
let mut grid = Grid::new( let mut grid = Grid::new(
27, 27,
125, 125,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -914,7 +914,7 @@ fn copy_wrapped_selected_text_from_viewport() {
let mut grid = Grid::new( let mut grid = Grid::new(
22, 22,
73, 73,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -939,7 +939,7 @@ fn copy_selected_text_from_lines_above() {
let mut grid = Grid::new( let mut grid = Grid::new(
27, 27,
125, 125,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -965,7 +965,7 @@ fn copy_selected_text_from_lines_below() {
let mut grid = Grid::new( let mut grid = Grid::new(
27, 27,
125, 125,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -999,7 +999,7 @@ fn run_bandwhich_from_fish_shell() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1017,7 +1017,7 @@ fn fish_tab_completion_options() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1040,7 +1040,7 @@ pub fn fish_select_tab_completion_options() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1066,7 +1066,7 @@ pub fn vim_scroll_region_down() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1090,7 +1090,7 @@ pub fn vim_ctrl_d() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1113,7 +1113,7 @@ pub fn vim_ctrl_u() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1131,7 +1131,7 @@ pub fn htop() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1149,7 +1149,7 @@ pub fn htop_scrolling() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1167,7 +1167,7 @@ pub fn htop_right_scrolling() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1193,7 +1193,7 @@ pub fn vim_overwrite() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1213,7 +1213,7 @@ pub fn clear_scroll_region() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1231,7 +1231,7 @@ pub fn display_tab_characters_properly() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1249,7 +1249,7 @@ pub fn neovim_insert_mode() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1267,7 +1267,7 @@ pub fn bash_cursor_linewrap() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
116, 116,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1287,7 +1287,7 @@ pub fn fish_paste_multiline() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
149, 149,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1305,7 +1305,7 @@ pub fn git_log() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
149, 149,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1325,7 +1325,7 @@ pub fn git_diff_scrollup() {
let mut grid = Grid::new( let mut grid = Grid::new(
28, 28,
149, 149,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1343,7 +1343,7 @@ pub fn emacs_longbuf() {
let mut grid = Grid::new( let mut grid = Grid::new(
60, 60,
284, 284,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1361,7 +1361,7 @@ pub fn top_and_quit() {
let mut grid = Grid::new( let mut grid = Grid::new(
56, 56,
235, 235,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1385,7 +1385,7 @@ pub fn exa_plus_omf_theme() {
let mut grid = Grid::new( let mut grid = Grid::new(
56, 56,
235, 235,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1403,7 +1403,7 @@ pub fn scroll_up() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
50, 50,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1422,7 +1422,7 @@ pub fn scroll_down() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
50, 50,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1442,7 +1442,7 @@ pub fn scroll_up_with_line_wraps() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
25, 25,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1461,7 +1461,7 @@ pub fn scroll_down_with_line_wraps() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
25, 25,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1481,7 +1481,7 @@ pub fn scroll_up_decrease_width_and_scroll_down() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
50, 50,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1506,7 +1506,7 @@ pub fn scroll_up_increase_width_and_scroll_down() {
let mut grid = Grid::new( let mut grid = Grid::new(
10, 10,
25, 25,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1531,7 +1531,7 @@ pub fn move_cursor_below_scroll_region() {
let mut grid = Grid::new( let mut grid = Grid::new(
34, 34,
114, 114,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1549,7 +1549,7 @@ pub fn insert_wide_characters_in_existing_line() {
let mut grid = Grid::new( let mut grid = Grid::new(
21, 21,
86, 86,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1572,7 +1572,7 @@ pub fn full_screen_scroll_region_and_scroll_up() {
let mut grid = Grid::new( let mut grid = Grid::new(
54, 54,
80, 80,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1593,7 +1593,7 @@ pub fn ring_bell() {
let mut grid = Grid::new( let mut grid = Grid::new(
134, 134,
64, 64,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1611,7 +1611,7 @@ pub fn alternate_screen_change_size() {
let mut grid = Grid::new( let mut grid = Grid::new(
20, 20,
20, 20,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1633,7 +1633,7 @@ pub fn fzf_fullscreen() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1655,7 +1655,7 @@ pub fn replace_multiple_wide_characters_under_cursor() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1677,7 +1677,7 @@ pub fn replace_non_wide_characters_with_wide_characters() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1695,7 +1695,7 @@ pub fn scroll_down_ansi() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1713,7 +1713,7 @@ pub fn ansi_capital_t() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1730,7 +1730,7 @@ pub fn ansi_capital_s() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -1747,7 +1747,7 @@ fn terminal_pixel_size_reports() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(Some(SizeInPixels { Rc::new(RefCell::new(Some(SizeInPixels {
height: 21, height: 21,
@ -1774,7 +1774,7 @@ fn terminal_pixel_size_reports_in_unsupported_terminals() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
97, 97,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), // in an unsupported terminal, we don't have this info Rc::new(RefCell::new(None)), // in an unsupported terminal, we don't have this info
); );
@ -1799,7 +1799,7 @@ pub fn ansi_csi_at_sign() {
let mut grid = Grid::new( let mut grid = Grid::new(
51, 51,
112, 112,
Palette::default(), Rc::new(RefCell::new(Palette::default())),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );

View file

@ -4,6 +4,7 @@ use crate::tab::Pane;
use ::insta::assert_snapshot; use ::insta::assert_snapshot;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use zellij_tile::data::Palette;
use zellij_tile::prelude::Style; use zellij_tile::prelude::Style;
use zellij_utils::pane_size::PaneGeom; use zellij_utils::pane_size::PaneGeom;
@ -26,6 +27,7 @@ pub fn scrolling_inside_a_pane() {
String::new(), String::new(),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
Rc::new(RefCell::new(Palette::default())),
); // 0 is the pane index ); // 0 is the pane index
let mut text_to_fill_pane = String::new(); let mut text_to_fill_pane = String::new();
for i in 0..30 { for i in 0..30 {

View file

@ -449,6 +449,26 @@ pub(crate) fn route_thread_main(
)) ))
.unwrap(); .unwrap();
} }
ClientToServerMsg::BackgroundColor(background_color_instruction) => {
rlocked_sessions
.as_ref()
.unwrap()
.senders
.send_to_screen(ScreenInstruction::TerminalBackgroundColor(
background_color_instruction,
))
.unwrap();
}
ClientToServerMsg::ForegroundColor(foreground_color_instruction) => {
rlocked_sessions
.as_ref()
.unwrap()
.senders
.send_to_screen(ScreenInstruction::TerminalForegroundColor(
foreground_color_instruction,
))
.unwrap();
}
ClientToServerMsg::NewClient( ClientToServerMsg::NewClient(
client_attributes, client_attributes,
cli_args, cli_args,

View file

@ -6,6 +6,7 @@ use std::os::unix::io::RawFd;
use std::rc::Rc; use std::rc::Rc;
use std::str; use std::str;
use zellij_tile::data::{Palette, PaletteColor};
use zellij_tile::prelude::Style; use zellij_tile::prelude::Style;
use zellij_utils::input::options::Clipboard; use zellij_utils::input::options::Clipboard;
use zellij_utils::pane_size::{Size, SizeInPixels}; use zellij_utils::pane_size::{Size, SizeInPixels};
@ -13,6 +14,9 @@ use zellij_utils::{
input::command::TerminalAction, input::layout::Layout, position::Position, zellij_tile, input::command::TerminalAction, input::layout::Layout, position::Position, zellij_tile,
}; };
use crate::panes::alacritty_functions::xparse_color;
use crate::panes::terminal_character::AnsiCode;
use crate::{ use crate::{
output::Output, output::Output,
panes::PaneId, panes::PaneId,
@ -88,6 +92,8 @@ pub enum ScreenInstruction {
UpdateTabName(Vec<u8>, ClientId), UpdateTabName(Vec<u8>, ClientId),
TerminalResize(Size), TerminalResize(Size),
TerminalPixelDimensions(PixelDimensions), TerminalPixelDimensions(PixelDimensions),
TerminalBackgroundColor(String),
TerminalForegroundColor(String),
ChangeMode(ModeInfo, ClientId), ChangeMode(ModeInfo, ClientId),
LeftClick(Position, ClientId), LeftClick(Position, ClientId),
RightClick(Position, ClientId), RightClick(Position, ClientId),
@ -166,6 +172,12 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::TerminalPixelDimensions(..) => { ScreenInstruction::TerminalPixelDimensions(..) => {
ScreenContext::TerminalPixelDimensions ScreenContext::TerminalPixelDimensions
} }
ScreenInstruction::TerminalBackgroundColor(..) => {
ScreenContext::TerminalBackgroundColor
}
ScreenInstruction::TerminalForegroundColor(..) => {
ScreenContext::TerminalForegroundColor
}
ScreenInstruction::ChangeMode(..) => ScreenContext::ChangeMode, ScreenInstruction::ChangeMode(..) => ScreenContext::ChangeMode,
ScreenInstruction::ToggleActiveSyncTab(..) => ScreenContext::ToggleActiveSyncTab, ScreenInstruction::ToggleActiveSyncTab(..) => ScreenContext::ToggleActiveSyncTab,
ScreenInstruction::ScrollUpAt(..) => ScreenContext::ScrollUpAt, ScreenInstruction::ScrollUpAt(..) => ScreenContext::ScrollUpAt,
@ -231,6 +243,7 @@ pub(crate) struct Screen {
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>, character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
/// The overlay that is drawn on top of [`Pane`]'s', [`Tab`]'s and the [`Screen`] /// The overlay that is drawn on top of [`Pane`]'s', [`Tab`]'s and the [`Screen`]
overlay: OverlayWindow, overlay: OverlayWindow,
terminal_emulator_colors: Rc<RefCell<Palette>>,
connected_clients: Rc<RefCell<HashSet<ClientId>>>, connected_clients: Rc<RefCell<HashSet<ClientId>>>,
/// The indices of this [`Screen`]'s active [`Tab`]s. /// The indices of this [`Screen`]'s active [`Tab`]s.
active_tab_indices: BTreeMap<ClientId, usize>, active_tab_indices: BTreeMap<ClientId, usize>,
@ -265,6 +278,7 @@ impl Screen {
active_tab_indices: BTreeMap::new(), active_tab_indices: BTreeMap::new(),
tabs: BTreeMap::new(), tabs: BTreeMap::new(),
overlay: OverlayWindow::default(), overlay: OverlayWindow::default(),
terminal_emulator_colors: Rc::new(RefCell::new(Palette::default())),
tab_history: BTreeMap::new(), tab_history: BTreeMap::new(),
mode_info: BTreeMap::new(), mode_info: BTreeMap::new(),
default_mode_info: mode_info, default_mode_info: mode_info,
@ -482,6 +496,22 @@ impl Screen {
*self.character_cell_size.borrow_mut() = Some(character_cell_size); *self.character_cell_size.borrow_mut() = Some(character_cell_size);
} }
} }
pub fn update_terminal_background_color(&mut self, background_color_instruction: String) {
if let Some(AnsiCode::RgbCode((r, g, b))) =
xparse_color(background_color_instruction.as_bytes())
{
let bg_palette_color = PaletteColor::Rgb((r, g, b));
self.terminal_emulator_colors.borrow_mut().bg = bg_palette_color;
}
}
pub fn update_terminal_foreground_color(&mut self, foreground_color_instruction: String) {
if let Some(AnsiCode::RgbCode((r, g, b))) =
xparse_color(foreground_color_instruction.as_bytes())
{
let fg_palette_color = PaletteColor::Rgb((r, g, b));
self.terminal_emulator_colors.borrow_mut().fg = fg_palette_color;
}
}
/// Renders this [`Screen`], which amounts to rendering its active [`Tab`]. /// Renders this [`Screen`], which amounts to rendering its active [`Tab`].
pub fn render(&mut self) { pub fn render(&mut self) {
@ -573,6 +603,7 @@ impl Screen {
self.session_is_mirrored, self.session_is_mirrored,
client_id, client_id,
self.copy_options.clone(), self.copy_options.clone(),
self.terminal_emulator_colors.clone(),
); );
tab.apply_layout(layout, new_pids, tab_index, client_id); tab.apply_layout(layout, new_pids, tab_index, client_id);
if self.session_is_mirrored { if self.session_is_mirrored {
@ -1309,6 +1340,12 @@ pub(crate) fn screen_thread_main(
ScreenInstruction::TerminalPixelDimensions(pixel_dimensions) => { ScreenInstruction::TerminalPixelDimensions(pixel_dimensions) => {
screen.update_pixel_dimensions(pixel_dimensions); screen.update_pixel_dimensions(pixel_dimensions);
} }
ScreenInstruction::TerminalBackgroundColor(background_color_instruction) => {
screen.update_terminal_background_color(background_color_instruction);
}
ScreenInstruction::TerminalForegroundColor(background_color_instruction) => {
screen.update_terminal_foreground_color(background_color_instruction);
}
ScreenInstruction::ChangeMode(mode_info, client_id) => { ScreenInstruction::ChangeMode(mode_info, client_id) => {
screen.change_mode(mode_info, client_id); screen.change_mode(mode_info, client_id);

View file

@ -90,6 +90,7 @@ pub(crate) struct Tab {
// it seems that optimization is possible using `active_panes` // it seems that optimization is possible using `active_panes`
focus_pane_id: Option<PaneId>, focus_pane_id: Option<PaneId>,
copy_on_select: bool, copy_on_select: bool,
terminal_emulator_colors: Rc<RefCell<Palette>>,
} }
#[derive(Clone, Debug, Default, Serialize, Deserialize)] #[derive(Clone, Debug, Default, Serialize, Deserialize)]
@ -283,6 +284,7 @@ impl Tab {
session_is_mirrored: bool, session_is_mirrored: bool,
client_id: ClientId, client_id: ClientId,
copy_options: CopyOptions, copy_options: CopyOptions,
terminal_emulator_colors: Rc<RefCell<Palette>>,
) -> Self { ) -> Self {
let name = if name.is_empty() { let name = if name.is_empty() {
format!("Tab #{}", index + 1) format!("Tab #{}", index + 1)
@ -352,6 +354,7 @@ impl Tab {
clipboard_provider, clipboard_provider,
focus_pane_id: None, focus_pane_id: None,
copy_on_select: copy_options.copy_on_select, copy_on_select: copy_options.copy_on_select,
terminal_emulator_colors,
} }
} }
@ -419,6 +422,7 @@ impl Tab {
layout.pane_name.clone().unwrap_or_default(), layout.pane_name.clone().unwrap_or_default(),
self.link_handler.clone(), self.link_handler.clone(),
self.character_cell_size.clone(), self.character_cell_size.clone(),
self.terminal_emulator_colors.clone(),
); );
new_pane.set_borderless(layout.borderless); new_pane.set_borderless(layout.borderless);
self.tiled_panes self.tiled_panes
@ -647,6 +651,7 @@ impl Tab {
String::new(), String::new(),
self.link_handler.clone(), self.link_handler.clone(),
self.character_cell_size.clone(), self.character_cell_size.clone(),
self.terminal_emulator_colors.clone(),
); );
new_pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame new_pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame
resize_pty!(new_pane, self.os_api); resize_pty!(new_pane, self.os_api);
@ -669,6 +674,7 @@ impl Tab {
String::new(), String::new(),
self.link_handler.clone(), self.link_handler.clone(),
self.character_cell_size.clone(), self.character_cell_size.clone(),
self.terminal_emulator_colors.clone(),
); );
self.tiled_panes.insert_pane(pid, Box::new(new_terminal)); self.tiled_panes.insert_pane(pid, Box::new(new_terminal));
self.should_clear_display_before_rendering = true; self.should_clear_display_before_rendering = true;
@ -698,6 +704,7 @@ impl Tab {
String::new(), String::new(),
self.link_handler.clone(), self.link_handler.clone(),
self.character_cell_size.clone(), self.character_cell_size.clone(),
self.terminal_emulator_colors.clone(),
); );
self.tiled_panes self.tiled_panes
.split_pane_horizontally(pid, Box::new(new_terminal), client_id); .split_pane_horizontally(pid, Box::new(new_terminal), client_id);
@ -725,6 +732,7 @@ impl Tab {
String::new(), String::new(),
self.link_handler.clone(), self.link_handler.clone(),
self.character_cell_size.clone(), self.character_cell_size.clone(),
self.terminal_emulator_colors.clone(),
); );
self.tiled_panes self.tiled_panes
.split_pane_vertically(pid, Box::new(new_terminal), client_id); .split_pane_vertically(pid, Box::new(new_terminal), client_id);

View file

@ -103,6 +103,7 @@ fn create_new_tab(size: Size) -> Tab {
connected_clients.insert(client_id); connected_clients.insert(client_id);
let connected_clients = Rc::new(RefCell::new(connected_clients)); let connected_clients = Rc::new(RefCell::new(connected_clients));
let character_cell_info = Rc::new(RefCell::new(None)); let character_cell_info = Rc::new(RefCell::new(None));
let terminal_emulator_colors = Rc::new(RefCell::new(Palette::default()));
let copy_options = CopyOptions::default(); let copy_options = CopyOptions::default();
let mut tab = Tab::new( let mut tab = Tab::new(
index, index,
@ -120,6 +121,7 @@ fn create_new_tab(size: Size) -> Tab {
session_is_mirrored, session_is_mirrored,
client_id, client_id,
copy_options, copy_options,
terminal_emulator_colors,
); );
tab.apply_layout( tab.apply_layout(
LayoutTemplate::default().try_into().unwrap(), LayoutTemplate::default().try_into().unwrap(),
@ -149,7 +151,7 @@ fn take_snapshot(ansi_instructions: &str, rows: usize, columns: usize, palette:
let mut grid = Grid::new( let mut grid = Grid::new(
rows, rows,
columns, columns,
palette, Rc::new(RefCell::new(palette)),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );
@ -170,7 +172,7 @@ fn take_snapshot_and_cursor_position(
let mut grid = Grid::new( let mut grid = Grid::new(
rows, rows,
columns, columns,
palette, Rc::new(RefCell::new(palette)),
Rc::new(RefCell::new(LinkHandler::new())), Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)), Rc::new(RefCell::new(None)),
); );

View file

@ -99,6 +99,7 @@ fn create_new_tab(size: Size) -> Tab {
let character_cell_info = Rc::new(RefCell::new(None)); let character_cell_info = Rc::new(RefCell::new(None));
connected_clients.insert(client_id); connected_clients.insert(client_id);
let connected_clients = Rc::new(RefCell::new(connected_clients)); let connected_clients = Rc::new(RefCell::new(connected_clients));
let terminal_emulator_colors = Rc::new(RefCell::new(Palette::default()));
let copy_options = CopyOptions::default(); let copy_options = CopyOptions::default();
let mut tab = Tab::new( let mut tab = Tab::new(
index, index,
@ -116,6 +117,7 @@ fn create_new_tab(size: Size) -> Tab {
session_is_mirrored, session_is_mirrored,
client_id, client_id,
copy_options, copy_options,
terminal_emulator_colors,
); );
tab.apply_layout( tab.apply_layout(
LayoutTemplate::default().try_into().unwrap(), LayoutTemplate::default().try_into().unwrap(),
@ -144,6 +146,7 @@ fn create_new_tab_with_cell_size(
let mut connected_clients = HashSet::new(); let mut connected_clients = HashSet::new();
connected_clients.insert(client_id); connected_clients.insert(client_id);
let connected_clients = Rc::new(RefCell::new(connected_clients)); let connected_clients = Rc::new(RefCell::new(connected_clients));
let terminal_emulator_colors = Rc::new(RefCell::new(Palette::default()));
let copy_options = CopyOptions::default(); let copy_options = CopyOptions::default();
let mut tab = Tab::new( let mut tab = Tab::new(
index, index,
@ -161,6 +164,7 @@ fn create_new_tab_with_cell_size(
session_is_mirrored, session_is_mirrored,
client_id, client_id,
copy_options, copy_options,
terminal_emulator_colors,
); );
tab.apply_layout( tab.apply_layout(
LayoutTemplate::default().try_into().unwrap(), LayoutTemplate::default().try_into().unwrap(),

View file

@ -268,6 +268,8 @@ pub enum ScreenContext {
UpdateTabName, UpdateTabName,
TerminalResize, TerminalResize,
TerminalPixelDimensions, TerminalPixelDimensions,
TerminalBackgroundColor,
TerminalForegroundColor,
ChangeMode, ChangeMode,
LeftClick, LeftClick,
RightClick, RightClick,

View file

@ -75,6 +75,8 @@ pub enum ClientToServerMsg {
// Disconnect from the session we're connected to // Disconnect from the session we're connected to
DisconnectFromSession,*/ DisconnectFromSession,*/
TerminalPixelDimensions(PixelDimensions), TerminalPixelDimensions(PixelDimensions),
BackgroundColor(String),
ForegroundColor(String),
TerminalResize(Size), TerminalResize(Size),
NewClient( NewClient(
ClientAttributes, ClientAttributes,