1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

Remove gui dependencies from alacritty_terminal

This commit removes font dependency from alacritty_terminal,
so it'll simplify the usage of alacritty_terminal as a library,
since you won't link to system's libraries anymore. It also
moves many alacritty related config options from it.

Fixes #3393.
This commit is contained in:
Kirill Chibisov 2020-07-11 20:03:09 +03:00 committed by GitHub
parent 5f039cee49
commit 18cf806a27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 350 additions and 327 deletions

View file

@ -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` - 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 variable must now be set to `CellForeground` instead of omitting it
- URLs are no longer highlighted without a clearly delimited scheme - 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 ### Fixed
@ -71,6 +72,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ingoring of default FreeType properties - Ingoring of default FreeType properties
- Alacritty crashing at startup when the configured font does not exist - 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 ## 0.4.3
### Fixed ### Fixed

3
Cargo.lock generated
View file

@ -35,6 +35,7 @@ dependencies = [
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
@ -55,7 +56,6 @@ version = "0.5.0-dev"
dependencies = [ dependencies = [
"base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -36,6 +36,9 @@ xdg = "2"
[target.'cfg(not(target_os = "macos"))'.dependencies] [target.'cfg(not(target_os = "macos"))'.dependencies]
image = { version = "0.23.3", default-features = false, features = ["ico"] } 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] [target.'cfg(any(target_os = "macos", windows))'.dependencies]
dirs = "2.0.2" dirs = "2.0.2"

View file

@ -4,9 +4,11 @@ use std::path::PathBuf;
use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg}; use clap::{crate_authors, crate_description, crate_name, crate_version, App, Arg};
use log::{self, error, LevelFilter}; 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 alacritty_terminal::index::{Column, Line};
use crate::config::ui_config::Delta;
use crate::config::window::{Dimensions, DEFAULT_NAME};
use crate::config::Config; use crate::config::Config;
#[cfg(not(any(target_os = "macos", windows)))] #[cfg(not(any(target_os = "macos", windows)))]
@ -263,35 +265,42 @@ impl Options {
} }
if let Some(lcr) = self.live_config_reload { 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.shell = self.command.or(config.shell);
config.hold = self.hold; config.hold = self.hold;
config.set_dynamic_title(config.dynamic_title() && self.title.is_none()); let dynamic_title = config.ui_config.dynamic_title() && self.title.is_none();
config.window.dimensions = self.dimensions.unwrap_or(config.window.dimensions); config.ui_config.set_dynamic_title(dynamic_title);
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());
config.window.class.instance = self.class_instance.unwrap_or(config.window.class.instance); replace_if_some(&mut config.ui_config.window.dimensions, self.dimensions);
config.window.class.general = self.class_general.unwrap_or(config.window.class.general); 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.ui_config.debug.print_events |= self.print_events;
config.debug.log_level = max(config.debug.log_level, self.log_level); config.ui_config.debug.log_level = max(config.ui_config.debug.log_level, self.log_level);
config.debug.ref_test = self.ref_test || config.debug.ref_test; config.ui_config.debug.ref_test |= self.ref_test;
config.debug.persistent_logging = config.ui_config.debug.persistent_logging |= self.persistent_logging;
self.persistent_logging || config.debug.persistent_logging;
if config.debug.print_events { if config.ui_config.debug.print_events {
config.debug.log_level = max(config.debug.log_level, LevelFilter::Info); config.ui_config.debug.log_level =
max(config.ui_config.debug.log_level, LevelFilter::Info);
} }
config config
} }
} }
fn replace_if_some<T>(option: &mut T, value: Option<T>) {
if let Some(value) = value {
*option = value;
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::cli::Options; use crate::cli::Options;
@ -300,11 +309,11 @@ mod tests {
#[test] #[test]
fn dynamic_title_ignoring_options_by_default() { fn dynamic_title_ignoring_options_by_default() {
let config = Config::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); 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] #[test]
@ -315,16 +324,16 @@ mod tests {
options.title = Some("foo".to_owned()); options.title = Some("foo".to_owned());
let config = options.into_config(config); let config = options.into_config(config);
assert!(!config.dynamic_title()); assert!(!config.ui_config.dynamic_title());
} }
#[test] #[test]
fn dynamic_title_not_overridden_by_config() { fn dynamic_title_not_overridden_by_config() {
let mut config = Config::default(); 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); let config = Options::default().into_config(config);
assert!(config.dynamic_title()); assert!(config.ui_config.dynamic_title());
} }
} }

View file

@ -1,7 +1,7 @@
use log::{error, LevelFilter}; use log::{error, LevelFilter};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use crate::config::{failure_default, LOG_TARGET_CONFIG}; use alacritty_terminal::config::{failure_default, LOG_TARGET_CONFIG};
/// Debugging options. /// Debugging options.
#[serde(default)] #[serde(default)]

View file

@ -5,9 +5,11 @@ use log::error;
use serde::de::Visitor; use serde::de::Visitor;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use alacritty_terminal::config::{failure_default, LOG_TARGET_CONFIG};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use crate::config::DefaultTrueBool; use crate::config::ui_config::DefaultTrueBool;
use crate::config::{failure_default, Delta, LOG_TARGET_CONFIG}; use crate::config::ui_config::Delta;
/// Font config. /// Font config.
/// ///

View file

@ -11,9 +11,12 @@ use log::{error, warn};
use alacritty_terminal::config::{Config as TermConfig, LOG_TARGET_CONFIG}; use alacritty_terminal::config::{Config as TermConfig, LOG_TARGET_CONFIG};
mod bindings; mod bindings;
pub mod debug;
pub mod font;
pub mod monitor; pub mod monitor;
mod mouse; mod mouse;
mod ui_config; pub mod ui_config;
pub mod window;
pub use crate::config::bindings::{Action, Binding, Key, ViAction}; pub use crate::config::bindings::{Action, Binding, Key, ViAction};
#[cfg(test)] #[cfg(test)]
@ -172,27 +175,6 @@ fn parse_config(contents: &str) -> Result<Config> {
} }
fn print_deprecation_warnings(config: &Config) { 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() { if config.scrolling.faux_multiplier().is_some() {
warn!( warn!(
target: LOG_TARGET_CONFIG, target: LOG_TARGET_CONFIG,
@ -224,6 +206,13 @@ fn print_deprecation_warnings(config: &Config) {
"Config visual_bell has been deprecated; please use bell instead" "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)] #[cfg(test)]

View file

@ -1,13 +1,24 @@
use log::error; use log::error;
use serde::{Deserialize, Deserializer}; 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::bindings::{self, Binding, KeyBinding, MouseBinding};
use crate::config::debug::Debug;
use crate::config::font::Font;
use crate::config::mouse::Mouse; use crate::config::mouse::Mouse;
use crate::config::window::WindowConfig;
#[derive(Debug, PartialEq, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
pub struct UIConfig { 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")] #[serde(default, deserialize_with = "failure_default")]
pub mouse: Mouse, pub mouse: Mouse,
@ -18,18 +29,79 @@ pub struct UIConfig {
/// Bindings for the mouse. /// Bindings for the mouse.
#[serde(default = "default_mouse_bindings", deserialize_with = "deserialize_mouse_bindings")] #[serde(default = "default_mouse_bindings", deserialize_with = "deserialize_mouse_bindings")]
pub mouse_bindings: Vec<MouseBinding>, pub mouse_bindings: Vec<MouseBinding>,
/// 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<bool>,
} }
impl Default for UIConfig { impl Default for UIConfig {
fn default() -> Self { fn default() -> Self {
UIConfig { UIConfig {
mouse: Mouse::default(), font: Default::default(),
window: Default::default(),
mouse: Default::default(),
key_bindings: default_key_bindings(), key_bindings: default_key_bindings(),
mouse_bindings: default_mouse_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<KeyBinding> { fn default_key_bindings() -> Vec<KeyBinding> {
bindings::default_key_bindings() bindings::default_key_bindings()
} }
@ -83,3 +155,24 @@ where
Ok(bindings) 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<T: Default + PartialEq + Eq> {
/// Horizontal change.
#[serde(deserialize_with = "failure_default")]
pub x: T,
/// Vertical change.
#[serde(deserialize_with = "failure_default")]
pub y: T,
}

View file

@ -4,8 +4,10 @@ use log::error;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_yaml::Value; use serde_yaml::Value;
use crate::config::{failure_default, option_explicit_none, Delta, LOG_TARGET_CONFIG}; use alacritty_terminal::config::{failure_default, option_explicit_none, LOG_TARGET_CONFIG};
use crate::index::{Column, Line}; use alacritty_terminal::index::{Column, Line};
use crate::config::ui_config::{DefaultTrueBool, Delta};
/// Default Alacritty name, used for window title and class. /// Default Alacritty name, used for window title and class.
pub const DEFAULT_NAME: &str = "Alacritty"; pub const DEFAULT_NAME: &str = "Alacritty";
@ -35,7 +37,7 @@ pub struct WindowConfig {
/// Startup mode. /// Startup mode.
#[serde(deserialize_with = "failure_default")] #[serde(deserialize_with = "failure_default")]
startup_mode: StartupMode, pub startup_mode: StartupMode,
/// Window title. /// Window title.
#[serde(default = "default_title")] #[serde(default = "default_title")]
@ -53,9 +55,9 @@ pub struct WindowConfig {
#[serde(deserialize_with = "option_explicit_none")] #[serde(deserialize_with = "option_explicit_none")]
pub gtk_theme_variant: Option<String>, pub gtk_theme_variant: Option<String>,
// TODO: DEPRECATED /// Use dynamic title.
#[serde(deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub start_maximized: Option<bool>, dynamic_title: DefaultTrueBool,
} }
pub fn default_title() -> String { pub fn default_title() -> String {
@ -63,11 +65,14 @@ pub fn default_title() -> String {
} }
impl WindowConfig { impl WindowConfig {
pub fn startup_mode(&self) -> StartupMode { #[inline]
match self.start_maximized { pub fn dynamic_title(&self) -> bool {
Some(true) => StartupMode::Maximized, self.dynamic_title.0
_ => self.startup_mode,
} }
#[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(), class: Default::default(),
embed: Default::default(), embed: Default::default(),
gtk_theme_variant: Default::default(), gtk_theme_variant: Default::default(),
start_maximized: Default::default(),
title: default_title(), title: default_title(),
dynamic_title: Default::default(),
} }
} }
} }

View file

@ -22,19 +22,23 @@ use wayland_client::{Display as WaylandDisplay, EventQueue};
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
use font::set_font_smoothing; 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}; use alacritty_terminal::event::{EventListener, OnResize};
#[cfg(not(windows))]
use alacritty_terminal::grid::Dimensions; use alacritty_terminal::grid::Dimensions;
use alacritty_terminal::index::{Column, Line, Point}; use alacritty_terminal::index::Line;
use alacritty_terminal::message_bar::MessageBuffer; #[cfg(not(windows))]
use alacritty_terminal::meter::Meter; use alacritty_terminal::index::{Column, Point};
use alacritty_terminal::selection::Selection; use alacritty_terminal::selection::Selection;
use alacritty_terminal::term::{RenderableCell, SizeInfo, Term, TermMode}; use alacritty_terminal::term::{RenderableCell, SizeInfo, Term, TermMode};
use crate::config::font::Font;
use crate::config::window::StartupMode;
use crate::config::Config; use crate::config::Config;
use crate::event::Mouse; use crate::event::Mouse;
use crate::message_bar::MessageBuffer;
use crate::meter::Meter;
use crate::renderer::rects::{RenderLines, RenderRect}; use crate::renderer::rects::{RenderLines, RenderRect};
use crate::renderer::{self, GlyphCache, QuadRenderer}; use crate::renderer::{self, GlyphCache, QuadRenderer};
use crate::url::{Url, Urls}; use crate::url::{Url, Urls};
@ -167,10 +171,15 @@ impl Display {
event_loop.available_monitors().next().map(|m| m.scale_factor()).unwrap_or(1.); event_loop.available_monitors().next().map(|m| m.scale_factor()).unwrap_or(1.);
// Guess the target window dimensions. // 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 (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 DPR: {}", estimated_dpr);
debug!("Estimated Cell Size: {} x {}", cell_width, cell_height); debug!("Estimated Cell Size: {} x {}", cell_width, cell_height);
@ -212,11 +221,12 @@ impl Display {
let (glyph_cache, cell_width, cell_height) = let (glyph_cache, cell_width, cell_height) =
Self::new_glyph_cache(dpr, &mut renderer, config)?; Self::new_glyph_cache(dpr, &mut renderer, config)?;
let mut padding_x = f32::from(config.window.padding.x) * dpr as f32; let padding = config.ui_config.window.padding;
let mut padding_y = f32::from(config.window.padding.y) * dpr as f32; 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)) = 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(); let PhysicalSize { width: w, height: h } = window.inner_size();
if w == width && h == height { if w == width && h == height {
@ -224,7 +234,7 @@ impl Display {
} else { } else {
window.set_inner_size(PhysicalSize::new(width, height)); 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. // Make sure additional padding is spread evenly.
padding_x = dynamic_padding(padding_x, viewport_size.width as f32, cell_width); 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); padding_y = dynamic_padding(padding_y, viewport_size.height as f32, cell_height);
@ -252,13 +262,13 @@ impl Display {
// Clear screen. // Clear screen.
let background_color = config.colors.primary.background; 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); api.clear(background_color);
}); });
// Set subpixel anti-aliasing. // Set subpixel anti-aliasing.
#[cfg(target_os = "macos")] #[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)))] #[cfg(not(any(target_os = "macos", windows)))]
let is_x11 = event_loop.is_x11(); let is_x11 = event_loop.is_x11();
@ -269,7 +279,7 @@ impl Display {
// actually draw something into it and commit those changes. // actually draw something into it and commit those changes.
if is_x11 { if is_x11 {
window.swap_buffers(); window.swap_buffers();
renderer.with_api(&config, &size_info, |api| { renderer.with_api(&config.ui_config, config.cursor, &size_info, |api| {
api.finish(); api.finish();
}); });
} }
@ -281,12 +291,12 @@ impl Display {
// //
// TODO: replace `set_position` with `with_position` once available. // TODO: replace `set_position` with `with_position` once available.
// Upstream issue: https://github.com/rust-windowing/winit/issues/806. // 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))); window.set_outer_position(PhysicalPosition::from((position.x, position.y)));
} }
#[allow(clippy::single_match)] #[allow(clippy::single_match)]
match config.window.startup_mode() { match config.ui_config.window.startup_mode {
StartupMode::Fullscreen => window.set_fullscreen(true), StartupMode::Fullscreen => window.set_fullscreen(true),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
StartupMode::SimpleFullscreen => window.set_simple_fullscreen(true), StartupMode::SimpleFullscreen => window.set_simple_fullscreen(true),
@ -315,8 +325,8 @@ impl Display {
renderer: &mut QuadRenderer, renderer: &mut QuadRenderer,
config: &Config, config: &Config,
) -> Result<(GlyphCache, f32, f32), Error> { ) -> Result<(GlyphCache, f32, f32), Error> {
let font = config.font.clone(); let font = config.ui_config.font.clone();
let rasterizer = font::Rasterizer::new(dpr as f32, config.font.use_thin_strokes())?; let rasterizer = Rasterizer::new(dpr as f32, config.ui_config.font.use_thin_strokes())?;
// Initialize glyph cache. // Initialize glyph cache.
let glyph_cache = { let glyph_cache = {
@ -387,8 +397,9 @@ impl Display {
let cell_height = self.size_info.cell_height; let cell_height = self.size_info.cell_height;
// Recalculate padding. // Recalculate padding.
let mut padding_x = f32::from(config.window.padding.x) * self.size_info.dpr as f32; let padding = config.ui_config.window.padding;
let mut padding_y = f32::from(config.window.padding.y) * self.size_info.dpr as f32; 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. // Update the window dimensions.
if let Some(size) = update_pending.dimensions() { if let Some(size) = update_pending.dimensions() {
@ -398,7 +409,7 @@ impl Display {
} }
// Distribute excess padding equally on all sides. // 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_x = dynamic_padding(padding_x, self.size_info.width, cell_width);
padding_y = dynamic_padding(padding_y, self.size_info.height, cell_height); 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 as early as possible to free lock.
drop(terminal); 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); api.clear(background_color);
}); });
@ -491,7 +502,7 @@ impl Display {
{ {
let _sampler = self.meter.sampler(); 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. // Iterate over all non-empty cells in the grid.
for cell in grid_cells { for cell in grid_cells {
// Update URL underlines. // Update URL underlines.
@ -566,7 +577,7 @@ impl Display {
// Relay messages to the user. // Relay messages to the user.
let fg = config.colors.primary.background; let fg = config.colors.primary.background;
for (i, message_text) in text.iter().rev().enumerate() { 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( api.render_string(
glyph_cache, glyph_cache,
Line(size_info.lines().saturating_sub(i + 1)), 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 // 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 // will block to synchronize (this is `glClear` in Alacritty), which causes a
// permanent one frame delay. // 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(); api.finish();
}); });
} }
@ -650,14 +661,14 @@ impl Display {
let fg = config.colors.search_bar_foreground(); let fg = config.colors.search_bar_foreground();
let bg = config.colors.search_bar_background(); let bg = config.colors.search_bar_background();
let line = size_info.lines() - message_bar_lines - 1; 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)); api.render_string(glyph_cache, line, &text, fg, Some(bg));
}); });
} }
/// Draw render timer. /// Draw render timer.
fn draw_render_timer(&mut self, config: &Config, size_info: &SizeInfo) { fn draw_render_timer(&mut self, config: &Config, size_info: &SizeInfo) {
if !config.render_timer() { if !config.ui_config.debug.render_timer {
return; return;
} }
let glyph_cache = &mut self.glyph_cache; let glyph_cache = &mut self.glyph_cache;
@ -666,7 +677,7 @@ impl Display {
let fg = config.colors.normal().black; let fg = config.colors.normal().black;
let bg = config.colors.normal().red; 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)); 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. /// Calculate the cell dimensions based on font metrics.
#[inline] #[inline]
fn compute_cell_size(config: &Config, metrics: &font::Metrics) -> (f32, f32) { fn compute_cell_size(config: &Config, metrics: &font::Metrics) -> (f32, f32) {
let offset_x = f64::from(config.font.offset.x); let offset_x = f64::from(config.ui_config.font.offset.x);
let offset_y = f64::from(config.font.offset.y); let offset_y = f64::from(config.ui_config.font.offset.y);
( (
((metrics.average_advance + offset_x) as f32).floor().max(1.), ((metrics.average_advance + offset_x) as f32).floor().max(1.),
((metrics.line_height + offset_y) as f32).floor().max(1.), ((metrics.line_height + offset_y) as f32).floor().max(1.),

View file

@ -32,7 +32,6 @@ use alacritty_terminal::config::LOG_TARGET_CONFIG;
use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify, OnResize}; use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify, OnResize};
use alacritty_terminal::grid::{Dimensions, Scroll}; use alacritty_terminal::grid::{Dimensions, Scroll};
use alacritty_terminal::index::{Column, Direction, Line, Point, Side}; 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::selection::{Selection, SelectionType};
use alacritty_terminal::sync::FairMutex; use alacritty_terminal::sync::FairMutex;
use alacritty_terminal::term::cell::Cell; use alacritty_terminal::term::cell::Cell;
@ -47,6 +46,7 @@ use crate::config::Config;
use crate::daemon::start_daemon; use crate::daemon::start_daemon;
use crate::display::{Display, DisplayUpdate}; use crate::display::{Display, DisplayUpdate};
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
use crate::message_bar::{Message, MessageBuffer};
use crate::scheduler::{Scheduler, TimerId}; use crate::scheduler::{Scheduler, TimerId};
use crate::url::{Url, Urls}; use crate::url::{Url, Urls};
use crate::window::Window; use crate::window::Window;
@ -312,14 +312,14 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
fn change_font_size(&mut self, delta: f32) { fn change_font_size(&mut self, delta: f32) {
*self.font_size = max(*self.font_size + delta, Size::new(FONT_SIZE_STEP)); *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.display_update_pending.set_font(font);
self.terminal.dirty = true; self.terminal.dirty = true;
} }
fn reset_font_size(&mut self) { fn reset_font_size(&mut self) {
*self.font_size = self.config.font.size; *self.font_size = self.config.ui_config.font.size;
self.display_update_pending.set_font(self.config.font.clone()); self.display_update_pending.set_font(self.config.ui_config.font.clone());
self.terminal.dirty = true; self.terminal.dirty = true;
} }
@ -636,7 +636,7 @@ impl<N: Notify + OnResize> Processor<N> {
received_count: 0, received_count: 0,
suppress_chars: false, suppress_chars: false,
modifiers: Default::default(), modifiers: Default::default(),
font_size: config.font.size, font_size: config.ui_config.font.size,
config, config,
message_buffer, message_buffer,
display, display,
@ -679,7 +679,7 @@ impl<N: Notify + OnResize> Processor<N> {
let mut scheduler = Scheduler::new(); let mut scheduler = Scheduler::new();
event_loop.run_return(|event, event_loop, control_flow| { 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); info!("glutin event: {:?}", event);
} }
@ -791,7 +791,7 @@ impl<N: Notify + OnResize> Processor<N> {
}); });
// Write ref tests to disk. // 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()); self.write_ref_test_results(&terminal.lock());
} }
} }
@ -811,7 +811,7 @@ impl<N: Notify + OnResize> Processor<N> {
let display_update_pending = &mut processor.ctx.display_update_pending; let display_update_pending = &mut processor.ctx.display_update_pending;
// Push current font to update its DPR. // 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)); 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. // Resize to event's dimensions, since no resize event is emitted on Wayland.
@ -829,7 +829,18 @@ impl<N: Notify + OnResize> Processor<N> {
Event::ConfigReload(path) => Self::reload_config(&path, processor), Event::ConfigReload(path) => Self::reload_config(&path, processor),
Event::Scroll(scroll) => processor.ctx.scroll(scroll), Event::Scroll(scroll) => processor.ctx.scroll(scroll),
Event::TerminalEvent(event) => match event { 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::Wakeup => processor.ctx.terminal.dirty = true,
TerminalEvent::Bell => { TerminalEvent::Bell => {
let bell_command = processor.ctx.config.bell().command.as_ref(); let bell_command = processor.ctx.config.bell().command.as_ref();
@ -983,16 +994,23 @@ impl<N: Notify + OnResize> Processor<N> {
processor.ctx.display_update_pending.set_cursor_dirty(); 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. // Do not update font size if it has been changed at runtime.
if *processor.ctx.font_size == processor.ctx.config.font.size { if *processor.ctx.font_size == processor.ctx.config.ui_config.font.size {
*processor.ctx.font_size = 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); 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)))] #[cfg(not(any(target_os = "macos", windows)))]
{ {
if processor.ctx.event_loop.is_wayland() { if processor.ctx.event_loop.is_wayland() {
@ -1002,7 +1020,7 @@ impl<N: Notify + OnResize> Processor<N> {
// Set subpixel anti-aliasing. // Set subpixel anti-aliasing.
#[cfg(target_os = "macos")] #[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; *processor.ctx.config = config;

View file

@ -26,7 +26,6 @@ use alacritty_terminal::ansi::{ClearMode, Handler};
use alacritty_terminal::event::EventListener; use alacritty_terminal::event::EventListener;
use alacritty_terminal::grid::{Dimensions, Scroll}; use alacritty_terminal::grid::{Dimensions, Scroll};
use alacritty_terminal::index::{Column, Direction, Line, Point, Side}; use alacritty_terminal::index::{Column, Direction, Line, Point, Side};
use alacritty_terminal::message_bar::{self, Message};
use alacritty_terminal::selection::SelectionType; use alacritty_terminal::selection::SelectionType;
use alacritty_terminal::term::mode::TermMode; use alacritty_terminal::term::mode::TermMode;
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term}; 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::config::{Action, Binding, Config, Key, ViAction};
use crate::daemon::start_daemon; use crate::daemon::start_daemon;
use crate::event::{ClickState, Event, Mouse, TYPING_SEARCH_DELAY}; use crate::event::{ClickState, Event, Mouse, TYPING_SEARCH_DELAY};
use crate::message_bar::{self, Message};
use crate::scheduler::{Scheduler, TimerId}; use crate::scheduler::{Scheduler, TimerId};
use crate::url::{Url, Urls}; use crate::url::{Url, Urls};
use crate::window::Window; use crate::window::Window;
@ -894,7 +894,7 @@ impl<'a, T: EventListener, A: ActionContext<T>> Processor<'a, T, A> {
c.encode_utf8(&mut bytes[..]); 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.received_count() == 0
&& self.ctx.modifiers().alt() && self.ctx.modifiers().alt()
&& utf8_len == 1 && utf8_len == 1
@ -1088,10 +1088,10 @@ mod tests {
use glutin::event::{Event as GlutinEvent, VirtualKeyCode, WindowEvent}; use glutin::event::{Event as GlutinEvent, VirtualKeyCode, WindowEvent};
use alacritty_terminal::event::Event as TerminalEvent; use alacritty_terminal::event::Event as TerminalEvent;
use alacritty_terminal::message_bar::MessageBuffer;
use alacritty_terminal::selection::Selection; use alacritty_terminal::selection::Selection;
use crate::config::ClickHandler; use crate::config::ClickHandler;
use crate::message_bar::MessageBuffer;
const KEY: VirtualKeyCode = VirtualKeyCode::Key0; const KEY: VirtualKeyCode = VirtualKeyCode::Key0;

View file

@ -9,6 +9,7 @@ use std::str;
use libc::{setlocale, LC_ALL, LC_CTYPE}; use libc::{setlocale, LC_ALL, LC_CTYPE};
use log::debug; use log::debug;
use objc::runtime::{Class, Object}; use objc::runtime::{Class, Object};
use objc::{msg_send, sel, sel_impl};
const FALLBACK_LOCALE: &str = "UTF-8"; const FALLBACK_LOCALE: &str = "UTF-8";

View file

@ -15,11 +15,11 @@ use std::sync::{Arc, Mutex};
use glutin::event_loop::EventLoopProxy; use glutin::event_loop::EventLoopProxy;
use log::{self, Level}; use log::{self, Level};
use alacritty_terminal::message_bar::Message;
use alacritty_terminal::term::color; use alacritty_terminal::term::color;
use crate::cli::Options; use crate::cli::Options;
use crate::event::Event; use crate::event::Event;
use crate::message_bar::Message;
const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG"; const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG";

View file

@ -1,7 +1,6 @@
//! Alacritty - The GPU Enhanced Terminal. //! Alacritty - The GPU Enhanced Terminal.
#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)] #![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_attr(all(test, feature = "bench"), feature(test))]
// With the default subsystem, 'console', windows creates an additional console // With the default subsystem, 'console', windows creates an additional console
// window for the program. // window for the program.
@ -24,10 +23,6 @@ use log::{error, info};
use winapi::um::wincon::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; use winapi::um::wincon::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS};
use alacritty_terminal::event_loop::{self, EventLoop, Msg}; 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::sync::FairMutex;
use alacritty_terminal::term::Term; use alacritty_terminal::term::Term;
use alacritty_terminal::tty; use alacritty_terminal::tty;
@ -40,7 +35,13 @@ mod daemon;
mod display; mod display;
mod event; mod event;
mod input; mod input;
#[cfg(target_os = "macos")]
mod locale;
mod logging; mod logging;
mod message_bar;
mod meter;
#[cfg(windows)]
mod panic;
mod renderer; mod renderer;
mod scheduler; mod scheduler;
mod url; mod url;
@ -59,8 +60,10 @@ use crate::config::monitor::Monitor;
use crate::config::Config; use crate::config::Config;
use crate::display::Display; use crate::display::Display;
use crate::event::{Event, EventProxy, Processor}; use crate::event::{Event, EventProxy, Processor};
use crate::message_bar::MessageBuffer;
fn main() { fn main() {
#[cfg(windows)]
panic::attach_handler(); panic::attach_handler();
// When linked with the windows subsystem windows won't automatically attach // When linked with the windows subsystem windows won't automatically attach
@ -87,7 +90,7 @@ fn main() {
let config = options.into_config(config); let config = options.into_config(config);
// Update the log level from 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. // Switch to home directory.
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -97,7 +100,7 @@ fn main() {
locale::set_locale_environment(); locale::set_locale_environment();
// Store if log file should be deleted before moving config. // 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. // Run Alacritty.
if let Err(err) = run(window_event_loop, config) { if let Err(err) = run(window_event_loop, config) {
@ -161,7 +164,13 @@ fn run(window_event_loop: GlutinEventLoop<Event>, config: Config) -> Result<(),
// renderer and input processing. Note that access to the terminal state is // renderer and input processing. Note that access to the terminal state is
// synchronized since the I/O loop updates the state, and the display // synchronized since the I/O loop updates the state, and the display
// consumes it periodically. // 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 // The event loop channel allows write requests from the event processor
// to be sent to the pty loop and ultimately written to the pty. // to be sent to the pty loop and ultimately written to the pty.
@ -171,7 +180,7 @@ fn run(window_event_loop: GlutinEventLoop<Event>, config: Config) -> Result<(),
// //
// The monitor watches the config file for changes and reloads it. Pending // The monitor watches the config file for changes and reloads it. Pending
// config changes are processed in the main loop. // 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())); config.config_path.as_ref().map(|path| Monitor::new(path, event_proxy.clone()));
} }

View file

@ -1,7 +1,7 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use crate::term::color::Rgb; use alacritty_terminal::term::color::Rgb;
use crate::term::SizeInfo; use alacritty_terminal::term::SizeInfo;
pub const CLOSE_BUTTON_TEXT: &str = "[X]"; pub const CLOSE_BUTTON_TEXT: &str = "[X]";
const CLOSE_BUTTON_PADDING: usize = 1; const CLOSE_BUTTON_PADDING: usize = 1;
@ -161,7 +161,7 @@ impl MessageBuffer {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Message, MessageBuffer, MIN_FREE_LINES}; use super::{Message, MessageBuffer, MIN_FREE_LINES};
use crate::term::{color, SizeInfo}; use alacritty_terminal::term::{color, SizeInfo};
#[test] #[test]
fn appends_close_button() { fn appends_close_button() {

View file

@ -1,13 +1,7 @@
#[cfg(windows)] use alacritty_terminal::tty::windows::win32_string;
use crate::tty::windows::win32_string;
// Use the default behavior of the other platforms.
#[cfg(not(windows))]
pub fn attach_handler() {}
// Install a panic handler that renders the panic in a classical Windows error // Install a panic handler that renders the panic in a classical Windows error
// dialog box as well as writes the panic to STDERR. // dialog box as well as writes the panic to STDERR.
#[cfg(windows)]
pub fn attach_handler() { pub fn attach_handler() {
use std::{io, io::Write, panic, ptr}; use std::{io, io::Write, panic, ptr};
use winapi::um::winuser; use winapi::um::winuser;

View file

@ -1,4 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::{self, Display, Formatter};
use std::fs; use std::fs;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::io; use std::io;
@ -10,7 +11,8 @@ use std::time::Duration;
use fnv::FnvHasher; use fnv::FnvHasher;
use font::{ 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 log::{error, info};
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
@ -19,16 +21,19 @@ use crate::cursor;
use crate::gl; use crate::gl;
use crate::gl::types::*; use crate::gl::types::*;
use crate::renderer::rects::RenderRect; 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::index::{Column, Line};
use alacritty_terminal::term::cell::{self, Flags}; use alacritty_terminal::term::cell::{self, Flags};
use alacritty_terminal::term::color::Rgb; 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 alacritty_terminal::thread;
use std::fmt::{self, Display, Formatter};
pub mod rects; 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. // Shader paths for live reload.
static TEXT_SHADER_F_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../res/text.f.glsl"); 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"); static TEXT_SHADER_V_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../res/text.v.glsl");
@ -173,7 +178,7 @@ pub struct GlyphCache {
impl GlyphCache { impl GlyphCache {
pub fn new<L>( pub fn new<L>(
mut rasterizer: Rasterizer, mut rasterizer: Rasterizer,
font: &config::Font, font: &Font,
loader: &mut L, loader: &mut L,
) -> Result<GlyphCache, font::Error> ) -> Result<GlyphCache, font::Error>
where where
@ -215,14 +220,13 @@ impl GlyphCache {
/// Computes font keys for (Regular, Bold, Italic, Bold Italic). /// Computes font keys for (Regular, Bold, Italic, Bold Italic).
fn compute_font_keys( fn compute_font_keys(
font: &config::Font, font: &Font,
rasterizer: &mut Rasterizer, rasterizer: &mut Rasterizer,
) -> Result<(FontKey, FontKey, FontKey, FontKey), font::Error> { ) -> Result<(FontKey, FontKey, FontKey, FontKey), font::Error> {
let size = font.size; let size = font.size;
// Load regular font. // Load regular font.
let regular_desc = let regular_desc = Self::make_desc(&font.normal(), Slant::Normal, Weight::Normal);
Self::make_desc(&font.normal(), font::Slant::Normal, font::Weight::Normal);
let regular = Self::load_regular_font(rasterizer, &regular_desc, size)?; let regular = Self::load_regular_font(rasterizer, &regular_desc, size)?;
@ -236,19 +240,17 @@ impl GlyphCache {
}; };
// Load bold font. // 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); let bold = load_or_regular(bold_desc);
// Load italic font. // Load italic font.
let italic_desc = let italic_desc = Self::make_desc(&font.italic(), Slant::Italic, Weight::Normal);
Self::make_desc(&font.italic(), font::Slant::Italic, font::Weight::Normal);
let italic = load_or_regular(italic_desc); let italic = load_or_regular(italic_desc);
// Load bold italic font. // Load bold italic font.
let bold_italic_desc = let bold_italic_desc = Self::make_desc(&font.bold_italic(), Slant::Italic, Weight::Bold);
Self::make_desc(&font.bold_italic(), font::Slant::Italic, font::Weight::Bold);
let bold_italic = load_or_regular(bold_italic_desc); let bold_italic = load_or_regular(bold_italic_desc);
@ -265,25 +267,18 @@ impl GlyphCache {
Err(err) => { Err(err) => {
error!("{}", err); error!("{}", err);
let fallback_desc = Self::make_desc( let fallback_desc =
&Font::default().normal(), Self::make_desc(&Font::default().normal(), Slant::Normal, Weight::Normal);
font::Slant::Normal,
font::Weight::Normal,
);
rasterizer.load_font(&fallback_desc, size) rasterizer.load_font(&fallback_desc, size)
}, },
} }
} }
fn make_desc( fn make_desc(desc: &FontDescription, slant: Slant, weight: Weight) -> FontDesc {
desc: &config::FontDescription,
slant: font::Slant,
weight: font::Weight,
) -> FontDesc {
let style = if let Some(ref spec) = desc.style { let style = if let Some(ref spec) = desc.style {
font::Style::Specific(spec.to_owned()) Style::Specific(spec.to_owned())
} else { } else {
font::Style::Description { slant, weight } Style::Description { slant, weight }
}; };
FontDesc::new(desc.family.clone(), style) FontDesc::new(desc.family.clone(), style)
} }
@ -318,7 +313,7 @@ impl GlyphCache {
pub fn update_font_size<L: LoadGlyph>( pub fn update_font_size<L: LoadGlyph>(
&mut self, &mut self,
font: &config::Font, font: &Font,
dpr: f64, dpr: f64,
loader: &mut L, loader: &mut L,
) -> Result<(), font::Error> { ) -> Result<(), font::Error> {
@ -361,31 +356,30 @@ impl GlyphCache {
/// Calculate font metrics without access to a glyph cache. /// Calculate font metrics without access to a glyph cache.
pub fn static_metrics(font: Font, dpr: f64) -> Result<font::Metrics, font::Error> { pub fn static_metrics(font: Font, dpr: f64) -> Result<font::Metrics, font::Error> {
let mut rasterizer = font::Rasterizer::new(dpr as f32, font.use_thin_strokes())?; let mut rasterizer = font::Rasterizer::new(dpr as f32, font.use_thin_strokes())?;
let regular_desc = let regular_desc = GlyphCache::make_desc(&font.normal(), Slant::Normal, Weight::Normal);
GlyphCache::make_desc(&font.normal(), font::Slant::Normal, font::Weight::Normal);
let regular = Self::load_regular_font(&mut rasterizer, &regular_desc, font.size)?; let regular = Self::load_regular_font(&mut rasterizer, &regular_desc, font.size)?;
rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?; rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?;
rasterizer.metrics(regular, font.size) rasterizer.metrics(regular, font.size)
} }
pub fn calculate_dimensions<C>( pub fn calculate_dimensions(
config: &Config<C>, window_config: &WindowConfig,
dpr: f64, dpr: f64,
cell_width: f32, cell_width: f32,
cell_height: f32, cell_height: f32,
) -> Option<(u32, u32)> { ) -> Option<(u32, u32)> {
let dimensions = config.window.dimensions; let dimensions = window_config.dimensions;
if dimensions.columns_u32() == 0 if dimensions.columns_u32() == 0
|| dimensions.lines_u32() == 0 || dimensions.lines_u32() == 0
|| config.window.startup_mode() != StartupMode::Windowed || window_config.startup_mode != StartupMode::Windowed
{ {
return None; return None;
} }
let padding_x = f64::from(config.window.padding.x) * dpr; let padding_x = f64::from(window_config.padding.x) * dpr;
let padding_y = f64::from(config.window.padding.y) * dpr; let padding_y = f64::from(window_config.padding.y) * dpr;
// Calculate new size based on cols/lines specified in config. // Calculate new size based on cols/lines specified in config.
let grid_width = cell_width as u32 * dimensions.columns_u32(); let grid_width = cell_width as u32 * dimensions.columns_u32();
@ -446,13 +440,14 @@ pub struct QuadRenderer {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct RenderApi<'a, C> { pub struct RenderApi<'a> {
active_tex: &'a mut GLuint, active_tex: &'a mut GLuint,
batch: &'a mut Batch, batch: &'a mut Batch,
atlas: &'a mut Vec<Atlas>, atlas: &'a mut Vec<Atlas>,
current_atlas: &'a mut usize, current_atlas: &'a mut usize,
program: &'a mut TextShaderProgram, program: &'a mut TextShaderProgram,
config: &'a Config<C>, config: &'a UIConfig,
cursor_config: Cursor,
} }
#[derive(Debug)] #[derive(Debug)]
@ -730,7 +725,7 @@ impl QuadRenderer {
} }
/// Draw all rectangles simultaneously to prevent excessive program swaps. /// Draw all rectangles simultaneously to prevent excessive program swaps.
pub fn draw_rects(&mut self, props: &term::SizeInfo, rects: Vec<RenderRect>) { pub fn draw_rects(&mut self, props: &SizeInfo, rects: Vec<RenderRect>) {
// Swap to rectangle rendering program. // Swap to rectangle rendering program.
unsafe { unsafe {
// Swap program. // Swap program.
@ -783,9 +778,15 @@ impl QuadRenderer {
} }
} }
pub fn with_api<F, T, C>(&mut self, config: &Config<C>, props: &term::SizeInfo, func: F) -> T pub fn with_api<F, T>(
&mut self,
config: &UIConfig,
cursor_config: Cursor,
props: &SizeInfo,
func: F,
) -> T
where where
F: FnOnce(RenderApi<'_, C>) -> T, F: FnOnce(RenderApi<'_>) -> T,
{ {
// Flush message queue. // Flush message queue.
if let Ok(Msg::ShaderReload) = self.rx.try_recv() { if let Ok(Msg::ShaderReload) = self.rx.try_recv() {
@ -810,6 +811,7 @@ impl QuadRenderer {
current_atlas: &mut self.current_atlas, current_atlas: &mut self.current_atlas,
program: &mut self.program, program: &mut self.program,
config, config,
cursor_config,
}); });
unsafe { 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..."); info!("Reloading shaders...");
let result = (TextShaderProgram::new(), RectShaderProgram::new()); let result = (TextShaderProgram::new(), RectShaderProgram::new());
let (program, rect_program) = match result { let (program, rect_program) = match result {
@ -888,7 +890,7 @@ impl QuadRenderer {
/// Render a rectangle. /// Render a rectangle.
/// ///
/// This requires the rectangle program to be activated. /// 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. // Do nothing when alpha is fully transparent.
if rect.alpha == 0. { if rect.alpha == 0. {
return; return;
@ -923,7 +925,7 @@ impl QuadRenderer {
} }
} }
impl<'a, C> RenderApi<'a, C> { impl<'a> RenderApi<'a> {
pub fn clear(&self, color: Rgb) { pub fn clear(&self, color: Rgb) {
unsafe { unsafe {
let alpha = self.config.background_opacity(); 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.x,
self.config.font.offset.y, self.config.font.offset.y,
cursor_key.is_wide, cursor_key.is_wide,
self.config.cursor.thickness(), self.cursor_config.thickness(),
)) ))
}); });
self.add_render_item(cell, glyph); 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 { fn load_glyph(&mut self, rasterized: &RasterizedGlyph) -> Glyph {
load_glyph(self.active_tex, self.atlas, self.current_atlas, rasterized) 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) { fn drop(&mut self) {
if !self.batch.is_empty() { if !self.batch.is_empty() {
self.render_batch(); 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 { unsafe {
gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height); gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height);
} }

View file

@ -33,12 +33,12 @@ use glutin::{self, ContextBuilder, PossiblyCurrent, WindowedContext};
#[cfg(windows)] #[cfg(windows)]
use winapi::shared::minwindef::WORD; use winapi::shared::minwindef::WORD;
use alacritty_terminal::config::{Decorations, StartupMode, WindowConfig};
#[cfg(not(windows))] #[cfg(not(windows))]
use alacritty_terminal::index::Point; use alacritty_terminal::index::Point;
#[cfg(not(windows))] #[cfg(not(windows))]
use alacritty_terminal::term::SizeInfo; use alacritty_terminal::term::SizeInfo;
use crate::config::window::{Decorations, StartupMode, WindowConfig};
use crate::config::Config; use crate::config::Config;
use crate::gl; use crate::gl;
@ -154,7 +154,8 @@ impl Window {
size: Option<PhysicalSize<u32>>, size: Option<PhysicalSize<u32>>,
#[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue: Option<&EventQueue>, #[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue: Option<&EventQueue>,
) -> Result<Window> { ) -> Result<Window> {
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. // Disable vsync on Wayland.
#[cfg(not(any(target_os = "macos", windows)))] #[cfg(not(any(target_os = "macos", windows)))]
@ -180,7 +181,7 @@ impl Window {
{ {
if event_loop.is_x11() { if event_loop.is_x11() {
// On X11, embed the window inside another if the parent ID has been set. // 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); x_embed_window(windowed_context.window(), parent_window_id);
} }
} else { } else {
@ -265,7 +266,7 @@ impl Window {
.with_visible(false) .with_visible(false)
.with_transparent(true) .with_transparent(true)
.with_decorations(decorations) .with_decorations(decorations)
.with_maximized(window_config.startup_mode() == StartupMode::Maximized) .with_maximized(window_config.startup_mode == StartupMode::Maximized)
.with_window_icon(icon.ok()) .with_window_icon(icon.ok())
// X11. // X11.
.with_class(class.instance.clone(), class.general.clone()) .with_class(class.instance.clone(), class.general.clone())
@ -293,7 +294,7 @@ impl Window {
.with_visible(false) .with_visible(false)
.with_decorations(decorations) .with_decorations(decorations)
.with_transparent(true) .with_transparent(true)
.with_maximized(window_config.startup_mode() == StartupMode::Maximized) .with_maximized(window_config.startup_mode == StartupMode::Maximized)
.with_window_icon(icon.ok()) .with_window_icon(icon.ok())
} }
@ -303,7 +304,7 @@ impl Window {
.with_title(title) .with_title(title)
.with_visible(false) .with_visible(false)
.with_transparent(true) .with_transparent(true)
.with_maximized(window_config.startup_mode() == StartupMode::Maximized); .with_maximized(window_config.startup_mode == StartupMode::Maximized);
match window_config.decorations { match window_config.decorations {
Decorations::Full => window, Decorations::Full => window,

View file

@ -11,7 +11,6 @@ edition = "2018"
[dependencies] [dependencies]
libc = "0.2" libc = "0.2"
bitflags = "1" bitflags = "1"
font = { path = "../font", features = ["force_system_fontconfig"] }
parking_lot = "0.10.2" parking_lot = "0.10.2"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8" serde_yaml = "0.8"
@ -38,12 +37,8 @@ winapi = { version = "0.3.7", features = [
]} ]}
mio-anonymous-pipes = "0.1" mio-anonymous-pipes = "0.1"
[target.'cfg(target_os = "macos")'.dependencies]
objc = "0.2.2"
[features] [features]
default = ["winpty"] default = ["winpty"]
nightly = []
bench = [] bench = []
[dev-dependencies] [dev-dependencies]

View file

@ -8,19 +8,13 @@ use serde_yaml::Value;
mod bell; mod bell;
mod colors; mod colors;
mod debug;
mod font;
mod scrolling; mod scrolling;
mod window;
use crate::ansi::CursorStyle; use crate::ansi::CursorStyle;
pub use crate::config::bell::{BellAnimation, BellConfig}; pub use crate::config::bell::{BellAnimation, BellConfig};
pub use crate::config::colors::Colors; 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::scrolling::Scrolling;
pub use crate::config::window::{Decorations, Dimensions, StartupMode, WindowConfig, DEFAULT_NAME};
pub const LOG_TARGET_CONFIG: &str = "alacritty_config"; pub const LOG_TARGET_CONFIG: &str = "alacritty_config";
const MAX_SCROLLBACK_LINES: u32 = 100_000; const MAX_SCROLLBACK_LINES: u32 = 100_000;
@ -31,18 +25,10 @@ pub type MockConfig = Config<HashMap<String, serde_yaml::Value>>;
/// Top-level config type. /// Top-level config type.
#[derive(Debug, PartialEq, Default, Deserialize)] #[derive(Debug, PartialEq, Default, Deserialize)]
pub struct Config<T> { pub struct Config<T> {
/// Pixel padding.
#[serde(default, deserialize_with = "failure_default")]
pub padding: Option<Delta<u8>>,
/// TERM env variable. /// TERM env variable.
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub env: HashMap<String, String>, pub env: HashMap<String, String>,
/// Font configuration.
#[serde(default, deserialize_with = "failure_default")]
pub font: Font,
/// Should draw bold text with brighter colors instead of bold font. /// Should draw bold text with brighter colors instead of bold font.
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
draw_bold_text_with_bright_colors: bool, draw_bold_text_with_bright_colors: bool,
@ -50,14 +36,6 @@ pub struct Config<T> {
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub colors: Colors, 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")] #[serde(default, deserialize_with = "failure_default")]
pub selection: Selection, pub selection: Selection,
@ -73,14 +51,6 @@ pub struct Config<T> {
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
bell: BellConfig, 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. /// How much scrolling history to keep.
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub scrolling: Scrolling, pub scrolling: Scrolling,
@ -94,18 +64,10 @@ pub struct Config<T> {
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub winpty_backend: bool, pub winpty_backend: bool,
/// Send escape sequences using the alt key.
#[serde(default, deserialize_with = "failure_default")]
alt_send_esc: DefaultTrueBool,
/// Shell startup directory. /// Shell startup directory.
#[serde(default, deserialize_with = "option_explicit_none")] #[serde(default, deserialize_with = "option_explicit_none")]
pub working_directory: Option<PathBuf>, pub working_directory: Option<PathBuf>,
/// Debug options.
#[serde(default, deserialize_with = "failure_default")]
pub debug: Debug,
/// Additional configuration options not directly required by the terminal. /// Additional configuration options not directly required by the terminal.
#[serde(flatten)] #[serde(flatten)]
pub ui_config: T, pub ui_config: T,
@ -121,14 +83,6 @@ pub struct Config<T> {
// TODO: REMOVED // TODO: REMOVED
#[serde(default, deserialize_with = "failure_default")] #[serde(default, deserialize_with = "failure_default")]
pub tabspaces: Option<usize>, pub tabspaces: Option<usize>,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
pub render_timer: Option<bool>,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
pub persistent_logging: Option<bool>,
} }
impl<T> Config<T> { impl<T> Config<T> {
@ -137,50 +91,6 @@ impl<T> Config<T> {
self.draw_bold_text_with_bright_colors 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] #[inline]
pub fn bell(&self) -> &BellConfig { pub fn bell(&self) -> &BellConfig {
self.visual_bell.as_ref().unwrap_or(&self.bell) 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<T: Default + PartialEq + Eq> {
/// 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. /// Wrapper around f32 that represents a percentage value between 0.0 and 1.0.
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct Percentage(f32); pub struct Percentage(f32);
@ -320,6 +218,10 @@ impl Percentage {
value value
}) })
} }
pub fn as_f32(self) -> f32 {
self.0
}
} }
impl Default for Percentage { impl Default for Percentage {

View file

@ -8,6 +8,7 @@ use crate::term::{ClipboardType, SizeInfo};
pub enum Event { pub enum Event {
MouseCursorDirty, MouseCursorDirty,
Title(String), Title(String),
ResetTitle,
ClipboardStore(ClipboardType, String), ClipboardStore(ClipboardType, String),
ClipboardLoad(ClipboardType, Arc<dyn Fn(&str) -> String + Sync + Send + 'static>), ClipboardLoad(ClipboardType, Arc<dyn Fn(&str) -> String + Sync + Send + 'static>),
Wakeup, Wakeup,
@ -20,6 +21,7 @@ impl Debug for Event {
match self { match self {
Event::MouseCursorDirty => write!(f, "MouseCursorDirty"), Event::MouseCursorDirty => write!(f, "MouseCursorDirty"),
Event::Title(title) => write!(f, "Title({})", title), Event::Title(title) => write!(f, "Title({})", title),
Event::ResetTitle => write!(f, "ResetTitle"),
Event::ClipboardStore(ty, text) => write!(f, "ClipboardStore({:?}, {})", ty, text), Event::ClipboardStore(ty, text) => write!(f, "ClipboardStore({:?}, {})", ty, text),
Event::ClipboardLoad(ty, _) => write!(f, "ClipboardLoad({:?})", ty), Event::ClipboardLoad(ty, _) => write!(f, "ClipboardLoad({:?})", ty),
Event::Wakeup => write!(f, "Wakeup"), Event::Wakeup => write!(f, "Wakeup"),

View file

@ -15,7 +15,6 @@ use mio::{self, Events, PollOpt, Ready};
use mio_extras::channel::{self, Receiver, Sender}; use mio_extras::channel::{self, Receiver, Sender};
use crate::ansi; use crate::ansi;
use crate::config::Config;
use crate::event::{self, Event, EventListener}; use crate::event::{self, Event, EventListener};
use crate::sync::FairMutex; use crate::sync::FairMutex;
use crate::term::{SizeInfo, Term}; use crate::term::{SizeInfo, Term};
@ -155,11 +154,12 @@ where
U: EventListener + Send + 'static, U: EventListener + Send + 'static,
{ {
/// Create a new event loop. /// Create a new event loop.
pub fn new<V>( pub fn new(
terminal: Arc<FairMutex<Term<U>>>, terminal: Arc<FairMutex<Term<U>>>,
event_proxy: U, event_proxy: U,
pty: T, pty: T,
config: &Config<V>, hold: bool,
ref_test: bool,
) -> EventLoop<T, U> { ) -> EventLoop<T, U> {
let (tx, rx) = channel::channel(); let (tx, rx) = channel::channel();
EventLoop { EventLoop {
@ -169,8 +169,8 @@ where
rx, rx,
terminal, terminal,
event_proxy, event_proxy,
hold: config.hold, hold,
ref_test: config.debug.ref_test, ref_test,
} }
} }

View file

@ -1,24 +1,14 @@
//! Alacritty - The GPU Enhanced Terminal. //! Alacritty - The GPU Enhanced Terminal.
#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)] #![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_attr(all(test, feature = "bench"), feature(test))]
#[cfg(target_os = "macos")]
#[macro_use]
extern crate objc;
pub mod ansi; pub mod ansi;
pub mod config; pub mod config;
pub mod event; pub mod event;
pub mod event_loop; pub mod event_loop;
pub mod grid; pub mod grid;
pub mod index; 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 selection;
pub mod sync; pub mod sync;
pub mod term; pub mod term;

View file

@ -721,14 +721,8 @@ pub struct Term<T> {
/// Current title of the window. /// Current title of the window.
title: Option<String>, title: Option<String>,
/// 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 /// 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<Option<String>>, title_stack: Vec<Option<String>>,
/// Current forwards and backwards buffer search regexes. /// Current forwards and backwards buffer search regexes.
@ -777,11 +771,9 @@ impl<T> Term<T> {
cursor_style: None, cursor_style: None,
default_cursor_style: config.cursor.style, default_cursor_style: config.cursor.style,
vi_mode_cursor_style: config.cursor.vi_mode_style, vi_mode_cursor_style: config.cursor.vi_mode_style,
dynamic_title: config.dynamic_title(),
event_proxy, event_proxy,
is_focused: true, is_focused: true,
title: None, title: None,
default_title: config.window.title.clone(),
title_stack: Vec::new(), title_stack: Vec::new(),
selection: None, selection: None,
regex_search: None, regex_search: None,
@ -808,14 +800,12 @@ impl<T> Term<T> {
self.default_cursor_style = config.cursor.style; self.default_cursor_style = config.cursor.style;
self.vi_mode_cursor_style = config.cursor.vi_mode_style; self.vi_mode_cursor_style = config.cursor.vi_mode_style;
self.default_title = config.window.title.clone(); let title_event = match &self.title {
self.dynamic_title = config.dynamic_title(); Some(title) => Event::Title(title.clone()),
None => Event::ResetTitle,
};
if self.dynamic_title { self.event_proxy.send_event(title_event);
self.set_title(self.title.clone());
} else {
self.event_proxy.send_event(Event::Title(self.default_title.clone()));
}
if self.mode.contains(TermMode::ALT_SCREEN) { if self.mode.contains(TermMode::ALT_SCREEN) {
self.inactive_grid.update_history(config.scrolling.history() as usize); self.inactive_grid.update_history(config.scrolling.history() as usize);
@ -2167,10 +2157,12 @@ impl<T: EventListener> Handler for Term<T> {
self.title = title.clone(); self.title = title.clone();
if self.dynamic_title { let title_event = match title {
let title = title.unwrap_or_else(|| self.default_title.clone()); Some(title) => Event::Title(title),
self.event_proxy.send_event(Event::Title(title)); None => Event::ResetTitle,
} };
self.event_proxy.send_event(title_event);
} }
#[inline] #[inline]

View file

@ -125,8 +125,7 @@ pub fn new<C>(config: &Config<C>, size: &SizeInfo, _window_id: Option<usize>) ->
let mut startup_info_ex: STARTUPINFOEXW = Default::default(); let mut startup_info_ex: STARTUPINFOEXW = Default::default();
let title = win32_string(&config.window.title); startup_info_ex.StartupInfo.lpTitle = std::ptr::null_mut() as LPWSTR;
startup_info_ex.StartupInfo.lpTitle = title.as_ptr() as LPWSTR;
startup_info_ex.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32; startup_info_ex.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32;