use serde::{Deserialize, Serialize}; use zellij_utils::{input::config::Config, pane_size::Size}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct WebClientToWebServerControlMessage { pub web_client_id: String, pub payload: WebClientToWebServerControlMessagePayload, } #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type")] pub enum WebClientToWebServerControlMessagePayload { TerminalResize(Size), TerminalResizeRendering(Size), TerminalSizeSettled(Size), TerminalMetrics(TerminalMetricsPayload), SoftKeyboardVisibilityChanged { visible: bool }, NestedSessionFrameFromHost { payload_bytes: Vec }, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TerminalMetricsPayload { pub cell_pixel_width: usize, pub cell_pixel_height: usize, pub text_area_pixel_width: usize, pub text_area_pixel_height: usize, } #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(tag = "type")] pub enum WebServerToWebClientControlMessage { SetConfig(SetConfigPayload), QueryTerminalSize, Log { lines: Vec }, LogError { lines: Vec }, SwitchedSession { new_session_name: String }, SetSoftKeyboard { on: bool }, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SetConfigPayload { pub font: String, pub theme: SetConfigPayloadTheme, pub cursor_blink: bool, #[serde(skip_serializing_if = "Option::is_none")] pub cursor_inactive_style: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cursor_style: Option, pub mac_option_is_meta: bool, #[serde(skip_serializing_if = "Option::is_none")] pub font_size: Option, } #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct SetConfigPayloadTheme { #[serde(skip_serializing_if = "Option::is_none")] pub background: Option, #[serde(skip_serializing_if = "Option::is_none")] pub foreground: Option, #[serde(skip_serializing_if = "Option::is_none")] pub black: Option, #[serde(skip_serializing_if = "Option::is_none")] pub blue: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_black: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_blue: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_cyan: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_green: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_magenta: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_red: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_white: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bright_yellow: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cursor: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cursor_accent: Option, #[serde(skip_serializing_if = "Option::is_none")] pub cyan: Option, #[serde(skip_serializing_if = "Option::is_none")] pub green: Option, #[serde(skip_serializing_if = "Option::is_none")] pub magenta: Option, #[serde(skip_serializing_if = "Option::is_none")] pub red: Option, #[serde(skip_serializing_if = "Option::is_none")] pub selection_background: Option, #[serde(skip_serializing_if = "Option::is_none")] pub selection_foreground: Option, #[serde(skip_serializing_if = "Option::is_none")] pub selection_inactive_background: Option, #[serde(skip_serializing_if = "Option::is_none")] pub white: Option, #[serde(skip_serializing_if = "Option::is_none")] pub yellow: Option, } impl From<&Config> for SetConfigPayload { fn from(config: &Config) -> Self { let font = config.web_client.font.clone(); let palette = config.theme_config(config.options.theme.as_ref()); let web_client_theme_from_config = config.web_client.theme.as_ref(); let mut theme = SetConfigPayloadTheme::default(); theme.background = web_client_theme_from_config .and_then(|theme| theme.background.clone()) .or_else(|| palette.map(|p| p.text_unselected.background.as_rgb_str())); theme.foreground = web_client_theme_from_config .and_then(|theme| theme.foreground.clone()) .or_else(|| palette.map(|p| p.text_unselected.base.as_rgb_str())); theme.black = web_client_theme_from_config.and_then(|theme| theme.black.clone()); theme.blue = web_client_theme_from_config.and_then(|theme| theme.blue.clone()); theme.bright_black = web_client_theme_from_config.and_then(|theme| theme.bright_black.clone()); theme.bright_blue = web_client_theme_from_config.and_then(|theme| theme.bright_blue.clone()); theme.bright_cyan = web_client_theme_from_config.and_then(|theme| theme.bright_cyan.clone()); theme.bright_green = web_client_theme_from_config.and_then(|theme| theme.bright_green.clone()); theme.bright_magenta = web_client_theme_from_config.and_then(|theme| theme.bright_magenta.clone()); theme.bright_red = web_client_theme_from_config.and_then(|theme| theme.bright_red.clone()); theme.bright_white = web_client_theme_from_config.and_then(|theme| theme.bright_white.clone()); theme.bright_yellow = web_client_theme_from_config.and_then(|theme| theme.bright_yellow.clone()); theme.cursor = web_client_theme_from_config.and_then(|theme| theme.cursor.clone()); theme.cursor_accent = web_client_theme_from_config.and_then(|theme| theme.cursor_accent.clone()); theme.cyan = web_client_theme_from_config.and_then(|theme| theme.cyan.clone()); theme.green = web_client_theme_from_config.and_then(|theme| theme.green.clone()); theme.magenta = web_client_theme_from_config.and_then(|theme| theme.magenta.clone()); theme.red = web_client_theme_from_config.and_then(|theme| theme.red.clone()); theme.selection_background = web_client_theme_from_config .and_then(|theme| theme.selection_background.clone()) .or_else(|| palette.map(|p| p.text_selected.background.as_rgb_str())); theme.selection_foreground = web_client_theme_from_config .and_then(|theme| theme.selection_foreground.clone()) .or_else(|| palette.map(|p| p.text_selected.base.as_rgb_str())); theme.selection_inactive_background = web_client_theme_from_config .and_then(|theme| theme.selection_inactive_background.clone()); theme.white = web_client_theme_from_config.and_then(|theme| theme.white.clone()); theme.yellow = web_client_theme_from_config.and_then(|theme| theme.yellow.clone()); let cursor_blink = config.web_client.cursor_blink; let mac_option_is_meta = config.web_client.mac_option_is_meta; let cursor_style = config .web_client .cursor_style .as_ref() .map(|s| s.to_string()); let cursor_inactive_style = config .web_client .cursor_inactive_style .as_ref() .map(|s| s.to_string()); let font_size = config.web_client.font_size; SetConfigPayload { font, theme, cursor_blink, mac_option_is_meta, cursor_style, cursor_inactive_style, font_size, } } }