diff options
Diffstat (limited to 'alacritty/src/config/window.rs')
-rw-r--r-- | alacritty/src/config/window.rs | 198 |
1 files changed, 91 insertions, 107 deletions
diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs index ce36d23c..2d501b91 100644 --- a/alacritty/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -1,82 +1,77 @@ +use std::fmt::{self, Formatter}; use std::os::raw::c_ulong; use glutin::window::Fullscreen; use log::error; +use serde::de::{self, MapAccess, Visitor}; use serde::{Deserialize, Deserializer}; -use serde_yaml::Value; -use alacritty_terminal::config::{failure_default, option_explicit_none, LOG_TARGET_CONFIG}; +use alacritty_config_derive::ConfigDeserialize; +use alacritty_terminal::config::LOG_TARGET_CONFIG; use alacritty_terminal::index::{Column, Line}; -use crate::config::ui_config::{DefaultTrueBool, Delta}; +use crate::config::ui_config::Delta; /// Default Alacritty name, used for window title and class. pub const DEFAULT_NAME: &str = "Alacritty"; -#[serde(default)] -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Clone, PartialEq, Eq)] pub struct WindowConfig { /// Initial position. - #[serde(deserialize_with = "failure_default")] pub position: Option<Delta<i32>>, /// Draw the window with title bar / borders. - #[serde(deserialize_with = "failure_default")] pub decorations: Decorations, /// Startup mode. - #[serde(deserialize_with = "failure_default")] pub startup_mode: StartupMode, - /// Window title. - #[serde(default = "default_title")] - pub title: String, - - /// Window class. - #[serde(deserialize_with = "deserialize_class")] - pub class: Class, - /// XEmbed parent. - #[serde(skip)] + #[config(skip)] pub embed: Option<c_ulong>, /// GTK theme variant. - #[serde(deserialize_with = "option_explicit_none")] pub gtk_theme_variant: Option<String>, /// Spread out additional padding evenly. - #[serde(deserialize_with = "failure_default")] pub dynamic_padding: bool, + /// Use dynamic title. + pub dynamic_title: bool, + + /// Window title. + pub title: String, + + /// Window class. + pub class: Class, + /// Pixel padding. - #[serde(deserialize_with = "failure_default")] padding: Delta<u8>, - /// Use dynamic title. - #[serde(default, deserialize_with = "failure_default")] - dynamic_title: DefaultTrueBool, - /// Initial dimensions. - #[serde(deserialize_with = "failure_default")] dimensions: Dimensions, } -pub fn default_title() -> String { - DEFAULT_NAME.to_string() +impl Default for WindowConfig { + fn default() -> Self { + Self { + dynamic_title: true, + title: DEFAULT_NAME.into(), + position: Default::default(), + decorations: Default::default(), + startup_mode: Default::default(), + embed: Default::default(), + gtk_theme_variant: Default::default(), + dynamic_padding: Default::default(), + class: Default::default(), + padding: Default::default(), + dimensions: Default::default(), + } + } } impl WindowConfig { #[inline] - pub fn dynamic_title(&self) -> bool { - self.dynamic_title.0 - } - - #[inline] - pub fn set_dynamic_title(&mut self, dynamic_title: bool) { - self.dynamic_title.0 = dynamic_title; - } - - #[inline] pub fn dimensions(&self) -> Option<Dimensions> { if self.dimensions.columns.0 != 0 && self.dimensions.lines.0 != 0 @@ -110,25 +105,7 @@ impl WindowConfig { } } -impl Default for WindowConfig { - fn default() -> WindowConfig { - WindowConfig { - dimensions: Default::default(), - position: Default::default(), - padding: Default::default(), - decorations: Default::default(), - dynamic_padding: Default::default(), - startup_mode: Default::default(), - class: Default::default(), - embed: Default::default(), - gtk_theme_variant: Default::default(), - title: default_title(), - dynamic_title: Default::default(), - } - } -} - -#[derive(Debug, Deserialize, Copy, Clone, PartialEq, Eq)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum StartupMode { Windowed, Maximized, @@ -143,17 +120,13 @@ impl Default for StartupMode { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)] +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] pub enum Decorations { - #[serde(rename = "full")] Full, #[cfg(target_os = "macos")] - #[serde(rename = "transparent")] Transparent, #[cfg(target_os = "macos")] - #[serde(rename = "buttonless")] Buttonless, - #[serde(rename = "none")] None, } @@ -166,71 +139,82 @@ impl Default for Decorations { /// Window Dimensions. /// /// Newtype to avoid passing values incorrectly. -#[serde(default)] -#[derive(Default, Debug, Copy, Clone, Deserialize, PartialEq, Eq)] +#[derive(ConfigDeserialize, Default, Debug, Copy, Clone, PartialEq, Eq)] pub struct Dimensions { /// Window width in character columns. - #[serde(deserialize_with = "failure_default")] pub columns: Column, /// Window Height in character lines. - #[serde(deserialize_with = "failure_default")] pub lines: Line, } /// Window class hint. -#[serde(default)] -#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Class { - #[serde(deserialize_with = "deserialize_class_resource")] pub instance: String, - - #[serde(deserialize_with = "deserialize_class_resource")] pub general: String, } impl Default for Class { fn default() -> Self { - Class { instance: DEFAULT_NAME.into(), general: DEFAULT_NAME.into() } - } -} - -fn deserialize_class_resource<'a, D>(deserializer: D) -> Result<String, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - match String::deserialize(value) { - Ok(value) => Ok(value), - Err(err) => { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: {}, using default value {}", err, DEFAULT_NAME, - ); - - Ok(DEFAULT_NAME.into()) - }, + Self { instance: DEFAULT_NAME.into(), general: DEFAULT_NAME.into() } } } -fn deserialize_class<'a, D>(deserializer: D) -> Result<Class, D::Error> -where - D: Deserializer<'a>, -{ - let value = Value::deserialize(deserializer)?; - - if let Value::String(instance) = value { - return Ok(Class { instance, general: DEFAULT_NAME.into() }); - } +impl<'de> Deserialize<'de> for Class { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct ClassVisitor; + impl<'a> Visitor<'a> for ClassVisitor { + type Value = Class; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + Ok(Self::Value { instance: value.into(), ..Self::Value::default() }) + } + + fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error> + where + M: MapAccess<'a>, + { + let mut class = Self::Value::default(); + + while let Some((key, value)) = map.next_entry::<String, serde_yaml::Value>()? { + match key.as_str() { + "instance" => match String::deserialize(value) { + Ok(instance) => class.instance = instance, + Err(err) => { + error!( + target: LOG_TARGET_CONFIG, + "Config error: class.instance: {}", err + ); + }, + }, + "general" => match String::deserialize(value) { + Ok(general) => class.general = general, + Err(err) => { + error!( + target: LOG_TARGET_CONFIG, + "Config error: class.instance: {}", err + ); + }, + }, + _ => (), + } + } + + Ok(class) + } + } - match Class::deserialize(value) { - Ok(value) => Ok(value), - Err(err) => { - error!( - target: LOG_TARGET_CONFIG, - "Problem with config: {}; using class {}", err, DEFAULT_NAME - ); - Ok(Class::default()) - }, + deserializer.deserialize_any(ClassVisitor) } } |