diff --git a/CHANGELOG.md b/CHANGELOG.md index 9175fcad..46510dfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - To use the cell's text color for selection with a modified background, the `color.selection.text` variable must now be set to `CellForeground` instead of omitting it - URLs are no longer highlighted without a clearly delimited scheme -- Renamed `visual_bell` to `bell` +- Renamed config option `visual_bell` to `bell` +- Moved config option `dynamic_title` to `window.dynamic_title` ### Fixed @@ -71,6 +72,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ingoring of default FreeType properties - Alacritty crashing at startup when the configured font does not exist +### Removed + +- Deprecated `window.start_maximized` config field +- Deprecated `render_timer` config field +- Deprecated `persistent_logging` config field + ## 0.4.3 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 1eb8cab2..663cf8ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ dependencies = [ "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", @@ -55,7 +56,6 @@ version = "0.5.0-dev" dependencies = [ "base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "font 0.1.0", "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -64,7 +64,6 @@ dependencies = [ "mio-named-pipes 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index b5dc924f..c30bc370 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -36,6 +36,9 @@ xdg = "2" [target.'cfg(not(target_os = "macos"))'.dependencies] image = { version = "0.23.3", default-features = false, features = ["ico"] } +[target.'cfg(target_os = "macos")'.dependencies] +objc = "0.2.2" + [target.'cfg(any(target_os = "macos", windows))'.dependencies] dirs = "2.0.2" diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index 89db20e1..1f677488 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -4,9 +4,11 @@ use std::path::PathBuf; use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; use log::{self, error, LevelFilter}; -use alacritty_terminal::config::{Delta, Dimensions, Program, DEFAULT_NAME}; +use alacritty_terminal::config::Program; use alacritty_terminal::index::{Column, Line}; +use crate::config::ui_config::Delta; +use crate::config::window::{Dimensions, DEFAULT_NAME}; use crate::config::Config; #[cfg(not(any(target_os = "macos", windows)))] @@ -263,35 +265,42 @@ impl Options { } if let Some(lcr) = self.live_config_reload { - config.set_live_config_reload(lcr); + config.ui_config.set_live_config_reload(lcr); } config.shell = self.command.or(config.shell); config.hold = self.hold; - config.set_dynamic_title(config.dynamic_title() && self.title.is_none()); - config.window.dimensions = self.dimensions.unwrap_or(config.window.dimensions); - config.window.title = self.title.unwrap_or(config.window.title); - config.window.position = self.position.or(config.window.position); - config.window.embed = self.embed.and_then(|embed| embed.parse().ok()); + let dynamic_title = config.ui_config.dynamic_title() && self.title.is_none(); + config.ui_config.set_dynamic_title(dynamic_title); - config.window.class.instance = self.class_instance.unwrap_or(config.window.class.instance); - config.window.class.general = self.class_general.unwrap_or(config.window.class.general); + replace_if_some(&mut config.ui_config.window.dimensions, self.dimensions); + replace_if_some(&mut config.ui_config.window.title, self.title); + config.ui_config.window.position = self.position.or(config.ui_config.window.position); + config.ui_config.window.embed = self.embed.and_then(|embed| embed.parse().ok()); + replace_if_some(&mut config.ui_config.window.class.instance, self.class_instance); + replace_if_some(&mut config.ui_config.window.class.general, self.class_general); - config.debug.print_events = self.print_events || config.debug.print_events; - config.debug.log_level = max(config.debug.log_level, self.log_level); - config.debug.ref_test = self.ref_test || config.debug.ref_test; - config.debug.persistent_logging = - self.persistent_logging || config.debug.persistent_logging; + config.ui_config.debug.print_events |= self.print_events; + config.ui_config.debug.log_level = max(config.ui_config.debug.log_level, self.log_level); + config.ui_config.debug.ref_test |= self.ref_test; + config.ui_config.debug.persistent_logging |= self.persistent_logging; - if config.debug.print_events { - config.debug.log_level = max(config.debug.log_level, LevelFilter::Info); + if config.ui_config.debug.print_events { + config.ui_config.debug.log_level = + max(config.ui_config.debug.log_level, LevelFilter::Info); } config } } +fn replace_if_some(option: &mut T, value: Option) { + if let Some(value) = value { + *option = value; + } +} + #[cfg(test)] mod tests { use crate::cli::Options; @@ -300,11 +309,11 @@ mod tests { #[test] fn dynamic_title_ignoring_options_by_default() { let config = Config::default(); - let old_dynamic_title = config.dynamic_title(); + let old_dynamic_title = config.ui_config.dynamic_title(); let config = Options::default().into_config(config); - assert_eq!(old_dynamic_title, config.dynamic_title()); + assert_eq!(old_dynamic_title, config.ui_config.dynamic_title()); } #[test] @@ -315,16 +324,16 @@ mod tests { options.title = Some("foo".to_owned()); let config = options.into_config(config); - assert!(!config.dynamic_title()); + assert!(!config.ui_config.dynamic_title()); } #[test] fn dynamic_title_not_overridden_by_config() { let mut config = Config::default(); - config.window.title = "foo".to_owned(); + config.ui_config.window.title = "foo".to_owned(); let config = Options::default().into_config(config); - assert!(config.dynamic_title()); + assert!(config.ui_config.dynamic_title()); } } diff --git a/alacritty_terminal/src/config/debug.rs b/alacritty/src/config/debug.rs similarity index 96% rename from alacritty_terminal/src/config/debug.rs rename to alacritty/src/config/debug.rs index 9c9d4fde..62de0500 100644 --- a/alacritty_terminal/src/config/debug.rs +++ b/alacritty/src/config/debug.rs @@ -1,7 +1,7 @@ use log::{error, LevelFilter}; use serde::{Deserialize, Deserializer}; -use crate::config::{failure_default, LOG_TARGET_CONFIG}; +use alacritty_terminal::config::{failure_default, LOG_TARGET_CONFIG}; /// Debugging options. #[serde(default)] diff --git a/alacritty_terminal/src/config/font.rs b/alacritty/src/config/font.rs similarity index 97% rename from alacritty_terminal/src/config/font.rs rename to alacritty/src/config/font.rs index 6a9120c9..f718587c 100644 --- a/alacritty_terminal/src/config/font.rs +++ b/alacritty/src/config/font.rs @@ -5,9 +5,11 @@ use log::error; use serde::de::Visitor; use serde::{Deserialize, Deserializer}; +use alacritty_terminal::config::{failure_default, LOG_TARGET_CONFIG}; + #[cfg(target_os = "macos")] -use crate::config::DefaultTrueBool; -use crate::config::{failure_default, Delta, LOG_TARGET_CONFIG}; +use crate::config::ui_config::DefaultTrueBool; +use crate::config::ui_config::Delta; /// Font config. /// diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index e6437d26..7fffcc39 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -11,9 +11,12 @@ use log::{error, warn}; use alacritty_terminal::config::{Config as TermConfig, LOG_TARGET_CONFIG}; mod bindings; +pub mod debug; +pub mod font; pub mod monitor; mod mouse; -mod ui_config; +pub mod ui_config; +pub mod window; pub use crate::config::bindings::{Action, Binding, Key, ViAction}; #[cfg(test)] @@ -172,27 +175,6 @@ fn parse_config(contents: &str) -> Result { } fn print_deprecation_warnings(config: &Config) { - if config.window.start_maximized.is_some() { - warn!( - target: LOG_TARGET_CONFIG, - "Config window.start_maximized is deprecated; please use window.startup_mode instead" - ); - } - - if config.render_timer.is_some() { - warn!( - target: LOG_TARGET_CONFIG, - "Config render_timer is deprecated; please use debug.render_timer instead" - ); - } - - if config.persistent_logging.is_some() { - warn!( - target: LOG_TARGET_CONFIG, - "Config persistent_logging is deprecated; please use debug.persistent_logging instead" - ); - } - if config.scrolling.faux_multiplier().is_some() { warn!( target: LOG_TARGET_CONFIG, @@ -224,6 +206,13 @@ fn print_deprecation_warnings(config: &Config) { "Config visual_bell has been deprecated; please use bell instead" ) } + + if config.ui_config.dynamic_title.is_some() { + warn!( + target: LOG_TARGET_CONFIG, + "Config dynamic_title is deprecated; please use window.dynamic_title instead", + ) + } } #[cfg(test)] diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index 49e54e05..a8b1749f 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -1,13 +1,24 @@ use log::error; use serde::{Deserialize, Deserializer}; -use alacritty_terminal::config::{failure_default, LOG_TARGET_CONFIG}; +use alacritty_terminal::config::{failure_default, Percentage, LOG_TARGET_CONFIG}; use crate::config::bindings::{self, Binding, KeyBinding, MouseBinding}; +use crate::config::debug::Debug; +use crate::config::font::Font; use crate::config::mouse::Mouse; +use crate::config::window::WindowConfig; #[derive(Debug, PartialEq, Deserialize)] pub struct UIConfig { + /// Font configuration. + #[serde(default, deserialize_with = "failure_default")] + pub font: Font, + + /// Window configuration. + #[serde(default, deserialize_with = "failure_default")] + pub window: WindowConfig, + #[serde(default, deserialize_with = "failure_default")] pub mouse: Mouse, @@ -18,18 +29,79 @@ pub struct UIConfig { /// Bindings for the mouse. #[serde(default = "default_mouse_bindings", deserialize_with = "deserialize_mouse_bindings")] pub mouse_bindings: Vec, + + /// Debug options. + #[serde(default, deserialize_with = "failure_default")] + pub debug: Debug, + + /// Send escape sequences using the alt key. + #[serde(default, deserialize_with = "failure_default")] + alt_send_esc: DefaultTrueBool, + + /// Live config reload. + #[serde(default, deserialize_with = "failure_default")] + live_config_reload: DefaultTrueBool, + + /// Background opacity from 0.0 to 1.0. + #[serde(default, deserialize_with = "failure_default")] + background_opacity: Percentage, + + // TODO: DEPRECATED + #[serde(default, deserialize_with = "failure_default")] + pub dynamic_title: Option, } impl Default for UIConfig { fn default() -> Self { UIConfig { - mouse: Mouse::default(), + font: Default::default(), + window: Default::default(), + mouse: Default::default(), key_bindings: default_key_bindings(), mouse_bindings: default_mouse_bindings(), + debug: Default::default(), + alt_send_esc: Default::default(), + background_opacity: Default::default(), + live_config_reload: Default::default(), + dynamic_title: Default::default(), } } } +impl UIConfig { + #[inline] + pub fn background_opacity(&self) -> f32 { + self.background_opacity.as_f32() + } + + #[inline] + pub fn dynamic_title(&self) -> bool { + self.dynamic_title.unwrap_or_else(|| self.window.dynamic_title()) + } + + #[inline] + pub fn set_dynamic_title(&mut self, dynamic_title: bool) { + self.window.set_dynamic_title(dynamic_title); + } + + /// Live config reload. + #[inline] + pub fn live_config_reload(&self) -> bool { + self.live_config_reload.0 + } + + #[inline] + pub fn set_live_config_reload(&mut self, live_config_reload: bool) { + self.live_config_reload.0 = live_config_reload; + } + + /// Send escape sequences using the alt key. + #[inline] + pub fn alt_send_esc(&self) -> bool { + self.alt_send_esc.0 + } +} + fn default_key_bindings() -> Vec { bindings::default_key_bindings() } @@ -83,3 +155,24 @@ where Ok(bindings) } + +#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq)] +pub struct DefaultTrueBool(pub bool); + +impl Default for DefaultTrueBool { + fn default() -> Self { + DefaultTrueBool(true) + } +} + +/// 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)] +pub struct Delta { + /// Horizontal change. + #[serde(deserialize_with = "failure_default")] + pub x: T, + /// Vertical change. + #[serde(deserialize_with = "failure_default")] + pub y: T, +} diff --git a/alacritty_terminal/src/config/window.rs b/alacritty/src/config/window.rs similarity index 88% rename from alacritty_terminal/src/config/window.rs rename to alacritty/src/config/window.rs index b410f0a2..f866e180 100644 --- a/alacritty_terminal/src/config/window.rs +++ b/alacritty/src/config/window.rs @@ -4,8 +4,10 @@ use log::error; use serde::{Deserialize, Deserializer}; use serde_yaml::Value; -use crate::config::{failure_default, option_explicit_none, Delta, LOG_TARGET_CONFIG}; -use crate::index::{Column, Line}; +use alacritty_terminal::config::{failure_default, option_explicit_none, LOG_TARGET_CONFIG}; +use alacritty_terminal::index::{Column, Line}; + +use crate::config::ui_config::{DefaultTrueBool, Delta}; /// Default Alacritty name, used for window title and class. pub const DEFAULT_NAME: &str = "Alacritty"; @@ -35,7 +37,7 @@ pub struct WindowConfig { /// Startup mode. #[serde(deserialize_with = "failure_default")] - startup_mode: StartupMode, + pub startup_mode: StartupMode, /// Window title. #[serde(default = "default_title")] @@ -53,9 +55,9 @@ pub struct WindowConfig { #[serde(deserialize_with = "option_explicit_none")] pub gtk_theme_variant: Option, - // TODO: DEPRECATED - #[serde(deserialize_with = "failure_default")] - pub start_maximized: Option, + /// Use dynamic title. + #[serde(default, deserialize_with = "failure_default")] + dynamic_title: DefaultTrueBool, } pub fn default_title() -> String { @@ -63,11 +65,14 @@ pub fn default_title() -> String { } impl WindowConfig { - pub fn startup_mode(&self) -> StartupMode { - match self.start_maximized { - Some(true) => StartupMode::Maximized, - _ => self.startup_mode, - } + #[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; } } @@ -83,8 +88,8 @@ impl Default for WindowConfig { class: Default::default(), embed: Default::default(), gtk_theme_variant: Default::default(), - start_maximized: Default::default(), title: default_title(), + dynamic_title: Default::default(), } } } diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs index 0a3bea34..ab6ed7e6 100644 --- a/alacritty/src/display.rs +++ b/alacritty/src/display.rs @@ -22,19 +22,23 @@ use wayland_client::{Display as WaylandDisplay, EventQueue}; #[cfg(target_os = "macos")] use font::set_font_smoothing; -use font::{self, Rasterize}; +use font::{self, Rasterize, Rasterizer}; -use alacritty_terminal::config::{Font, StartupMode}; use alacritty_terminal::event::{EventListener, OnResize}; +#[cfg(not(windows))] use alacritty_terminal::grid::Dimensions; -use alacritty_terminal::index::{Column, Line, Point}; -use alacritty_terminal::message_bar::MessageBuffer; -use alacritty_terminal::meter::Meter; +use alacritty_terminal::index::Line; +#[cfg(not(windows))] +use alacritty_terminal::index::{Column, Point}; use alacritty_terminal::selection::Selection; use alacritty_terminal::term::{RenderableCell, SizeInfo, Term, TermMode}; +use crate::config::font::Font; +use crate::config::window::StartupMode; use crate::config::Config; use crate::event::Mouse; +use crate::message_bar::MessageBuffer; +use crate::meter::Meter; use crate::renderer::rects::{RenderLines, RenderRect}; use crate::renderer::{self, GlyphCache, QuadRenderer}; use crate::url::{Url, Urls}; @@ -167,10 +171,15 @@ impl Display { event_loop.available_monitors().next().map(|m| m.scale_factor()).unwrap_or(1.); // Guess the target window dimensions. - let metrics = GlyphCache::static_metrics(config.font.clone(), estimated_dpr)?; + let metrics = GlyphCache::static_metrics(config.ui_config.font.clone(), estimated_dpr)?; let (cell_width, cell_height) = compute_cell_size(config, &metrics); - let dimensions = - GlyphCache::calculate_dimensions(config, estimated_dpr, cell_width, cell_height); + + let dimensions = GlyphCache::calculate_dimensions( + &config.ui_config.window, + estimated_dpr, + cell_width, + cell_height, + ); debug!("Estimated DPR: {}", estimated_dpr); debug!("Estimated Cell Size: {} x {}", cell_width, cell_height); @@ -212,11 +221,12 @@ impl Display { let (glyph_cache, cell_width, cell_height) = Self::new_glyph_cache(dpr, &mut renderer, config)?; - let mut padding_x = f32::from(config.window.padding.x) * dpr as f32; - let mut padding_y = f32::from(config.window.padding.y) * dpr as f32; + let padding = config.ui_config.window.padding; + let mut padding_x = f32::from(padding.x) * dpr as f32; + let mut padding_y = f32::from(padding.y) * dpr as f32; if let Some((width, height)) = - GlyphCache::calculate_dimensions(config, dpr, cell_width, cell_height) + GlyphCache::calculate_dimensions(&config.ui_config.window, dpr, cell_width, cell_height) { let PhysicalSize { width: w, height: h } = window.inner_size(); if w == width && h == height { @@ -224,7 +234,7 @@ impl Display { } else { window.set_inner_size(PhysicalSize::new(width, height)); } - } else if config.window.dynamic_padding { + } else if config.ui_config.window.dynamic_padding { // Make sure additional padding is spread evenly. padding_x = dynamic_padding(padding_x, viewport_size.width as f32, cell_width); padding_y = dynamic_padding(padding_y, viewport_size.height as f32, cell_height); @@ -252,13 +262,13 @@ impl Display { // Clear screen. let background_color = config.colors.primary.background; - renderer.with_api(&config, &size_info, |api| { + renderer.with_api(&config.ui_config, config.cursor, &size_info, |api| { api.clear(background_color); }); // Set subpixel anti-aliasing. #[cfg(target_os = "macos")] - set_font_smoothing(config.font.use_thin_strokes()); + set_font_smoothing(config.ui_config.font.use_thin_strokes()); #[cfg(not(any(target_os = "macos", windows)))] let is_x11 = event_loop.is_x11(); @@ -269,7 +279,7 @@ impl Display { // actually draw something into it and commit those changes. if is_x11 { window.swap_buffers(); - renderer.with_api(&config, &size_info, |api| { + renderer.with_api(&config.ui_config, config.cursor, &size_info, |api| { api.finish(); }); } @@ -281,12 +291,12 @@ impl Display { // // TODO: replace `set_position` with `with_position` once available. // Upstream issue: https://github.com/rust-windowing/winit/issues/806. - if let Some(position) = config.window.position { + if let Some(position) = config.ui_config.window.position { window.set_outer_position(PhysicalPosition::from((position.x, position.y))); } #[allow(clippy::single_match)] - match config.window.startup_mode() { + match config.ui_config.window.startup_mode { StartupMode::Fullscreen => window.set_fullscreen(true), #[cfg(target_os = "macos")] StartupMode::SimpleFullscreen => window.set_simple_fullscreen(true), @@ -315,8 +325,8 @@ impl Display { renderer: &mut QuadRenderer, config: &Config, ) -> Result<(GlyphCache, f32, f32), Error> { - let font = config.font.clone(); - let rasterizer = font::Rasterizer::new(dpr as f32, config.font.use_thin_strokes())?; + let font = config.ui_config.font.clone(); + let rasterizer = Rasterizer::new(dpr as f32, config.ui_config.font.use_thin_strokes())?; // Initialize glyph cache. let glyph_cache = { @@ -387,8 +397,9 @@ impl Display { let cell_height = self.size_info.cell_height; // Recalculate padding. - let mut padding_x = f32::from(config.window.padding.x) * self.size_info.dpr as f32; - let mut padding_y = f32::from(config.window.padding.y) * self.size_info.dpr as f32; + let padding = config.ui_config.window.padding; + let mut padding_x = f32::from(padding.x) * self.size_info.dpr as f32; + let mut padding_y = f32::from(padding.y) * self.size_info.dpr as f32; // Update the window dimensions. if let Some(size) = update_pending.dimensions() { @@ -398,7 +409,7 @@ impl Display { } // Distribute excess padding equally on all sides. - if config.window.dynamic_padding { + if config.ui_config.window.dynamic_padding { padding_x = dynamic_padding(padding_x, self.size_info.width, cell_width); padding_y = dynamic_padding(padding_y, self.size_info.height, cell_height); } @@ -480,7 +491,7 @@ impl Display { // Drop terminal as early as possible to free lock. drop(terminal); - self.renderer.with_api(&config, &size_info, |api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |api| { api.clear(background_color); }); @@ -491,7 +502,7 @@ impl Display { { let _sampler = self.meter.sampler(); - self.renderer.with_api(&config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { // Iterate over all non-empty cells in the grid. for cell in grid_cells { // Update URL underlines. @@ -566,7 +577,7 @@ impl Display { // Relay messages to the user. let fg = config.colors.primary.background; for (i, message_text) in text.iter().rev().enumerate() { - self.renderer.with_api(&config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { api.render_string( glyph_cache, Line(size_info.lines().saturating_sub(i + 1)), @@ -597,7 +608,7 @@ impl Display { // On X11 `swap_buffers` does not block for vsync. However the next OpenGl command // will block to synchronize (this is `glClear` in Alacritty), which causes a // permanent one frame delay. - self.renderer.with_api(&config, &size_info, |api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |api| { api.finish(); }); } @@ -650,14 +661,14 @@ impl Display { let fg = config.colors.search_bar_foreground(); let bg = config.colors.search_bar_background(); let line = size_info.lines() - message_bar_lines - 1; - self.renderer.with_api(&config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { api.render_string(glyph_cache, line, &text, fg, Some(bg)); }); } /// Draw render timer. fn draw_render_timer(&mut self, config: &Config, size_info: &SizeInfo) { - if !config.render_timer() { + if !config.ui_config.debug.render_timer { return; } let glyph_cache = &mut self.glyph_cache; @@ -666,7 +677,7 @@ impl Display { let fg = config.colors.normal().black; let bg = config.colors.normal().red; - self.renderer.with_api(&config, &size_info, |mut api| { + self.renderer.with_api(&config.ui_config, config.cursor, &size_info, |mut api| { api.render_string(glyph_cache, size_info.lines() - 2, &timing[..], fg, Some(bg)); }); } @@ -701,8 +712,8 @@ fn dynamic_padding(padding: f32, dimension: f32, cell_dimension: f32) -> f32 { /// Calculate the cell dimensions based on font metrics. #[inline] fn compute_cell_size(config: &Config, metrics: &font::Metrics) -> (f32, f32) { - let offset_x = f64::from(config.font.offset.x); - let offset_y = f64::from(config.font.offset.y); + let offset_x = f64::from(config.ui_config.font.offset.x); + let offset_y = f64::from(config.ui_config.font.offset.y); ( ((metrics.average_advance + offset_x) as f32).floor().max(1.), ((metrics.line_height + offset_y) as f32).floor().max(1.), diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index c651fda3..f90ebdd3 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -32,7 +32,6 @@ use alacritty_terminal::config::LOG_TARGET_CONFIG; use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify, OnResize}; use alacritty_terminal::grid::{Dimensions, Scroll}; use alacritty_terminal::index::{Column, Direction, Line, Point, Side}; -use alacritty_terminal::message_bar::{Message, MessageBuffer}; use alacritty_terminal::selection::{Selection, SelectionType}; use alacritty_terminal::sync::FairMutex; use alacritty_terminal::term::cell::Cell; @@ -47,6 +46,7 @@ use crate::config::Config; use crate::daemon::start_daemon; use crate::display::{Display, DisplayUpdate}; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; +use crate::message_bar::{Message, MessageBuffer}; use crate::scheduler::{Scheduler, TimerId}; use crate::url::{Url, Urls}; use crate::window::Window; @@ -312,14 +312,14 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon fn change_font_size(&mut self, delta: f32) { *self.font_size = max(*self.font_size + delta, Size::new(FONT_SIZE_STEP)); - let font = self.config.font.clone().with_size(*self.font_size); + let font = self.config.ui_config.font.clone().with_size(*self.font_size); self.display_update_pending.set_font(font); self.terminal.dirty = true; } fn reset_font_size(&mut self) { - *self.font_size = self.config.font.size; - self.display_update_pending.set_font(self.config.font.clone()); + *self.font_size = self.config.ui_config.font.size; + self.display_update_pending.set_font(self.config.ui_config.font.clone()); self.terminal.dirty = true; } @@ -636,7 +636,7 @@ impl Processor { received_count: 0, suppress_chars: false, modifiers: Default::default(), - font_size: config.font.size, + font_size: config.ui_config.font.size, config, message_buffer, display, @@ -679,7 +679,7 @@ impl Processor { let mut scheduler = Scheduler::new(); event_loop.run_return(|event, event_loop, control_flow| { - if self.config.debug.print_events { + if self.config.ui_config.debug.print_events { info!("glutin event: {:?}", event); } @@ -791,7 +791,7 @@ impl Processor { }); // Write ref tests to disk. - if self.config.debug.ref_test { + if self.config.ui_config.debug.ref_test { self.write_ref_test_results(&terminal.lock()); } } @@ -811,7 +811,7 @@ impl Processor { let display_update_pending = &mut processor.ctx.display_update_pending; // Push current font to update its DPR. - let font = processor.ctx.config.font.clone(); + let font = processor.ctx.config.ui_config.font.clone(); display_update_pending.set_font(font.with_size(*processor.ctx.font_size)); // Resize to event's dimensions, since no resize event is emitted on Wayland. @@ -829,7 +829,18 @@ impl Processor { Event::ConfigReload(path) => Self::reload_config(&path, processor), Event::Scroll(scroll) => processor.ctx.scroll(scroll), Event::TerminalEvent(event) => match event { - TerminalEvent::Title(title) => processor.ctx.window.set_title(&title), + TerminalEvent::Title(title) => { + let ui_config = &processor.ctx.config.ui_config; + if ui_config.dynamic_title() { + processor.ctx.window.set_title(&title); + } + }, + TerminalEvent::ResetTitle => { + let ui_config = &processor.ctx.config.ui_config; + if ui_config.dynamic_title() { + processor.ctx.window.set_title(&ui_config.window.title); + } + }, TerminalEvent::Wakeup => processor.ctx.terminal.dirty = true, TerminalEvent::Bell => { let bell_command = processor.ctx.config.bell().command.as_ref(); @@ -983,16 +994,23 @@ impl Processor { processor.ctx.display_update_pending.set_cursor_dirty(); } - if processor.ctx.config.font != config.font { + if processor.ctx.config.ui_config.font != config.ui_config.font { // Do not update font size if it has been changed at runtime. - if *processor.ctx.font_size == processor.ctx.config.font.size { - *processor.ctx.font_size = config.font.size; + if *processor.ctx.font_size == processor.ctx.config.ui_config.font.size { + *processor.ctx.font_size = config.ui_config.font.size; } - let font = config.font.clone().with_size(*processor.ctx.font_size); + let font = config.ui_config.font.clone().with_size(*processor.ctx.font_size); processor.ctx.display_update_pending.set_font(font); } + // Live title reload. + if !config.ui_config.dynamic_title() + || processor.ctx.config.ui_config.window.title != config.ui_config.window.title + { + processor.ctx.window.set_title(&config.ui_config.window.title); + } + #[cfg(not(any(target_os = "macos", windows)))] { if processor.ctx.event_loop.is_wayland() { @@ -1002,7 +1020,7 @@ impl Processor { // Set subpixel anti-aliasing. #[cfg(target_os = "macos")] - set_font_smoothing(config.font.use_thin_strokes()); + set_font_smoothing(config.ui_config.font.use_thin_strokes()); *processor.ctx.config = config; diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index 64b79002..2d865990 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -26,7 +26,6 @@ use alacritty_terminal::ansi::{ClearMode, Handler}; use alacritty_terminal::event::EventListener; use alacritty_terminal::grid::{Dimensions, Scroll}; use alacritty_terminal::index::{Column, Direction, Line, Point, Side}; -use alacritty_terminal::message_bar::{self, Message}; use alacritty_terminal::selection::SelectionType; use alacritty_terminal::term::mode::TermMode; use alacritty_terminal::term::{ClipboardType, SizeInfo, Term}; @@ -36,6 +35,7 @@ use crate::clipboard::Clipboard; use crate::config::{Action, Binding, Config, Key, ViAction}; use crate::daemon::start_daemon; use crate::event::{ClickState, Event, Mouse, TYPING_SEARCH_DELAY}; +use crate::message_bar::{self, Message}; use crate::scheduler::{Scheduler, TimerId}; use crate::url::{Url, Urls}; use crate::window::Window; @@ -894,7 +894,7 @@ impl<'a, T: EventListener, A: ActionContext> Processor<'a, T, A> { c.encode_utf8(&mut bytes[..]); } - if self.ctx.config().alt_send_esc() + if self.ctx.config().ui_config.alt_send_esc() && *self.ctx.received_count() == 0 && self.ctx.modifiers().alt() && utf8_len == 1 @@ -1088,10 +1088,10 @@ mod tests { use glutin::event::{Event as GlutinEvent, VirtualKeyCode, WindowEvent}; use alacritty_terminal::event::Event as TerminalEvent; - use alacritty_terminal::message_bar::MessageBuffer; use alacritty_terminal::selection::Selection; use crate::config::ClickHandler; + use crate::message_bar::MessageBuffer; const KEY: VirtualKeyCode = VirtualKeyCode::Key0; diff --git a/alacritty_terminal/src/locale.rs b/alacritty/src/locale.rs similarity index 99% rename from alacritty_terminal/src/locale.rs rename to alacritty/src/locale.rs index 0a72e775..6c02c12c 100644 --- a/alacritty_terminal/src/locale.rs +++ b/alacritty/src/locale.rs @@ -9,6 +9,7 @@ use std::str; use libc::{setlocale, LC_ALL, LC_CTYPE}; use log::debug; use objc::runtime::{Class, Object}; +use objc::{msg_send, sel, sel_impl}; const FALLBACK_LOCALE: &str = "UTF-8"; diff --git a/alacritty/src/logging.rs b/alacritty/src/logging.rs index a6fcf3fb..5d702999 100644 --- a/alacritty/src/logging.rs +++ b/alacritty/src/logging.rs @@ -15,11 +15,11 @@ use std::sync::{Arc, Mutex}; use glutin::event_loop::EventLoopProxy; use log::{self, Level}; -use alacritty_terminal::message_bar::Message; use alacritty_terminal::term::color; use crate::cli::Options; use crate::event::Event; +use crate::message_bar::Message; const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG"; diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 9fbcab55..ae3ef346 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -1,7 +1,6 @@ //! Alacritty - The GPU Enhanced Terminal. #![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)] -#![cfg_attr(feature = "nightly", feature(core_intrinsics))] #![cfg_attr(all(test, feature = "bench"), feature(test))] // With the default subsystem, 'console', windows creates an additional console // window for the program. @@ -24,10 +23,6 @@ use log::{error, info}; use winapi::um::wincon::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; use alacritty_terminal::event_loop::{self, EventLoop, Msg}; -#[cfg(target_os = "macos")] -use alacritty_terminal::locale; -use alacritty_terminal::message_bar::MessageBuffer; -use alacritty_terminal::panic; use alacritty_terminal::sync::FairMutex; use alacritty_terminal::term::Term; use alacritty_terminal::tty; @@ -40,7 +35,13 @@ mod daemon; mod display; mod event; mod input; +#[cfg(target_os = "macos")] +mod locale; mod logging; +mod message_bar; +mod meter; +#[cfg(windows)] +mod panic; mod renderer; mod scheduler; mod url; @@ -59,8 +60,10 @@ use crate::config::monitor::Monitor; use crate::config::Config; use crate::display::Display; use crate::event::{Event, EventProxy, Processor}; +use crate::message_bar::MessageBuffer; fn main() { + #[cfg(windows)] panic::attach_handler(); // When linked with the windows subsystem windows won't automatically attach @@ -87,7 +90,7 @@ fn main() { let config = options.into_config(config); // Update the log level from config. - log::set_max_level(config.debug.log_level); + log::set_max_level(config.ui_config.debug.log_level); // Switch to home directory. #[cfg(target_os = "macos")] @@ -97,7 +100,7 @@ fn main() { locale::set_locale_environment(); // Store if log file should be deleted before moving config. - let persistent_logging = config.persistent_logging(); + let persistent_logging = config.ui_config.debug.persistent_logging; // Run Alacritty. if let Err(err) = run(window_event_loop, config) { @@ -161,7 +164,13 @@ fn run(window_event_loop: GlutinEventLoop, config: Config) -> Result<(), // renderer and input processing. Note that access to the terminal state is // synchronized since the I/O loop updates the state, and the display // consumes it periodically. - let event_loop = EventLoop::new(Arc::clone(&terminal), event_proxy.clone(), pty, &config); + let event_loop = EventLoop::new( + Arc::clone(&terminal), + event_proxy.clone(), + pty, + config.hold, + config.ui_config.debug.ref_test, + ); // The event loop channel allows write requests from the event processor // to be sent to the pty loop and ultimately written to the pty. @@ -171,7 +180,7 @@ fn run(window_event_loop: GlutinEventLoop, config: Config) -> Result<(), // // The monitor watches the config file for changes and reloads it. Pending // config changes are processed in the main loop. - if config.live_config_reload() { + if config.ui_config.live_config_reload() { config.config_path.as_ref().map(|path| Monitor::new(path, event_proxy.clone())); } diff --git a/alacritty_terminal/src/message_bar.rs b/alacritty/src/message_bar.rs similarity index 98% rename from alacritty_terminal/src/message_bar.rs rename to alacritty/src/message_bar.rs index 240581ff..175f7f81 100644 --- a/alacritty_terminal/src/message_bar.rs +++ b/alacritty/src/message_bar.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; -use crate::term::color::Rgb; -use crate::term::SizeInfo; +use alacritty_terminal::term::color::Rgb; +use alacritty_terminal::term::SizeInfo; pub const CLOSE_BUTTON_TEXT: &str = "[X]"; const CLOSE_BUTTON_PADDING: usize = 1; @@ -161,7 +161,7 @@ impl MessageBuffer { #[cfg(test)] mod tests { use super::{Message, MessageBuffer, MIN_FREE_LINES}; - use crate::term::{color, SizeInfo}; + use alacritty_terminal::term::{color, SizeInfo}; #[test] fn appends_close_button() { diff --git a/alacritty_terminal/src/meter.rs b/alacritty/src/meter.rs similarity index 100% rename from alacritty_terminal/src/meter.rs rename to alacritty/src/meter.rs diff --git a/alacritty_terminal/src/panic.rs b/alacritty/src/panic.rs similarity index 82% rename from alacritty_terminal/src/panic.rs rename to alacritty/src/panic.rs index 4ec409ff..9a76df72 100644 --- a/alacritty_terminal/src/panic.rs +++ b/alacritty/src/panic.rs @@ -1,13 +1,7 @@ -#[cfg(windows)] -use crate::tty::windows::win32_string; - -// Use the default behavior of the other platforms. -#[cfg(not(windows))] -pub fn attach_handler() {} +use alacritty_terminal::tty::windows::win32_string; // Install a panic handler that renders the panic in a classical Windows error // dialog box as well as writes the panic to STDERR. -#[cfg(windows)] pub fn attach_handler() { use std::{io, io::Write, panic, ptr}; use winapi::um::winuser; diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 99e4afbc..09682e6e 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::fmt::{self, Display, Formatter}; use std::fs; use std::hash::BuildHasherDefault; use std::io; @@ -10,7 +11,8 @@ use std::time::Duration; use fnv::FnvHasher; use font::{ - self, BitmapBuffer, FontDesc, FontKey, GlyphKey, Rasterize, RasterizedGlyph, Rasterizer, Size, + BitmapBuffer, FontDesc, FontKey, GlyphKey, Rasterize, RasterizedGlyph, Rasterizer, Size, Slant, + Style, Weight, }; use log::{error, info}; use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; @@ -19,16 +21,19 @@ use crate::cursor; use crate::gl; use crate::gl::types::*; use crate::renderer::rects::RenderRect; -use alacritty_terminal::config::{self, Config, Delta, Font, StartupMode}; +use alacritty_terminal::config::Cursor; use alacritty_terminal::index::{Column, Line}; use alacritty_terminal::term::cell::{self, Flags}; use alacritty_terminal::term::color::Rgb; -use alacritty_terminal::term::{self, CursorKey, RenderableCell, RenderableCellContent, SizeInfo}; +use alacritty_terminal::term::{CursorKey, RenderableCell, RenderableCellContent, SizeInfo}; use alacritty_terminal::thread; -use std::fmt::{self, Display, Formatter}; pub mod rects; +use crate::config::font::{Font, FontDescription}; +use crate::config::ui_config::{Delta, UIConfig}; +use crate::config::window::{StartupMode, WindowConfig}; + // Shader paths for live reload. static TEXT_SHADER_F_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../res/text.f.glsl"); static TEXT_SHADER_V_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../res/text.v.glsl"); @@ -173,7 +178,7 @@ pub struct GlyphCache { impl GlyphCache { pub fn new( mut rasterizer: Rasterizer, - font: &config::Font, + font: &Font, loader: &mut L, ) -> Result where @@ -215,14 +220,13 @@ impl GlyphCache { /// Computes font keys for (Regular, Bold, Italic, Bold Italic). fn compute_font_keys( - font: &config::Font, + font: &Font, rasterizer: &mut Rasterizer, ) -> Result<(FontKey, FontKey, FontKey, FontKey), font::Error> { let size = font.size; // Load regular font. - let regular_desc = - Self::make_desc(&font.normal(), font::Slant::Normal, font::Weight::Normal); + let regular_desc = Self::make_desc(&font.normal(), Slant::Normal, Weight::Normal); let regular = Self::load_regular_font(rasterizer, ®ular_desc, size)?; @@ -236,19 +240,17 @@ impl GlyphCache { }; // Load bold font. - let bold_desc = Self::make_desc(&font.bold(), font::Slant::Normal, font::Weight::Bold); + let bold_desc = Self::make_desc(&font.bold(), Slant::Normal, Weight::Bold); let bold = load_or_regular(bold_desc); // Load italic font. - let italic_desc = - Self::make_desc(&font.italic(), font::Slant::Italic, font::Weight::Normal); + let italic_desc = Self::make_desc(&font.italic(), Slant::Italic, Weight::Normal); let italic = load_or_regular(italic_desc); // Load bold italic font. - let bold_italic_desc = - Self::make_desc(&font.bold_italic(), font::Slant::Italic, font::Weight::Bold); + let bold_italic_desc = Self::make_desc(&font.bold_italic(), Slant::Italic, Weight::Bold); let bold_italic = load_or_regular(bold_italic_desc); @@ -265,25 +267,18 @@ impl GlyphCache { Err(err) => { error!("{}", err); - let fallback_desc = Self::make_desc( - &Font::default().normal(), - font::Slant::Normal, - font::Weight::Normal, - ); + let fallback_desc = + Self::make_desc(&Font::default().normal(), Slant::Normal, Weight::Normal); rasterizer.load_font(&fallback_desc, size) }, } } - fn make_desc( - desc: &config::FontDescription, - slant: font::Slant, - weight: font::Weight, - ) -> FontDesc { + fn make_desc(desc: &FontDescription, slant: Slant, weight: Weight) -> FontDesc { let style = if let Some(ref spec) = desc.style { - font::Style::Specific(spec.to_owned()) + Style::Specific(spec.to_owned()) } else { - font::Style::Description { slant, weight } + Style::Description { slant, weight } }; FontDesc::new(desc.family.clone(), style) } @@ -318,7 +313,7 @@ impl GlyphCache { pub fn update_font_size( &mut self, - font: &config::Font, + font: &Font, dpr: f64, loader: &mut L, ) -> Result<(), font::Error> { @@ -361,31 +356,30 @@ impl GlyphCache { /// Calculate font metrics without access to a glyph cache. pub fn static_metrics(font: Font, dpr: f64) -> Result { let mut rasterizer = font::Rasterizer::new(dpr as f32, font.use_thin_strokes())?; - let regular_desc = - GlyphCache::make_desc(&font.normal(), font::Slant::Normal, font::Weight::Normal); + let regular_desc = GlyphCache::make_desc(&font.normal(), Slant::Normal, Weight::Normal); let regular = Self::load_regular_font(&mut rasterizer, ®ular_desc, font.size)?; rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?; rasterizer.metrics(regular, font.size) } - pub fn calculate_dimensions( - config: &Config, + pub fn calculate_dimensions( + window_config: &WindowConfig, dpr: f64, cell_width: f32, cell_height: f32, ) -> Option<(u32, u32)> { - let dimensions = config.window.dimensions; + let dimensions = window_config.dimensions; if dimensions.columns_u32() == 0 || dimensions.lines_u32() == 0 - || config.window.startup_mode() != StartupMode::Windowed + || window_config.startup_mode != StartupMode::Windowed { return None; } - let padding_x = f64::from(config.window.padding.x) * dpr; - let padding_y = f64::from(config.window.padding.y) * dpr; + let padding_x = f64::from(window_config.padding.x) * dpr; + let padding_y = f64::from(window_config.padding.y) * dpr; // Calculate new size based on cols/lines specified in config. let grid_width = cell_width as u32 * dimensions.columns_u32(); @@ -446,13 +440,14 @@ pub struct QuadRenderer { } #[derive(Debug)] -pub struct RenderApi<'a, C> { +pub struct RenderApi<'a> { active_tex: &'a mut GLuint, batch: &'a mut Batch, atlas: &'a mut Vec, current_atlas: &'a mut usize, program: &'a mut TextShaderProgram, - config: &'a Config, + config: &'a UIConfig, + cursor_config: Cursor, } #[derive(Debug)] @@ -730,7 +725,7 @@ impl QuadRenderer { } /// Draw all rectangles simultaneously to prevent excessive program swaps. - pub fn draw_rects(&mut self, props: &term::SizeInfo, rects: Vec) { + pub fn draw_rects(&mut self, props: &SizeInfo, rects: Vec) { // Swap to rectangle rendering program. unsafe { // Swap program. @@ -783,9 +778,15 @@ impl QuadRenderer { } } - pub fn with_api(&mut self, config: &Config, props: &term::SizeInfo, func: F) -> T + pub fn with_api( + &mut self, + config: &UIConfig, + cursor_config: Cursor, + props: &SizeInfo, + func: F, + ) -> T where - F: FnOnce(RenderApi<'_, C>) -> T, + F: FnOnce(RenderApi<'_>) -> T, { // Flush message queue. if let Ok(Msg::ShaderReload) = self.rx.try_recv() { @@ -810,6 +811,7 @@ impl QuadRenderer { current_atlas: &mut self.current_atlas, program: &mut self.program, config, + cursor_config, }); unsafe { @@ -838,7 +840,7 @@ impl QuadRenderer { }) } - pub fn reload_shaders(&mut self, props: &term::SizeInfo) { + pub fn reload_shaders(&mut self, props: &SizeInfo) { info!("Reloading shaders..."); let result = (TextShaderProgram::new(), RectShaderProgram::new()); let (program, rect_program) = match result { @@ -888,7 +890,7 @@ impl QuadRenderer { /// Render a rectangle. /// /// This requires the rectangle program to be activated. - fn render_rect(&mut self, rect: &RenderRect, size: &term::SizeInfo) { + fn render_rect(&mut self, rect: &RenderRect, size: &SizeInfo) { // Do nothing when alpha is fully transparent. if rect.alpha == 0. { return; @@ -923,7 +925,7 @@ impl QuadRenderer { } } -impl<'a, C> RenderApi<'a, C> { +impl<'a> RenderApi<'a> { pub fn clear(&self, color: Rgb) { unsafe { let alpha = self.config.background_opacity(); @@ -1046,7 +1048,7 @@ impl<'a, C> RenderApi<'a, C> { self.config.font.offset.x, self.config.font.offset.y, cursor_key.is_wide, - self.config.cursor.thickness(), + self.cursor_config.thickness(), )) }); self.add_render_item(cell, glyph); @@ -1154,7 +1156,7 @@ impl<'a> LoadGlyph for LoaderApi<'a> { } } -impl<'a, C> LoadGlyph for RenderApi<'a, C> { +impl<'a> LoadGlyph for RenderApi<'a> { fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph { load_glyph(self.active_tex, self.atlas, self.current_atlas, rasterized) } @@ -1164,7 +1166,7 @@ impl<'a, C> LoadGlyph for RenderApi<'a, C> { } } -impl<'a, C> Drop for RenderApi<'a, C> { +impl<'a> Drop for RenderApi<'a> { fn drop(&mut self) { if !self.batch.is_empty() { self.render_batch(); @@ -1251,7 +1253,7 @@ impl TextShaderProgram { } } - fn set_term_uniforms(&self, props: &term::SizeInfo) { + fn set_term_uniforms(&self, props: &SizeInfo) { unsafe { gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height); } diff --git a/alacritty/src/window.rs b/alacritty/src/window.rs index 450329d4..89f16b7a 100644 --- a/alacritty/src/window.rs +++ b/alacritty/src/window.rs @@ -33,12 +33,12 @@ use glutin::{self, ContextBuilder, PossiblyCurrent, WindowedContext}; #[cfg(windows)] use winapi::shared::minwindef::WORD; -use alacritty_terminal::config::{Decorations, StartupMode, WindowConfig}; #[cfg(not(windows))] use alacritty_terminal::index::Point; #[cfg(not(windows))] use alacritty_terminal::term::SizeInfo; +use crate::config::window::{Decorations, StartupMode, WindowConfig}; use crate::config::Config; use crate::gl; @@ -154,7 +154,8 @@ impl Window { size: Option>, #[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue: Option<&EventQueue>, ) -> Result { - let window_builder = Window::get_platform_window(&config.window.title, &config.window); + let window_config = &config.ui_config.window; + let window_builder = Window::get_platform_window(&window_config.title, &window_config); // Disable vsync on Wayland. #[cfg(not(any(target_os = "macos", windows)))] @@ -180,7 +181,7 @@ impl Window { { if event_loop.is_x11() { // On X11, embed the window inside another if the parent ID has been set. - if let Some(parent_window_id) = config.window.embed { + if let Some(parent_window_id) = window_config.embed { x_embed_window(windowed_context.window(), parent_window_id); } } else { @@ -265,7 +266,7 @@ impl Window { .with_visible(false) .with_transparent(true) .with_decorations(decorations) - .with_maximized(window_config.startup_mode() == StartupMode::Maximized) + .with_maximized(window_config.startup_mode == StartupMode::Maximized) .with_window_icon(icon.ok()) // X11. .with_class(class.instance.clone(), class.general.clone()) @@ -293,7 +294,7 @@ impl Window { .with_visible(false) .with_decorations(decorations) .with_transparent(true) - .with_maximized(window_config.startup_mode() == StartupMode::Maximized) + .with_maximized(window_config.startup_mode == StartupMode::Maximized) .with_window_icon(icon.ok()) } @@ -303,7 +304,7 @@ impl Window { .with_title(title) .with_visible(false) .with_transparent(true) - .with_maximized(window_config.startup_mode() == StartupMode::Maximized); + .with_maximized(window_config.startup_mode == StartupMode::Maximized); match window_config.decorations { Decorations::Full => window, diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 3e796ba6..15edec3f 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -11,7 +11,6 @@ edition = "2018" [dependencies] libc = "0.2" bitflags = "1" -font = { path = "../font", features = ["force_system_fontconfig"] } parking_lot = "0.10.2" serde = { version = "1", features = ["derive"] } serde_yaml = "0.8" @@ -38,12 +37,8 @@ winapi = { version = "0.3.7", features = [ ]} mio-anonymous-pipes = "0.1" -[target.'cfg(target_os = "macos")'.dependencies] -objc = "0.2.2" - [features] default = ["winpty"] -nightly = [] bench = [] [dev-dependencies] diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs index 83dcd7b8..98579a69 100644 --- a/alacritty_terminal/src/config/mod.rs +++ b/alacritty_terminal/src/config/mod.rs @@ -8,19 +8,13 @@ use serde_yaml::Value; mod bell; mod colors; -mod debug; -mod font; mod scrolling; -mod window; use crate::ansi::CursorStyle; pub use crate::config::bell::{BellAnimation, BellConfig}; pub use crate::config::colors::Colors; -pub use crate::config::debug::Debug; -pub use crate::config::font::{Font, FontDescription}; pub use crate::config::scrolling::Scrolling; -pub use crate::config::window::{Decorations, Dimensions, StartupMode, WindowConfig, DEFAULT_NAME}; pub const LOG_TARGET_CONFIG: &str = "alacritty_config"; const MAX_SCROLLBACK_LINES: u32 = 100_000; @@ -31,18 +25,10 @@ pub type MockConfig = Config>; /// Top-level config type. #[derive(Debug, PartialEq, Default, Deserialize)] pub struct Config { - /// Pixel padding. - #[serde(default, deserialize_with = "failure_default")] - pub padding: Option>, - /// TERM env variable. #[serde(default, deserialize_with = "failure_default")] pub env: HashMap, - /// Font configuration. - #[serde(default, deserialize_with = "failure_default")] - pub font: Font, - /// Should draw bold text with brighter colors instead of bold font. #[serde(default, deserialize_with = "failure_default")] draw_bold_text_with_bright_colors: bool, @@ -50,14 +36,6 @@ pub struct Config { #[serde(default, deserialize_with = "failure_default")] pub colors: Colors, - /// Background opacity from 0.0 to 1.0. - #[serde(default, deserialize_with = "failure_default")] - background_opacity: Percentage, - - /// Window configuration. - #[serde(default, deserialize_with = "failure_default")] - pub window: WindowConfig, - #[serde(default, deserialize_with = "failure_default")] pub selection: Selection, @@ -73,14 +51,6 @@ pub struct Config { #[serde(default, deserialize_with = "failure_default")] bell: BellConfig, - /// Use dynamic title. - #[serde(default, deserialize_with = "failure_default")] - dynamic_title: DefaultTrueBool, - - /// Live config reload. - #[serde(default, deserialize_with = "failure_default")] - live_config_reload: DefaultTrueBool, - /// How much scrolling history to keep. #[serde(default, deserialize_with = "failure_default")] pub scrolling: Scrolling, @@ -94,18 +64,10 @@ pub struct Config { #[serde(default, deserialize_with = "failure_default")] pub winpty_backend: bool, - /// Send escape sequences using the alt key. - #[serde(default, deserialize_with = "failure_default")] - alt_send_esc: DefaultTrueBool, - /// Shell startup directory. #[serde(default, deserialize_with = "option_explicit_none")] pub working_directory: Option, - /// Debug options. - #[serde(default, deserialize_with = "failure_default")] - pub debug: Debug, - /// Additional configuration options not directly required by the terminal. #[serde(flatten)] pub ui_config: T, @@ -121,14 +83,6 @@ pub struct Config { // TODO: REMOVED #[serde(default, deserialize_with = "failure_default")] pub tabspaces: Option, - - // TODO: DEPRECATED - #[serde(default, deserialize_with = "failure_default")] - pub render_timer: Option, - - // TODO: DEPRECATED - #[serde(default, deserialize_with = "failure_default")] - pub persistent_logging: Option, } impl Config { @@ -137,50 +91,6 @@ impl Config { self.draw_bold_text_with_bright_colors } - /// Should show render timer. - #[inline] - pub fn render_timer(&self) -> bool { - self.render_timer.unwrap_or(self.debug.render_timer) - } - - /// Live config reload. - #[inline] - pub fn live_config_reload(&self) -> bool { - self.live_config_reload.0 - } - - #[inline] - pub fn set_live_config_reload(&mut self, live_config_reload: bool) { - self.live_config_reload.0 = live_config_reload; - } - - #[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; - } - - /// Send escape sequences using the alt key. - #[inline] - pub fn alt_send_esc(&self) -> bool { - self.alt_send_esc.0 - } - - /// Keep the log file after quitting Alacritty. - #[inline] - pub fn persistent_logging(&self) -> bool { - self.persistent_logging.unwrap_or(self.debug.persistent_logging) - } - - #[inline] - pub fn background_opacity(&self) -> f32 { - self.background_opacity.0 as f32 - } - #[inline] pub fn bell(&self) -> &BellConfig { self.visual_bell.as_ref().unwrap_or(&self.bell) @@ -294,18 +204,6 @@ impl Program { } } -/// 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)] -pub struct Delta { - /// Horizontal change. - #[serde(deserialize_with = "failure_default")] - pub x: T, - /// Vertical change. - #[serde(deserialize_with = "failure_default")] - pub y: T, -} - /// Wrapper around f32 that represents a percentage value between 0.0 and 1.0. #[derive(Clone, Copy, Debug, PartialEq)] pub struct Percentage(f32); @@ -320,6 +218,10 @@ impl Percentage { value }) } + + pub fn as_f32(self) -> f32 { + self.0 + } } impl Default for Percentage { diff --git a/alacritty_terminal/src/event.rs b/alacritty_terminal/src/event.rs index 863a2fbf..c7129b24 100644 --- a/alacritty_terminal/src/event.rs +++ b/alacritty_terminal/src/event.rs @@ -8,6 +8,7 @@ use crate::term::{ClipboardType, SizeInfo}; pub enum Event { MouseCursorDirty, Title(String), + ResetTitle, ClipboardStore(ClipboardType, String), ClipboardLoad(ClipboardType, Arc String + Sync + Send + 'static>), Wakeup, @@ -20,6 +21,7 @@ impl Debug for Event { match self { Event::MouseCursorDirty => write!(f, "MouseCursorDirty"), Event::Title(title) => write!(f, "Title({})", title), + Event::ResetTitle => write!(f, "ResetTitle"), Event::ClipboardStore(ty, text) => write!(f, "ClipboardStore({:?}, {})", ty, text), Event::ClipboardLoad(ty, _) => write!(f, "ClipboardLoad({:?})", ty), Event::Wakeup => write!(f, "Wakeup"), diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs index 156510b0..43e8a302 100644 --- a/alacritty_terminal/src/event_loop.rs +++ b/alacritty_terminal/src/event_loop.rs @@ -15,7 +15,6 @@ use mio::{self, Events, PollOpt, Ready}; use mio_extras::channel::{self, Receiver, Sender}; use crate::ansi; -use crate::config::Config; use crate::event::{self, Event, EventListener}; use crate::sync::FairMutex; use crate::term::{SizeInfo, Term}; @@ -155,11 +154,12 @@ where U: EventListener + Send + 'static, { /// Create a new event loop. - pub fn new( + pub fn new( terminal: Arc>>, event_proxy: U, pty: T, - config: &Config, + hold: bool, + ref_test: bool, ) -> EventLoop { let (tx, rx) = channel::channel(); EventLoop { @@ -169,8 +169,8 @@ where rx, terminal, event_proxy, - hold: config.hold, - ref_test: config.debug.ref_test, + hold, + ref_test, } } diff --git a/alacritty_terminal/src/lib.rs b/alacritty_terminal/src/lib.rs index 7130218b..2f3beeb0 100644 --- a/alacritty_terminal/src/lib.rs +++ b/alacritty_terminal/src/lib.rs @@ -1,24 +1,14 @@ //! Alacritty - The GPU Enhanced Terminal. #![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)] -#![cfg_attr(feature = "nightly", feature(core_intrinsics))] #![cfg_attr(all(test, feature = "bench"), feature(test))] -#[cfg(target_os = "macos")] -#[macro_use] -extern crate objc; - pub mod ansi; pub mod config; pub mod event; pub mod event_loop; pub mod grid; pub mod index; -#[cfg(target_os = "macos")] -pub mod locale; -pub mod message_bar; -pub mod meter; -pub mod panic; pub mod selection; pub mod sync; pub mod term; diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index f3f22d47..5a59b55b 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -721,14 +721,8 @@ pub struct Term { /// Current title of the window. title: Option, - /// Default title for resetting it. - default_title: String, - - /// Whether to permit updating the terminal title. - dynamic_title: bool, - /// Stack of saved window titles. When a title is popped from this stack, the `title` for the - /// term is set, and the Glutin window's title attribute is changed through the event listener. + /// term is set. title_stack: Vec>, /// Current forwards and backwards buffer search regexes. @@ -777,11 +771,9 @@ impl Term { cursor_style: None, default_cursor_style: config.cursor.style, vi_mode_cursor_style: config.cursor.vi_mode_style, - dynamic_title: config.dynamic_title(), event_proxy, is_focused: true, title: None, - default_title: config.window.title.clone(), title_stack: Vec::new(), selection: None, regex_search: None, @@ -808,14 +800,12 @@ impl Term { self.default_cursor_style = config.cursor.style; self.vi_mode_cursor_style = config.cursor.vi_mode_style; - self.default_title = config.window.title.clone(); - self.dynamic_title = config.dynamic_title(); + let title_event = match &self.title { + Some(title) => Event::Title(title.clone()), + None => Event::ResetTitle, + }; - if self.dynamic_title { - self.set_title(self.title.clone()); - } else { - self.event_proxy.send_event(Event::Title(self.default_title.clone())); - } + self.event_proxy.send_event(title_event); if self.mode.contains(TermMode::ALT_SCREEN) { self.inactive_grid.update_history(config.scrolling.history() as usize); @@ -2167,10 +2157,12 @@ impl Handler for Term { self.title = title.clone(); - if self.dynamic_title { - let title = title.unwrap_or_else(|| self.default_title.clone()); - self.event_proxy.send_event(Event::Title(title)); - } + let title_event = match title { + Some(title) => Event::Title(title), + None => Event::ResetTitle, + }; + + self.event_proxy.send_event(title_event); } #[inline] diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs index be147b49..fa9f8b5a 100644 --- a/alacritty_terminal/src/tty/windows/conpty.rs +++ b/alacritty_terminal/src/tty/windows/conpty.rs @@ -125,8 +125,7 @@ pub fn new(config: &Config, size: &SizeInfo, _window_id: Option) -> let mut startup_info_ex: STARTUPINFOEXW = Default::default(); - let title = win32_string(&config.window.title); - startup_info_ex.StartupInfo.lpTitle = title.as_ptr() as LPWSTR; + startup_info_ex.StartupInfo.lpTitle = std::ptr::null_mut() as LPWSTR; startup_info_ex.StartupInfo.cb = mem::size_of::() as u32;