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`
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

3
Cargo.lock generated
View file

@ -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)",

View file

@ -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"

View file

@ -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<T>(option: &mut T, value: Option<T>) {
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());
}
}

View file

@ -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)]

View file

@ -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.
///

View file

@ -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<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() {
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)]

View file

@ -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<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 {
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<KeyBinding> {
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<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_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<String>,
// TODO: DEPRECATED
#[serde(deserialize_with = "failure_default")]
pub start_maximized: Option<bool>,
/// 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(),
}
}
}

View file

@ -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.),

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::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<T> 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<N: Notify + OnResize> Processor<N> {
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<N: Notify + OnResize> Processor<N> {
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<N: Notify + OnResize> Processor<N> {
});
// 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<N: Notify + OnResize> Processor<N> {
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<N: Notify + OnResize> Processor<N> {
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<N: Notify + OnResize> Processor<N> {
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<N: Notify + OnResize> Processor<N> {
// 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;

View file

@ -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<T>> 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;

View file

@ -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";

View file

@ -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";

View file

@ -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<Event>, 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<Event>, 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()));
}

View file

@ -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() {

View file

@ -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;

View file

@ -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<L>(
mut rasterizer: Rasterizer,
font: &config::Font,
font: &Font,
loader: &mut L,
) -> Result<GlyphCache, font::Error>
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, &regular_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<L: LoadGlyph>(
&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<font::Metrics, font::Error> {
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, &regular_desc, font.size)?;
rasterizer.get_glyph(GlyphKey { font_key: regular, c: 'm', size: font.size })?;
rasterizer.metrics(regular, font.size)
}
pub fn calculate_dimensions<C>(
config: &Config<C>,
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<Atlas>,
current_atlas: &'a mut usize,
program: &'a mut TextShaderProgram,
config: &'a Config<C>,
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<RenderRect>) {
pub fn draw_rects(&mut self, props: &SizeInfo, rects: Vec<RenderRect>) {
// Swap to rectangle rendering program.
unsafe {
// 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
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);
}

View file

@ -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<PhysicalSize<u32>>,
#[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue: Option<&EventQueue>,
) -> 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.
#[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,

View file

@ -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]

View file

@ -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<HashMap<String, serde_yaml::Value>>;
/// Top-level config type.
#[derive(Debug, PartialEq, Default, Deserialize)]
pub struct Config<T> {
/// Pixel padding.
#[serde(default, deserialize_with = "failure_default")]
pub padding: Option<Delta<u8>>,
/// TERM env variable.
#[serde(default, deserialize_with = "failure_default")]
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.
#[serde(default, deserialize_with = "failure_default")]
draw_bold_text_with_bright_colors: bool,
@ -50,14 +36,6 @@ pub struct Config<T> {
#[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<T> {
#[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<T> {
#[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<PathBuf>,
/// 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<T> {
// TODO: REMOVED
#[serde(default, deserialize_with = "failure_default")]
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> {
@ -137,50 +91,6 @@ impl<T> Config<T> {
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<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.
#[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 {

View file

@ -8,6 +8,7 @@ use crate::term::{ClipboardType, SizeInfo};
pub enum Event {
MouseCursorDirty,
Title(String),
ResetTitle,
ClipboardStore(ClipboardType, String),
ClipboardLoad(ClipboardType, Arc<dyn Fn(&str) -> 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"),

View file

@ -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<V>(
pub fn new(
terminal: Arc<FairMutex<Term<U>>>,
event_proxy: U,
pty: T,
config: &Config<V>,
hold: bool,
ref_test: bool,
) -> EventLoop<T, U> {
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,
}
}

View file

@ -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;

View file

@ -721,14 +721,8 @@ pub struct Term<T> {
/// Current title of the window.
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
/// term is set, and the Glutin window's title attribute is changed through the event listener.
/// term is set.
title_stack: Vec<Option<String>>,
/// Current forwards and backwards buffer search regexes.
@ -777,11 +771,9 @@ impl<T> Term<T> {
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<T> Term<T> {
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<T: EventListener> Handler for Term<T> {
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]

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 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::<STARTUPINFOEXW>() as u32;