aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2020-07-11 20:03:09 +0300
committerGitHub <noreply@github.com>2020-07-11 20:03:09 +0300
commit18cf806a27f06185b1ceb2d63f3b9bc2dd3dc80e (patch)
tree6609ca3aec4fe8da171de474a4a8e8d9b572f0e5 /alacritty_terminal
parent5f039cee49b9c817177c6feecc5e7d97fb0a57e1 (diff)
downloadalacritty-18cf806a27f06185b1ceb2d63f3b9bc2dd3dc80e.tar.gz
alacritty-18cf806a27f06185b1ceb2d63f3b9bc2dd3dc80e.zip
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.
Diffstat (limited to 'alacritty_terminal')
-rw-r--r--alacritty_terminal/Cargo.toml5
-rw-r--r--alacritty_terminal/src/config/debug.rs64
-rw-r--r--alacritty_terminal/src/config/font.rs216
-rw-r--r--alacritty_terminal/src/config/mod.rs106
-rw-r--r--alacritty_terminal/src/config/window.rs215
-rw-r--r--alacritty_terminal/src/event.rs2
-rw-r--r--alacritty_terminal/src/event_loop.rs10
-rw-r--r--alacritty_terminal/src/lib.rs10
-rw-r--r--alacritty_terminal/src/locale.rs99
-rw-r--r--alacritty_terminal/src/message_bar.rs433
-rw-r--r--alacritty_terminal/src/meter.rs97
-rw-r--r--alacritty_terminal/src/panic.rs30
-rw-r--r--alacritty_terminal/src/term/mod.rs32
-rw-r--r--alacritty_terminal/src/tty/windows/conpty.rs3
14 files changed, 24 insertions, 1298 deletions
diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml
index 3e796ba6..15edec3f 100644
--- a/alacritty_terminal/Cargo.toml
+++ b/alacritty_terminal/Cargo.toml
@@ -11,7 +11,6 @@ edition = "2018"
[dependencies]
libc = "0.2"
bitflags = "1"
-font = { path = "../font", features = ["force_system_fontconfig"] }
parking_lot = "0.10.2"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
@@ -38,12 +37,8 @@ winapi = { version = "0.3.7", features = [
]}
mio-anonymous-pipes = "0.1"
-[target.'cfg(target_os = "macos")'.dependencies]
-objc = "0.2.2"
-
[features]
default = ["winpty"]
-nightly = []
bench = []
[dev-dependencies]
diff --git a/alacritty_terminal/src/config/debug.rs b/alacritty_terminal/src/config/debug.rs
deleted file mode 100644
index 9c9d4fde..00000000
--- a/alacritty_terminal/src/config/debug.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-use log::{error, LevelFilter};
-use serde::{Deserialize, Deserializer};
-
-use crate::config::{failure_default, LOG_TARGET_CONFIG};
-
-/// Debugging options.
-#[serde(default)]
-#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Debug {
- #[serde(default = "default_log_level", deserialize_with = "deserialize_log_level")]
- pub log_level: LevelFilter,
-
- #[serde(deserialize_with = "failure_default")]
- pub print_events: bool,
-
- /// Keep the log file after quitting.
- #[serde(deserialize_with = "failure_default")]
- pub persistent_logging: bool,
-
- /// Should show render timer.
- #[serde(deserialize_with = "failure_default")]
- pub render_timer: bool,
-
- /// Record ref test.
- #[serde(skip)]
- pub ref_test: bool,
-}
-
-impl Default for Debug {
- fn default() -> Self {
- Self {
- log_level: default_log_level(),
- print_events: Default::default(),
- persistent_logging: Default::default(),
- render_timer: Default::default(),
- ref_test: Default::default(),
- }
- }
-}
-
-fn default_log_level() -> LevelFilter {
- LevelFilter::Warn
-}
-
-fn deserialize_log_level<'a, D>(deserializer: D) -> Result<LevelFilter, D::Error>
-where
- D: Deserializer<'a>,
-{
- Ok(match failure_default::<D, String>(deserializer)?.to_lowercase().as_str() {
- "off" | "none" => LevelFilter::Off,
- "error" => LevelFilter::Error,
- "warn" => LevelFilter::Warn,
- "info" => LevelFilter::Info,
- "debug" => LevelFilter::Debug,
- "trace" => LevelFilter::Trace,
- level => {
- error!(
- target: LOG_TARGET_CONFIG,
- "Problem with config: invalid log level {}; using level Warn", level
- );
- default_log_level()
- },
- })
-}
diff --git a/alacritty_terminal/src/config/font.rs b/alacritty_terminal/src/config/font.rs
deleted file mode 100644
index 6a9120c9..00000000
--- a/alacritty_terminal/src/config/font.rs
+++ /dev/null
@@ -1,216 +0,0 @@
-use std::fmt;
-
-use font::Size;
-use log::error;
-use serde::de::Visitor;
-use serde::{Deserialize, Deserializer};
-
-#[cfg(target_os = "macos")]
-use crate::config::DefaultTrueBool;
-use crate::config::{failure_default, Delta, LOG_TARGET_CONFIG};
-
-/// Font config.
-///
-/// Defaults are provided at the level of this struct per platform, but not per
-/// field in this struct. It might be nice in the future to have defaults for
-/// each value independently. Alternatively, maybe erroring when the user
-/// doesn't provide complete config is Ok.
-#[serde(default)]
-#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
-pub struct Font {
- /// Normal font face.
- #[serde(deserialize_with = "failure_default")]
- normal: FontDescription,
-
- /// Bold font face.
- #[serde(deserialize_with = "failure_default")]
- bold: SecondaryFontDescription,
-
- /// Italic font face.
- #[serde(deserialize_with = "failure_default")]
- italic: SecondaryFontDescription,
-
- /// Bold italic font face.
- #[serde(deserialize_with = "failure_default")]
- bold_italic: SecondaryFontDescription,
-
- /// Font size in points.
- #[serde(deserialize_with = "DeserializeSize::deserialize")]
- pub size: Size,
-
- /// Extra spacing per character.
- #[serde(deserialize_with = "failure_default")]
- pub offset: Delta<i8>,
-
- /// Glyph offset within character cell.
- #[serde(deserialize_with = "failure_default")]
- pub glyph_offset: Delta<i8>,
-
- #[cfg(target_os = "macos")]
- #[serde(deserialize_with = "failure_default")]
- use_thin_strokes: DefaultTrueBool,
-}
-
-impl Default for Font {
- fn default() -> Font {
- Font {
- size: default_font_size(),
- normal: Default::default(),
- bold: Default::default(),
- italic: Default::default(),
- bold_italic: Default::default(),
- glyph_offset: Default::default(),
- offset: Default::default(),
- #[cfg(target_os = "macos")]
- use_thin_strokes: Default::default(),
- }
- }
-}
-
-impl Font {
- /// Get a font clone with a size modification.
- pub fn with_size(self, size: Size) -> Font {
- Font { size, ..self }
- }
-
- /// Get normal font description.
- pub fn normal(&self) -> &FontDescription {
- &self.normal
- }
-
- /// Get bold font description.
- pub fn bold(&self) -> FontDescription {
- self.bold.desc(&self.normal)
- }
-
- /// Get italic font description.
- pub fn italic(&self) -> FontDescription {
- self.italic.desc(&self.normal)
- }
-
- /// Get bold italic font description.
- pub fn bold_italic(&self) -> FontDescription {
- self.bold_italic.desc(&self.normal)
- }
-
- #[cfg(target_os = "macos")]
- pub fn use_thin_strokes(&self) -> bool {
- self.use_thin_strokes.0
- }
-
- #[cfg(not(target_os = "macos"))]
- pub fn use_thin_strokes(&self) -> bool {
- false
- }
-}
-
-fn default_font_size() -> Size {
- Size::new(11.)
-}
-
-/// Description of the normal font.
-#[serde(default)]
-#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
-pub struct FontDescription {
- #[serde(deserialize_with = "failure_default")]
- pub family: String,
- #[serde(deserialize_with = "failure_default")]
- pub style: Option<String>,
-}
-
-impl Default for FontDescription {
- fn default() -> FontDescription {
- FontDescription {
- #[cfg(not(any(target_os = "macos", windows)))]
- family: "monospace".into(),
- #[cfg(target_os = "macos")]
- family: "Menlo".into(),
- #[cfg(windows)]
- family: "Consolas".into(),
- style: None,
- }
- }
-}
-
-/// Description of the italic and bold font.
-#[serde(default)]
-#[derive(Debug, Default, Deserialize, Clone, PartialEq, Eq)]
-pub struct SecondaryFontDescription {
- #[serde(deserialize_with = "failure_default")]
- family: Option<String>,
- #[serde(deserialize_with = "failure_default")]
- style: Option<String>,
-}
-
-impl SecondaryFontDescription {
- pub fn desc(&self, fallback: &FontDescription) -> FontDescription {
- FontDescription {
- family: self.family.clone().unwrap_or_else(|| fallback.family.clone()),
- style: self.style.clone(),
- }
- }
-}
-
-trait DeserializeSize: Sized {
- fn deserialize<'a, D>(_: D) -> ::std::result::Result<Self, D::Error>
- where
- D: serde::de::Deserializer<'a>;
-}
-
-impl DeserializeSize for Size {
- fn deserialize<'a, D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
- where
- D: serde::de::Deserializer<'a>,
- {
- use std::marker::PhantomData;
-
- struct NumVisitor<__D> {
- _marker: PhantomData<__D>,
- }
-
- impl<'a, __D> Visitor<'a> for NumVisitor<__D>
- where
- __D: serde::de::Deserializer<'a>,
- {
- type Value = f64;
-
- fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str("f64 or u64")
- }
-
- fn visit_f64<E>(self, value: f64) -> ::std::result::Result<Self::Value, E>
- where
- E: ::serde::de::Error,
- {
- Ok(value)
- }
-
- fn visit_u64<E>(self, value: u64) -> ::std::result::Result<Self::Value, E>
- where
- E: ::serde::de::Error,
- {
- Ok(value as f64)
- }
- }
-
- let value = serde_yaml::Value::deserialize(deserializer)?;
- let size = value
- .deserialize_any(NumVisitor::<D> { _marker: PhantomData })
- .map(|v| Size::new(v as _));
-
- // Use default font size as fallback.
- match size {
- Ok(size) => Ok(size),
- Err(err) => {
- let size = default_font_size();
- error!(
- target: LOG_TARGET_CONFIG,
- "Problem with config: {}; using size {}",
- err,
- size.as_f32_pts()
- );
- Ok(size)
- },
- }
- }
-}
diff --git a/alacritty_terminal/src/config/mod.rs b/alacritty_terminal/src/config/mod.rs
index 83dcd7b8..98579a69 100644
--- a/alacritty_terminal/src/config/mod.rs
+++ b/alacritty_terminal/src/config/mod.rs
@@ -8,19 +8,13 @@ use serde_yaml::Value;
mod bell;
mod colors;
-mod debug;
-mod font;
mod scrolling;
-mod window;
use crate::ansi::CursorStyle;
pub use crate::config::bell::{BellAnimation, BellConfig};
pub use crate::config::colors::Colors;
-pub use crate::config::debug::Debug;
-pub use crate::config::font::{Font, FontDescription};
pub use crate::config::scrolling::Scrolling;
-pub use crate::config::window::{Decorations, Dimensions, StartupMode, WindowConfig, DEFAULT_NAME};
pub const LOG_TARGET_CONFIG: &str = "alacritty_config";
const MAX_SCROLLBACK_LINES: u32 = 100_000;
@@ -31,18 +25,10 @@ pub type MockConfig = Config<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 {
diff --git a/alacritty_terminal/src/config/window.rs b/alacritty_terminal/src/config/window.rs
deleted file mode 100644
index b410f0a2..00000000
--- a/alacritty_terminal/src/config/window.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-use std::os::raw::c_ulong;
-
-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};
-
-/// Default Alacritty name, used for window title and class.
-pub const DEFAULT_NAME: &str = "Alacritty";
-
-#[serde(default)]
-#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
-pub struct WindowConfig {
- /// Initial dimensions.
- #[serde(deserialize_with = "failure_default")]
- pub dimensions: Dimensions,
-
- /// Initial position.
- #[serde(deserialize_with = "failure_default")]
- pub position: Option<Delta<i32>>,
-
- /// Pixel padding.
- #[serde(deserialize_with = "failure_default")]
- pub padding: Delta<u8>,
-
- /// Draw the window with title bar / borders.
- #[serde(deserialize_with = "failure_default")]
- pub decorations: Decorations,
-
- /// Spread out additional padding evenly.
- #[serde(deserialize_with = "failure_default")]
- pub dynamic_padding: bool,
-
- /// Startup mode.
- #[serde(deserialize_with = "failure_default")]
- startup_mode: StartupMode,
-
- /// Window title.
- #[serde(default = "default_title")]
- pub title: String,
-
- /// Window class.
- #[serde(deserialize_with = "deserialize_class")]
- pub class: Class,
-
- /// XEmbed parent.
- #[serde(skip)]
- pub embed: Option<c_ulong>,
-
- /// GTK theme variant.
- #[serde(deserialize_with = "option_explicit_none")]
- pub gtk_theme_variant: Option<String>,
-
- // TODO: DEPRECATED
- #[serde(deserialize_with = "failure_default")]
- pub start_maximized: Option<bool>,
-}
-
-pub fn default_title() -> String {
- DEFAULT_NAME.to_string()
-}
-
-impl WindowConfig {
- pub fn startup_mode(&self) -> StartupMode {
- match self.start_maximized {
- Some(true) => StartupMode::Maximized,
- _ => self.startup_mode,
- }
- }
-}
-
-impl Default for WindowConfig {
- fn default() -> WindowConfig {
- WindowConfig {
- dimensions: Default::default(),
- position: Default::default(),
- padding: Default::default(),
- decorations: Default::default(),
- dynamic_padding: Default::default(),
- startup_mode: Default::default(),
- class: Default::default(),
- embed: Default::default(),
- gtk_theme_variant: Default::default(),
- start_maximized: Default::default(),
- title: default_title(),
- }
- }
-}
-
-#[derive(Debug, Deserialize, Copy, Clone, PartialEq, Eq)]
-pub enum StartupMode {
- Windowed,
- Maximized,
- Fullscreen,
- #[cfg(target_os = "macos")]
- SimpleFullscreen,
-}
-
-impl Default for StartupMode {
- fn default() -> StartupMode {
- StartupMode::Windowed
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)]
-pub enum Decorations {
- #[serde(rename = "full")]
- Full,
- #[cfg(target_os = "macos")]
- #[serde(rename = "transparent")]
- Transparent,
- #[cfg(target_os = "macos")]
- #[serde(rename = "buttonless")]
- Buttonless,
- #[serde(rename = "none")]
- None,
-}
-
-impl Default for Decorations {
- fn default() -> Decorations {
- Decorations::Full
- }
-}
-
-/// Window Dimensions.
-///
-/// Newtype to avoid passing values incorrectly.
-#[serde(default)]
-#[derive(Default, Debug, Copy, Clone, Deserialize, PartialEq, Eq)]
-pub struct Dimensions {
- /// Window width in character columns.
- #[serde(deserialize_with = "failure_default")]
- columns: Column,
-
- /// Window Height in character lines.
- #[serde(deserialize_with = "failure_default")]
- lines: Line,
-}
-
-impl Dimensions {
- pub fn new(columns: Column, lines: Line) -> Self {
- Dimensions { columns, lines }
- }
-
- /// Get lines.
- #[inline]
- pub fn lines_u32(&self) -> u32 {
- self.lines.0 as u32
- }
-
- /// Get columns.
- #[inline]
- pub fn columns_u32(&self) -> u32 {
- self.columns.0 as u32
- }
-}
-
-/// Window class hint.
-#[serde(default)]
-#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
-pub struct Class {
- #[serde(deserialize_with = "deserialize_class_resource")]
- pub instance: String,
-
- #[serde(deserialize_with = "deserialize_class_resource")]
- pub general: String,
-}
-
-impl Default for Class {
- fn default() -> Self {
- Class { instance: DEFAULT_NAME.into(), general: DEFAULT_NAME.into() }
- }
-}
-
-fn deserialize_class_resource<'a, D>(deserializer: D) -> Result<String, D::Error>
-where
- D: Deserializer<'a>,
-{
- let value = Value::deserialize(deserializer)?;
- match String::deserialize(value) {
- Ok(value) => Ok(value),
- Err(err) => {
- error!(
- target: LOG_TARGET_CONFIG,
- "Problem with config: {}, using default value {}", err, DEFAULT_NAME,
- );
-
- Ok(DEFAULT_NAME.into())
- },
- }
-}
-
-fn deserialize_class<'a, D>(deserializer: D) -> Result<Class, D::Error>
-where
- D: Deserializer<'a>,
-{
- let value = Value::deserialize(deserializer)?;
-
- if let Value::String(instance) = value {
- return Ok(Class { instance, general: DEFAULT_NAME.into() });
- }
-
- match Class::deserialize(value) {
- Ok(value) => Ok(value),
- Err(err) => {
- error!(
- target: LOG_TARGET_CONFIG,
- "Problem with config: {}; using class {}", err, DEFAULT_NAME
- );
- Ok(Class::default())
- },
- }
-}
diff --git a/alacritty_terminal/src/event.rs b/alacritty_terminal/src/event.rs
index 863a2fbf..c7129b24 100644
--- a/alacritty_terminal/src/event.rs
+++ b/alacritty_terminal/src/event.rs
@@ -8,6 +8,7 @@ use crate::term::{ClipboardType, SizeInfo};
pub enum Event {
MouseCursorDirty,
Title(String),
+ ResetTitle,
ClipboardStore(ClipboardType, String),
ClipboardLoad(ClipboardType, Arc<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"),
diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs
index 156510b0..43e8a302 100644
--- a/alacritty_terminal/src/event_loop.rs
+++ b/alacritty_terminal/src/event_loop.rs
@@ -15,7 +15,6 @@ use mio::{self, Events, PollOpt, Ready};
use mio_extras::channel::{self, Receiver, Sender};
use crate::ansi;
-use crate::config::Config;
use crate::event::{self, Event, EventListener};
use crate::sync::FairMutex;
use crate::term::{SizeInfo, Term};
@@ -155,11 +154,12 @@ where
U: EventListener + Send + 'static,
{
/// Create a new event loop.
- pub fn new<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,
}
}
diff --git a/alacritty_terminal/src/lib.rs b/alacritty_terminal/src/lib.rs
index 7130218b..2f3beeb0 100644
--- a/alacritty_terminal/src/lib.rs
+++ b/alacritty_terminal/src/lib.rs
@@ -1,24 +1,14 @@
//! Alacritty - The GPU Enhanced Terminal.
#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use, clippy::wrong_pub_self_convention)]
-#![cfg_attr(feature = "nightly", feature(core_intrinsics))]
#![cfg_attr(all(test, feature = "bench"), feature(test))]
-#[cfg(target_os = "macos")]
-#[macro_use]
-extern crate objc;
-
pub mod ansi;
pub mod config;
pub mod event;
pub mod event_loop;
pub mod grid;
pub mod index;
-#[cfg(target_os = "macos")]
-pub mod locale;
-pub mod message_bar;
-pub mod meter;
-pub mod panic;
pub mod selection;
pub mod sync;
pub mod term;
diff --git a/alacritty_terminal/src/locale.rs b/alacritty_terminal/src/locale.rs
deleted file mode 100644
index 0a72e775..00000000
--- a/alacritty_terminal/src/locale.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-#![allow(clippy::let_unit_value)]
-
-use std::env;
-use std::ffi::{CStr, CString};
-use std::os::raw::c_char;
-use std::slice;
-use std::str;
-
-use libc::{setlocale, LC_ALL, LC_CTYPE};
-use log::debug;
-use objc::runtime::{Class, Object};
-
-const FALLBACK_LOCALE: &str = "UTF-8";
-
-pub fn set_locale_environment() {
- let env_locale_c = CString::new("").unwrap();
- let env_locale_ptr = unsafe { setlocale(LC_ALL, env_locale_c.as_ptr()) };
- if !env_locale_ptr.is_null() {
- let env_locale = unsafe { CStr::from_ptr(env_locale_ptr).to_string_lossy() };
-
- // Assume `C` locale means unchanged, since it is the default anyways.
- if env_locale != "C" {
- debug!("Using environment locale: {}", env_locale);
- return;
- }
- }
-
- let system_locale = system_locale();
-
- // Set locale to system locale.
- let system_locale_c = CString::new(system_locale.clone()).expect("nul byte in system locale");
- let lc_all = unsafe { setlocale(LC_ALL, system_locale_c.as_ptr()) };
-
- // Check if system locale was valid or not.
- if lc_all.is_null() {
- // Use fallback locale.
- debug!("Using fallback locale: {}", FALLBACK_LOCALE);
-
- let fallback_locale_c = CString::new(FALLBACK_LOCALE).unwrap();
- unsafe { setlocale(LC_CTYPE, fallback_locale_c.as_ptr()) };
-
- env::set_var("LC_CTYPE", FALLBACK_LOCALE);
- } else {
- // Use system locale.
- debug!("Using system locale: {}", system_locale);
-
- env::set_var("LC_ALL", system_locale);
- }
-}
-
-/// Determine system locale based on language and country code.
-fn system_locale() -> String {
- unsafe {
- let locale_class = Class::get("NSLocale").unwrap();
- let locale: *const Object = msg_send![locale_class, currentLocale];
- let _: () = msg_send![locale_class, release];
-
- // `localeIdentifier` returns extra metadata with the locale (including currency and
- // collator) on newer versions of macOS. This is not a valid locale, so we use
- // `languageCode` and `countryCode`, if they're available (macOS 10.12+):
- //
- // https://developer.apple.com/documentation/foundation/nslocale/1416263-localeidentifier?language=objc
- // https://developer.apple.com/documentation/foundation/nslocale/1643060-countrycode?language=objc
- // https://developer.apple.com/documentation/foundation/nslocale/1643026-languagecode?language=objc
- let is_language_code_supported: bool =
- msg_send![locale, respondsToSelector: sel!(languageCode)];
- let is_country_code_supported: bool =
- msg_send![locale, respondsToSelector: sel!(countryCode)];
- let locale_id = if is_language_code_supported && is_country_code_supported {
- let language_code: *const Object = msg_send![locale, languageCode];
- let language_code_str = nsstring_as_str(language_code).to_owned();
- let _: () = msg_send![language_code, release];
-
- let country_code: *const Object = msg_send![locale, countryCode];
- let country_code_str = nsstring_as_str(country_code).to_owned();
- let _: () = msg_send![country_code, release];
-
- format!("{}_{}.UTF-8", &language_code_str, &country_code_str)
- } else {
- let identifier: *const Object = msg_send![locale, localeIdentifier];
- let identifier_str = nsstring_as_str(identifier).to_owned();
- let _: () = msg_send![identifier, release];
-
- identifier_str + ".UTF-8"
- };
-
- let _: () = msg_send![locale, release];
-
- locale_id
- }
-}
-
-const UTF8_ENCODING: usize = 4;
-
-unsafe fn nsstring_as_str<'a>(nsstring: *const Object) -> &'a str {
- let cstr: *const c_char = msg_send![nsstring, UTF8String];
- let len: usize = msg_send![nsstring, lengthOfBytesUsingEncoding: UTF8_ENCODING];
- str::from_utf8(slice::from_raw_parts(cstr as *const u8, len)).unwrap()
-}
diff --git a/alacritty_terminal/src/message_bar.rs b/alacritty_terminal/src/message_bar.rs
deleted file mode 100644
index 240581ff..00000000
--- a/alacritty_terminal/src/message_bar.rs
+++ /dev/null
@@ -1,433 +0,0 @@
-use std::collections::VecDeque;
-
-use crate::term::color::Rgb;
-use crate::term::SizeInfo;
-
-pub const CLOSE_BUTTON_TEXT: &str = "[X]";
-const CLOSE_BUTTON_PADDING: usize = 1;
-const MIN_FREE_LINES: usize = 3;
-const TRUNCATED_MESSAGE: &str = "[MESSAGE TRUNCATED]";
-
-/// Message for display in the MessageBuffer.
-#[derive(Debug, Eq, PartialEq, Clone)]
-pub struct Message {
- text: String,
- color: Rgb,
- target: Option<String>,
-}
-
-impl Message {
- /// Create a new message.
- pub fn new(text: String, color: Rgb) -> Message {
- Message { text, color, target: None }
- }
-
- /// Formatted message text lines.
- pub fn text(&self, size_info: &SizeInfo) -> Vec<String> {
- let num_cols = size_info.cols().0;
- let max_lines = size_info.lines().saturating_sub(MIN_FREE_LINES);
- let button_len = CLOSE_BUTTON_TEXT.len();
-
- // Split line to fit the screen.
- let mut lines = Vec::new();
- let mut line = String::new();
- for c in self.text.trim().chars() {
- if c == '\n'
- || line.len() == num_cols
- // Keep space in first line for button.
- || (lines.is_empty()
- && num_cols >= button_len
- && line.len() == num_cols.saturating_sub(button_len + CLOSE_BUTTON_PADDING))
- {
- // Attempt to wrap on word boundaries.
- if let (Some(index), true) = (line.rfind(char::is_whitespace), c != '\n') {
- let split = line.split_off(index + 1);
- line.pop();
- lines.push(Self::pad_text(line, num_cols));
- line = split
- } else {
- lines.push(Self::pad_text(line, num_cols));
- line = String::new();
- }
- }
-
- if c != '\n' {
- line.push(c);
- }
- }
- lines.push(Self::pad_text(line, num_cols));
-
- // Truncate output if it's too long.
- if lines.len() > max_lines {
- lines.truncate(max_lines);
- if TRUNCATED_MESSAGE.len() <= num_cols {
- if let Some(line) = lines.iter_mut().last() {
- *line = Self::pad_text(TRUNCATED_MESSAGE.into(), num_cols);
- }
- }
- }
-
- // Append close button to first line.
- if button_len <= num_cols {
- if let Some(line) = lines.get_mut(0) {
- line.truncate(num_cols - button_len);
- line.push_str(CLOSE_BUTTON_TEXT);
- }
- }
-
- lines
- }
-
- /// Message color.
- #[inline]
- pub fn color(&self) -> Rgb {
- self.color
- }
-
- /// Message target.
- #[inline]
- pub fn target(&self) -> Option<&String> {
- self.target.as_ref()
- }
-
- /// Update the message target.
- #[inline]
- pub fn set_target(&mut self, target: String) {
- self.target = Some(target);
- }
-
- /// Right-pad text to fit a specific number of columns.
- #[inline]
- fn pad_text(mut text: String, num_cols: usize) -> String {
- let padding_len = num_cols.saturating_sub(text.len());
- text.extend(vec![' '; padding_len]);
- text
- }
-}
-
-/// Storage for message bar.
-#[derive(Debug, Default)]
-pub struct MessageBuffer {
- messages: VecDeque<Message>,
-}
-
-impl MessageBuffer {
- /// Create new message buffer.
- pub fn new() -> MessageBuffer {
- MessageBuffer { messages: VecDeque::new() }
- }
-
- /// Check if there are any messages queued.
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.messages.is_empty()
- }
-
- /// Current message.
- #[inline]
- pub fn message(&self) -> Option<&Message> {
- self.messages.front()
- }
-
- /// Remove the currently visible message.
- #[inline]
- pub fn pop(&mut self) {
- // Remove the message itself.
- let msg = self.messages.pop_front();
-
- // Remove all duplicates.
- if let Some(msg) = msg {
- self.messages = self.messages.drain(..).filter(|m| m != &msg).collect();
- }
- }
-
- /// Remove all messages with a specific target.
- #[inline]
- pub fn remove_target(&mut self, target: &str) {
- self.messages = self
- .messages
- .drain(..)
- .filter(|m| m.target().map(String::as_str) != Some(target))
- .collect();
- }
-
- /// Add a new message to the queue.
- #[inline]
- pub fn push(&mut self, message: Message) {
- self.messages.push_back(message);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::{Message, MessageBuffer, MIN_FREE_LINES};
- use crate::term::{color, SizeInfo};
-
- #[test]
- fn appends_close_button() {
- let input = "a";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 7.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![String::from("a [X]")]);
- }
-
- #[test]
- fn multiline_close_button_first_line() {
- let input = "fo\nbar";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 6.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![String::from("fo [X]"), String::from("bar ")]);
- }
-
- #[test]
- fn splits_on_newline() {
- let input = "a\nb";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 6.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines.len(), 2);
- }
-
- #[test]
- fn splits_on_length() {
- let input = "foobar1";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 6.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines.len(), 2);
- }
-
- #[test]
- fn empty_with_shortterm() {
- let input = "foobar";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 6.,
- height: 0.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines.len(), 0);
- }
-
- #[test]
- fn truncates_long_messages() {
- let input = "hahahahahahahahahahaha truncate this because it's too long for the term";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 22.,
- height: (MIN_FREE_LINES + 2) as f32,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![
- String::from("hahahahahahahahaha [X]"),
- String::from("[MESSAGE TRUNCATED] ")
- ]);
- }
-
- #[test]
- fn hide_button_when_too_narrow() {
- let input = "ha";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 2.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![String::from("ha")]);
- }
-
- #[test]
- fn hide_truncated_when_too_narrow() {
- let input = "hahahahahahahahaha";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 2.,
- height: (MIN_FREE_LINES + 2) as f32,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![String::from("ha"), String::from("ha")]);
- }
-
- #[test]
- fn add_newline_for_button() {
- let input = "test";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 5.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![String::from("t [X]"), String::from("est ")]);
- }
-
- #[test]
- fn remove_target() {
- let mut message_buffer = MessageBuffer::new();
- for i in 0..10 {
- let mut msg = Message::new(i.to_string(), color::RED);
- if i % 2 == 0 && i < 5 {
- msg.set_target("target".into());
- }
- message_buffer.push(msg);
- }
-
- message_buffer.remove_target("target");
-
- // Count number of messages.
- let mut num_messages = 0;
- while message_buffer.message().is_some() {
- num_messages += 1;
- message_buffer.pop();
- }
-
- assert_eq!(num_messages, 7);
- }
-
- #[test]
- fn pop() {
- let mut message_buffer = MessageBuffer::new();
- let one = Message::new(String::from("one"), color::RED);
- message_buffer.push(one.clone());
- let two = Message::new(String::from("two"), color::YELLOW);
- message_buffer.push(two.clone());
-
- assert_eq!(message_buffer.message(), Some(&one));
-
- message_buffer.pop();
-
- assert_eq!(message_buffer.message(), Some(&two));
- }
-
- #[test]
- fn wrap_on_words() {
- let input = "a\nbc defg";
- let mut message_buffer = MessageBuffer::new();
- message_buffer.push(Message::new(input.into(), color::RED));
- let size = SizeInfo {
- width: 5.,
- height: 10.,
- cell_width: 1.,
- cell_height: 1.,
- padding_x: 0.,
- padding_y: 0.,
- dpr: 0.,
- };
-
- let lines = message_buffer.message().unwrap().text(&size);
-
- assert_eq!(lines, vec![
- String::from("a [X]"),
- String::from("bc "),
- String::from("defg ")
- ]);
- }
-
- #[test]
- fn remove_duplicates() {
- let mut message_buffer = MessageBuffer::new();
- for _ in 0..10 {
- let msg = Message::new(String::from("test"), color::RED);
- message_buffer.push(msg);
- }
- message_buffer.push(Message::new(String::from("other"), color::RED));
- message_buffer.push(Message::new(String::from("test"), color::YELLOW));
- let _ = message_buffer.message();
-
- message_buffer.pop();
-
- // Count number of messages.
- let mut num_messages = 0;
- while message_buffer.message().is_some() {
- num_messages += 1;
- message_buffer.pop();
- }
-
- assert_eq!(num_messages, 2);
- }
-}
diff --git a/alacritty_terminal/src/meter.rs b/alacritty_terminal/src/meter.rs
deleted file mode 100644
index c07d901f..00000000
--- a/alacritty_terminal/src/meter.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-//! Rendering time meter.
-//!
-//! Used to track rendering times and provide moving averages.
-//!
-//! # Examples
-//!
-//! ```rust
-//! // create a meter
-//! let mut meter = alacritty_terminal::meter::Meter::new();
-//!
-//! // Sample something.
-//! {
-//! let _sampler = meter.sampler();
-//! }
-//!
-//! // Get the moving average. The meter tracks a fixed number of samples, and
-//! // the average won't mean much until it's filled up at least once.
-//! println!("Average time: {}", meter.average());
-//! ```
-
-use std::time::{Duration, Instant};
-
-const NUM_SAMPLES: usize = 10;
-
-/// The meter.
-#[derive(Default)]
-pub struct Meter {
- /// Track last 60 timestamps.
- times: [f64; NUM_SAMPLES],
-
- /// Average sample time in microseconds.
- avg: f64,
-
- /// Index of next time to update..
- index: usize,
-}
-
-/// Sampler.
-///
-/// Samplers record how long they are "alive" for and update the meter on drop..
-pub struct Sampler<'a> {
- /// Reference to meter that created the sampler.
- meter: &'a mut Meter,
-
- /// When the sampler was created.
- created_at: Instant,
-}
-
-impl<'a> Sampler<'a> {
- fn new(meter: &'a mut Meter) -> Sampler<'a> {
- Sampler { meter, created_at: Instant::now() }
- }
-
- #[inline]
- fn alive_duration(&self) -> Duration {
- self.created_at.elapsed()
- }
-}
-
-impl<'a> Drop for Sampler<'a> {
- fn drop(&mut self) {
- self.meter.add_sample(self.alive_duration());
- }
-}
-
-impl Meter {
- /// Create a meter.
- pub fn new() -> Meter {
- Default::default()
- }
-
- /// Get a sampler.
- pub fn sampler(&mut self) -> Sampler<'_> {
- Sampler::new(self)
- }
-
- /// Get the current average sample duration in microseconds.
- pub fn average(&self) -> f64 {
- self.avg
- }
-
- /// Add a sample.
- ///
- /// Used by Sampler::drop.
- fn add_sample(&mut self, sample: Duration) {
- let mut usec = 0f64;
-
- usec += f64::from(sample.subsec_nanos()) / 1e3;
- usec += (sample.as_secs() as f64) * 1e6;
-
- let prev = self.times[self.index];
- self.times[self.index] = usec;
- self.avg -= prev / NUM_SAMPLES as f64;
- self.avg += usec / NUM_SAMPLES as f64;
- self.index = (self.index + 1) % NUM_SAMPLES;
- }
-}
diff --git a/alacritty_terminal/src/panic.rs b/alacritty_terminal/src/panic.rs
deleted file mode 100644
index 4ec409ff..00000000
--- a/alacritty_terminal/src/panic.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-#[cfg(windows)]
-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
-// 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;
-
- panic::set_hook(Box::new(|panic_info| {
- let _ = writeln!(io::stderr(), "{}", panic_info);
- let msg = format!("{}\n\nPress Ctrl-C to Copy", panic_info);
- unsafe {
- winuser::MessageBoxW(
- ptr::null_mut(),
- win32_string(&msg).as_ptr(),
- win32_string("Alacritty: Runtime Error").as_ptr(),
- winuser::MB_ICONERROR
- | winuser::MB_OK
- | winuser::MB_SETFOREGROUND
- | winuser::MB_TASKMODAL,
- );
- }
- }));
-}
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs
index f3f22d47..5a59b55b 100644
--- a/alacritty_terminal/src/term/mod.rs
+++ b/alacritty_terminal/src/term/mod.rs
@@ -721,14 +721,8 @@ pub struct Term<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]
diff --git a/alacritty_terminal/src/tty/windows/conpty.rs b/alacritty_terminal/src/tty/windows/conpty.rs
index be147b49..fa9f8b5a 100644
--- a/alacritty_terminal/src/tty/windows/conpty.rs
+++ b/alacritty_terminal/src/tty/windows/conpty.rs
@@ -125,8 +125,7 @@ pub fn new<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;