diff options
author | Brian Koropoff <bkoropoff@gmail.com> | 2019-07-06 12:34:56 -0700 |
---|---|---|
committer | Christian Duerr <chrisduerr@users.noreply.github.com> | 2019-07-06 19:34:56 +0000 |
commit | 228c641769c39bcd1460959e479b2259e7d5f773 (patch) | |
tree | f7bece352f9063753aa5af834bcb31eeecb82914 /alacritty_terminal | |
parent | e398eb84064c5eac7cb8a97c276494100a37314b (diff) | |
download | alacritty-228c641769c39bcd1460959e479b2259e7d5f773.tar.gz alacritty-228c641769c39bcd1460959e479b2259e7d5f773.zip |
Allow setting gtk variant and general class on X11
Diffstat (limited to 'alacritty_terminal')
-rw-r--r-- | alacritty_terminal/src/config/mod.rs | 82 | ||||
-rw-r--r-- | alacritty_terminal/src/config/window.rs | 31 | ||||
-rw-r--r-- | alacritty_terminal/src/window.rs | 20 |
3 files changed, 84 insertions, 49 deletions
diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs index 54af0fd1..50606ef0 100644 --- a/alacritty_terminal/src/config/mod.rs +++ b/alacritty_terminal/src/config/mod.rs @@ -15,8 +15,10 @@ use std::borrow::Cow; use std::collections::HashMap; use std::path::PathBuf; +use std::fmt::Display; use serde::{Deserialize, Deserializer}; +use serde_yaml::Value; mod bindings; mod colors; @@ -92,7 +94,7 @@ pub struct Config { pub mouse: Mouse, /// Path to a shell program to run on startup - #[serde(default, deserialize_with = "failure_default")] + #[serde(default, deserialize_with = "from_string_or_deserialize")] pub shell: Option<Shell<'static>>, /// Path where config was loaded from @@ -134,8 +136,8 @@ pub struct Config { alt_send_esc: DefaultTrueBool, /// Shell startup directory - #[serde(default, deserialize_with = "failure_default")] - working_directory: WorkingDirectory, + #[serde(default, deserialize_with = "option_explicit_none")] + working_directory: Option<PathBuf>, /// Debug options #[serde(default, deserialize_with = "failure_default")] @@ -212,37 +214,12 @@ impl Config { #[inline] pub fn working_directory(&self) -> &Option<PathBuf> { - &self.working_directory.0 + &self.working_directory } #[inline] pub fn set_working_directory(&mut self, working_directory: Option<PathBuf>) { - self.working_directory.0 = working_directory; - } -} - -#[derive(Default, Debug, PartialEq, Eq)] -struct WorkingDirectory(Option<PathBuf>); - -impl<'de> Deserialize<'de> for WorkingDirectory { - fn deserialize<D>(deserializer: D) -> Result<WorkingDirectory, D::Error> - where - D: Deserializer<'de>, - { - let value = serde_yaml::Value::deserialize(deserializer)?; - - // Accept `None` to use the default path - if value.as_str().filter(|v| v.to_lowercase() == "none").is_some() { - return Ok(WorkingDirectory(None)); - } - - Ok(match PathBuf::deserialize(value) { - Ok(path) => WorkingDirectory(Some(path)), - Err(err) => { - error!("Problem with config: {}; using None", err); - WorkingDirectory(None) - }, - }) + self.working_directory = working_directory; } } @@ -357,6 +334,12 @@ impl<'a> Shell<'a> { } } +impl FromString for Option<Shell<'_>> { + fn from(input: String) -> Self { + Some(Shell::new(input)) + } +} + /// A delta for a point in a 2 dimensional plane #[serde(default, bound(deserialize = "T: Deserialize<'de> + Default"))] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Eq)] @@ -418,17 +401,40 @@ impl Default for DefaultTrueBool { } } +fn fallback_default<T, E>(err: E) -> T + where T: Default, E: Display +{ + error!("Problem with config: {}; using default value", err); + T::default() +} + pub fn failure_default<'a, D, T>(deserializer: D) -> Result<T, D::Error> where D: Deserializer<'a>, T: Deserialize<'a> + Default, { - let value = serde_yaml::Value::deserialize(deserializer)?; - match T::deserialize(value) { - Ok(value) => Ok(value), - Err(err) => { - error!("Problem with config: {}; using default value", err); - Ok(T::default()) - }, - } + Ok(T::deserialize(Value::deserialize(deserializer)?).unwrap_or_else(fallback_default)) +} + +pub fn option_explicit_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error> + where D: Deserializer<'de>, T: Deserialize<'de> + Default +{ + Ok(match Value::deserialize(deserializer)? { + Value::String(ref value) if value.to_lowercase() == "none" => None, + value => Some(T::deserialize(value).unwrap_or_else(fallback_default)) + }) +} + +pub fn from_string_or_deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error> + where D: Deserializer<'de>, T: Deserialize<'de> + FromString + Default +{ + Ok(match Value::deserialize(deserializer)? { + Value::String(value) => T::from(value), + value => T::deserialize(value).unwrap_or_else(fallback_default) + }) +} + +// Used over From<String>, to allow implementation for foreign types +pub trait FromString { + fn from(input: String) -> Self; } diff --git a/alacritty_terminal/src/config/window.rs b/alacritty_terminal/src/config/window.rs index d7f3dcbf..351bef10 100644 --- a/alacritty_terminal/src/config/window.rs +++ b/alacritty_terminal/src/config/window.rs @@ -1,5 +1,6 @@ -use crate::config::{failure_default, Delta}; +use crate::config::{failure_default, option_explicit_none, from_string_or_deserialize, Delta, FromString}; use crate::index::{Column, Line}; +use crate::window::DEFAULT_NAME; #[serde(default)] #[derive(Deserialize, Debug, Clone, Default, PartialEq, Eq)] @@ -33,8 +34,12 @@ pub struct WindowConfig { pub title: Option<String>, /// Window class - #[serde(deserialize_with = "failure_default")] - pub class: Option<String>, + #[serde(deserialize_with = "from_string_or_deserialize")] + pub class: Class, + + /// GTK theme variant + #[serde(deserialize_with = "option_explicit_none")] + pub gtk_theme_variant: Option<String>, /// TODO: DEPRECATED #[serde(deserialize_with = "failure_default")] @@ -117,3 +122,23 @@ impl Dimensions { self.columns.0 as u32 } } + +/// Window class hint +#[serde(default)] +#[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +pub struct Class { + pub instance: String, + pub general: String +} + +impl Default for Class { + fn default() -> Self { + Class { instance: DEFAULT_NAME.into(), general: DEFAULT_NAME.into() } + } +} + +impl FromString for Class { + fn from(value: String) -> Self { + Class { instance: value, general: DEFAULT_NAME.into() } + } +} diff --git a/alacritty_terminal/src/window.rs b/alacritty_terminal/src/window.rs index f7eb16c1..204a1f73 100644 --- a/alacritty_terminal/src/window.rs +++ b/alacritty_terminal/src/window.rs @@ -151,9 +151,8 @@ impl Window { dimensions: Option<LogicalSize>, ) -> Result<Window> { let title = config.window.title.as_ref().map_or(DEFAULT_NAME, |t| t); - let class = config.window.class.as_ref().map_or(DEFAULT_NAME, |c| c); - let window_builder = Window::get_platform_window(title, class, &config.window); + let window_builder = Window::get_platform_window(title, &config.window); let windowed_context = create_gl_window(window_builder.clone(), &event_loop, false, dimensions) .or_else(|_| create_gl_window(window_builder, &event_loop, true, dimensions))?; @@ -255,7 +254,6 @@ impl Window { #[cfg(not(any(target_os = "macos", windows)))] pub fn get_platform_window( title: &str, - class: &str, window_config: &WindowConfig, ) -> WindowBuilder { use glutin::os::unix::WindowBuilderExt; @@ -267,7 +265,9 @@ impl Window { let icon = Icon::from_bytes_with_format(WINDOW_ICON, ImageFormat::ICO); - WindowBuilder::new() + let class = &window_config.class; + + let mut builder = WindowBuilder::new() .with_title(title) .with_visibility(false) .with_transparency(true) @@ -275,15 +275,20 @@ impl Window { .with_maximized(window_config.startup_mode() == StartupMode::Maximized) .with_window_icon(icon.ok()) // X11 - .with_class(class.into(), DEFAULT_NAME.into()) + .with_class(class.instance.clone(), class.general.clone()) // Wayland - .with_app_id(class.into()) + .with_app_id(class.instance.clone()); + + if let Some(ref val) = window_config.gtk_theme_variant { + builder = builder.with_gtk_theme_variant(val.clone()) + } + + builder } #[cfg(windows)] pub fn get_platform_window( title: &str, - _class: &str, window_config: &WindowConfig, ) -> WindowBuilder { let decorations = match window_config.decorations { @@ -305,7 +310,6 @@ impl Window { #[cfg(target_os = "macos")] pub fn get_platform_window( title: &str, - _class: &str, window_config: &WindowConfig, ) -> WindowBuilder { use glutin::os::macos::WindowBuilderExt; |