mirror of
https://github.com/alacritty/alacritty.git
synced 2025-09-04 22:43:53 -04:00
parent
b78f3d1339
commit
8bd2c13490
21 changed files with 297 additions and 207 deletions
|
@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Expanding existing selections using the right mouse button
|
- Expanding existing selections using the right mouse button
|
||||||
- Support for `gopher` and `gemini` URLs
|
- Support for `gopher` and `gemini` URLs
|
||||||
- Unicode 13 support
|
- Unicode 13 support
|
||||||
|
- Option to run command on bell which can be set in `bell.command`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- To use the cell's text color for selection with a modified background, the `color.selection.text`
|
- To use the cell's text color for selection with a modified background, the `color.selection.text`
|
||||||
variable must now be set to `CellForeground` instead of omitting it
|
variable must now be set to `CellForeground` instead of omitting it
|
||||||
- URLs are no longer highlighted without a clearly delimited scheme
|
- URLs are no longer highlighted without a clearly delimited scheme
|
||||||
|
- Renamed `visual_bell` to `bell`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -32,6 +32,7 @@ dependencies = [
|
||||||
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gl_generator 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin 0.24.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glutin 0.24.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -265,31 +265,46 @@
|
||||||
#
|
#
|
||||||
#indexed_colors: []
|
#indexed_colors: []
|
||||||
|
|
||||||
# Visual Bell
|
# Bell
|
||||||
#
|
#
|
||||||
# Any time the BEL code is received, Alacritty "rings" the visual bell. Once
|
# The bell is rung every time the BEL control character is received.
|
||||||
# rung, the terminal background will be set to white and transition back to the
|
#bell:
|
||||||
# default background color. You can control the rate of this transition by
|
# Visual Bell Animation
|
||||||
# setting the `duration` property (represented in milliseconds). You can also
|
#
|
||||||
# configure the transition function by setting the `animation` property.
|
# Animation effect for flashing the screen when the visual bell is rung.
|
||||||
#
|
#
|
||||||
# Values for `animation`:
|
# Values for `animation`:
|
||||||
# - Ease
|
# - Ease
|
||||||
# - EaseOut
|
# - EaseOut
|
||||||
# - EaseOutSine
|
# - EaseOutSine
|
||||||
# - EaseOutQuad
|
# - EaseOutQuad
|
||||||
# - EaseOutCubic
|
# - EaseOutCubic
|
||||||
# - EaseOutQuart
|
# - EaseOutQuart
|
||||||
# - EaseOutQuint
|
# - EaseOutQuint
|
||||||
# - EaseOutExpo
|
# - EaseOutExpo
|
||||||
# - EaseOutCirc
|
# - EaseOutCirc
|
||||||
# - Linear
|
# - Linear
|
||||||
#
|
#animation: EaseOutExpo
|
||||||
# Specifying a `duration` of `0` will disable the visual bell.
|
|
||||||
#visual_bell:
|
# Duration of the visual bell flash. A `duration` of `0` will disable the
|
||||||
# animation: EaseOutExpo
|
# visual bell animation.
|
||||||
# duration: 0
|
#duration: 0
|
||||||
# color: '#ffffff'
|
|
||||||
|
# Visual bell animation color.
|
||||||
|
#color: '#ffffff'
|
||||||
|
|
||||||
|
# Bell Command
|
||||||
|
#
|
||||||
|
# This program is executed whenever the bell is rung.
|
||||||
|
#
|
||||||
|
# When set to `command: None`, no command will be executed.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# command:
|
||||||
|
# program: notify-send
|
||||||
|
# args: ["Hello, World!"]
|
||||||
|
#
|
||||||
|
#command: None
|
||||||
|
|
||||||
# Background opacity
|
# Background opacity
|
||||||
#
|
#
|
||||||
|
@ -358,7 +373,7 @@
|
||||||
#
|
#
|
||||||
# Alacritty defaults to using the newer ConPTY backend if it is available,
|
# Alacritty defaults to using the newer ConPTY backend if it is available,
|
||||||
# since it resolves a lot of bugs and is quite a bit faster. If it is not
|
# since it resolves a lot of bugs and is quite a bit faster. If it is not
|
||||||
# available, the the WinPTY backend will be used instead.
|
# available, the WinPTY backend will be used instead.
|
||||||
#
|
#
|
||||||
# Setting this option to `true` makes Alacritty use the legacy WinPTY backend,
|
# Setting this option to `true` makes Alacritty use the legacy WinPTY backend,
|
||||||
# even if the ConPTY backend is available.
|
# even if the ConPTY backend is available.
|
||||||
|
|
|
@ -23,6 +23,7 @@ parking_lot = "0.10.2"
|
||||||
font = { path = "../font", features = ["force_system_fontconfig"] }
|
font = { path = "../font", features = ["force_system_fontconfig"] }
|
||||||
urlocator = "0.1.3"
|
urlocator = "0.1.3"
|
||||||
copypasta = { version = "0.7.0", default-features = false }
|
copypasta = { version = "0.7.0", default-features = false }
|
||||||
|
libc = "0.2"
|
||||||
unicode-width = "0.1"
|
unicode-width = "0.1"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -217,6 +217,13 @@ fn print_deprecation_warnings(config: &Config) {
|
||||||
the config"
|
the config"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.visual_bell.is_some() {
|
||||||
|
warn!(
|
||||||
|
target: LOG_TARGET_CONFIG,
|
||||||
|
"Config visual_bell has been deprecated; please use bell instead"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
||||||
|
|
||||||
use alacritty_terminal::util;
|
use alacritty_terminal::thread;
|
||||||
|
|
||||||
use crate::event::{Event, EventProxy};
|
use crate::event::{Event, EventProxy};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ impl Monitor {
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
|
|
||||||
Monitor {
|
Monitor {
|
||||||
_thread: util::thread::spawn_named("config watcher", move || {
|
_thread: thread::spawn_named("config watcher", move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
// The Duration argument is a debouncing period.
|
// The Duration argument is a debouncing period.
|
||||||
let mut watcher =
|
let mut watcher =
|
||||||
|
|
|
@ -1,65 +1,33 @@
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use std::os::windows::process::CommandExt;
|
use std::os::windows::process::CommandExt;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
|
||||||
|
use log::{debug, warn};
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW};
|
use winapi::um::winbase::{CREATE_NEW_PROCESS_GROUP, CREATE_NO_WINDOW};
|
||||||
|
|
||||||
/// Threading utilities.
|
/// Start the daemon and log error on failure.
|
||||||
pub mod thread {
|
pub fn start_daemon<I, S>(program: &str, args: I)
|
||||||
/// Like `thread::spawn`, but with a `name` argument.
|
|
||||||
pub fn spawn_named<F, T, S>(name: S, f: F) -> std::thread::JoinHandle<T>
|
|
||||||
where
|
|
||||||
F: FnOnce() -> T + Send + 'static,
|
|
||||||
T: Send + 'static,
|
|
||||||
S: Into<String>,
|
|
||||||
{
|
|
||||||
std::thread::Builder::new().name(name.into()).spawn(f).expect("thread spawn works")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use std::thread::*;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn start_daemon<I, S>(program: &str, args: I) -> io::Result<()>
|
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = S>,
|
I: IntoIterator<Item = S> + Debug + Copy,
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
unsafe {
|
match spawn_daemon(program, args) {
|
||||||
Command::new(program)
|
Ok(_) => debug!("Launched {} with args {:?}", program, args),
|
||||||
.args(args)
|
Err(_) => warn!("Unable to launch {} with args {:?}", program, args),
|
||||||
.stdin(Stdio::null())
|
|
||||||
.stdout(Stdio::null())
|
|
||||||
.stderr(Stdio::null())
|
|
||||||
.pre_exec(|| {
|
|
||||||
match ::libc::fork() {
|
|
||||||
-1 => return Err(io::Error::last_os_error()),
|
|
||||||
0 => (),
|
|
||||||
_ => ::libc::_exit(0),
|
|
||||||
}
|
|
||||||
|
|
||||||
if ::libc::setsid() == -1 {
|
|
||||||
return Err(io::Error::last_os_error());
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.spawn()?
|
|
||||||
.wait()
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub fn start_daemon<I, S>(program: &str, args: I) -> io::Result<()>
|
fn spawn_daemon<I, S>(program: &str, args: I) -> io::Result<()>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = S>,
|
I: IntoIterator<Item = S> + Copy,
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
// Setting all the I/O handles to null and setting the
|
// Setting all the I/O handles to null and setting the
|
||||||
|
@ -75,3 +43,34 @@ where
|
||||||
.spawn()
|
.spawn()
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn spawn_daemon<I, S>(program: &str, args: I) -> io::Result<()>
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = S> + Copy,
|
||||||
|
S: AsRef<OsStr>,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
Command::new(program)
|
||||||
|
.args(args)
|
||||||
|
.stdin(Stdio::null())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.pre_exec(|| {
|
||||||
|
match libc::fork() {
|
||||||
|
-1 => return Err(io::Error::last_os_error()),
|
||||||
|
0 => (),
|
||||||
|
_ => libc::_exit(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
if libc::setsid() == -1 {
|
||||||
|
return Err(io::Error::last_os_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.spawn()?
|
||||||
|
.wait()
|
||||||
|
.map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
|
@ -540,7 +540,7 @@ impl Display {
|
||||||
0.,
|
0.,
|
||||||
size_info.width,
|
size_info.width,
|
||||||
size_info.height,
|
size_info.height,
|
||||||
config.visual_bell.color,
|
config.bell().color,
|
||||||
visual_bell_intensity as f32,
|
visual_bell_intensity as f32,
|
||||||
);
|
);
|
||||||
rects.push(visual_bell_rect);
|
rects.push(visual_bell_rect);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::fmt::Debug;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -20,7 +21,7 @@ use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindow
|
||||||
use glutin::platform::desktop::EventLoopExtDesktop;
|
use glutin::platform::desktop::EventLoopExtDesktop;
|
||||||
#[cfg(not(any(target_os = "macos", windows)))]
|
#[cfg(not(any(target_os = "macos", windows)))]
|
||||||
use glutin::platform::unix::EventLoopWindowTargetExtUnix;
|
use glutin::platform::unix::EventLoopWindowTargetExtUnix;
|
||||||
use log::{debug, info, warn};
|
use log::info;
|
||||||
use serde_json as json;
|
use serde_json as json;
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -38,12 +39,12 @@ use alacritty_terminal::term::cell::Cell;
|
||||||
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term, TermMode};
|
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term, TermMode};
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use alacritty_terminal::tty;
|
use alacritty_terminal::tty;
|
||||||
use alacritty_terminal::util::start_daemon;
|
|
||||||
|
|
||||||
use crate::cli::Options;
|
use crate::cli::Options;
|
||||||
use crate::clipboard::Clipboard;
|
use crate::clipboard::Clipboard;
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::daemon::start_daemon;
|
||||||
use crate::display::{Display, DisplayUpdate};
|
use crate::display::{Display, DisplayUpdate};
|
||||||
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
|
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
|
||||||
use crate::scheduler::{Scheduler, TimerId};
|
use crate::scheduler::{Scheduler, TimerId};
|
||||||
|
@ -290,10 +291,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
let args: Vec<String> = Vec::new();
|
let args: Vec<String> = Vec::new();
|
||||||
|
|
||||||
match start_daemon(&alacritty, &args) {
|
start_daemon(&alacritty, &args);
|
||||||
Ok(_) => debug!("Started new Alacritty process: {} {:?}", alacritty, args),
|
|
||||||
Err(_) => warn!("Unable to start new Alacritty process: {} {:?}", alacritty, args),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn URL launcher when clicking on URLs.
|
/// Spawn URL launcher when clicking on URLs.
|
||||||
|
@ -308,10 +306,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
|
||||||
let end = self.terminal.visible_to_buffer(url.end());
|
let end = self.terminal.visible_to_buffer(url.end());
|
||||||
args.push(self.terminal.bounds_to_string(start, end));
|
args.push(self.terminal.bounds_to_string(start, end));
|
||||||
|
|
||||||
match start_daemon(launcher.program(), &args) {
|
start_daemon(launcher.program(), &args);
|
||||||
Ok(_) => debug!("Launched {} with args {:?}", launcher.program(), args),
|
|
||||||
Err(_) => warn!("Unable to launch {} with args {:?}", launcher.program(), args),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,8 +834,10 @@ impl<N: Notify + OnResize> Processor<N> {
|
||||||
Event::TerminalEvent(event) => match event {
|
Event::TerminalEvent(event) => match event {
|
||||||
TerminalEvent::Title(title) => processor.ctx.window.set_title(&title),
|
TerminalEvent::Title(title) => processor.ctx.window.set_title(&title),
|
||||||
TerminalEvent::Wakeup => processor.ctx.terminal.dirty = true,
|
TerminalEvent::Wakeup => processor.ctx.terminal.dirty = true,
|
||||||
TerminalEvent::Urgent => {
|
TerminalEvent::Bell => {
|
||||||
processor.ctx.window.set_urgent(!processor.ctx.terminal.is_focused)
|
let bell_command = processor.ctx.config.bell().command.as_ref();
|
||||||
|
let _ = bell_command.map(|cmd| start_daemon(cmd.program(), cmd.args()));
|
||||||
|
processor.ctx.window.set_urgent(!processor.ctx.terminal.is_focused);
|
||||||
},
|
},
|
||||||
TerminalEvent::ClipboardStore(clipboard_type, content) => {
|
TerminalEvent::ClipboardStore(clipboard_type, content) => {
|
||||||
processor.ctx.clipboard.store(clipboard_type, content);
|
processor.ctx.clipboard.store(clipboard_type, content);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use std::cmp::{max, min, Ordering};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use log::{debug, trace, warn};
|
use log::trace;
|
||||||
|
|
||||||
use glutin::dpi::PhysicalPosition;
|
use glutin::dpi::PhysicalPosition;
|
||||||
use glutin::event::{
|
use glutin::event::{
|
||||||
|
@ -30,11 +30,11 @@ use alacritty_terminal::message_bar::{self, Message};
|
||||||
use alacritty_terminal::selection::SelectionType;
|
use alacritty_terminal::selection::SelectionType;
|
||||||
use alacritty_terminal::term::mode::TermMode;
|
use alacritty_terminal::term::mode::TermMode;
|
||||||
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term};
|
use alacritty_terminal::term::{ClipboardType, SizeInfo, Term};
|
||||||
use alacritty_terminal::util::start_daemon;
|
|
||||||
use alacritty_terminal::vi_mode::ViMotion;
|
use alacritty_terminal::vi_mode::ViMotion;
|
||||||
|
|
||||||
use crate::clipboard::Clipboard;
|
use crate::clipboard::Clipboard;
|
||||||
use crate::config::{Action, Binding, Config, Key, ViAction};
|
use crate::config::{Action, Binding, Config, Key, ViAction};
|
||||||
|
use crate::daemon::start_daemon;
|
||||||
use crate::event::{ClickState, Event, Mouse, TYPING_SEARCH_DELAY};
|
use crate::event::{ClickState, Event, Mouse, TYPING_SEARCH_DELAY};
|
||||||
use crate::scheduler::{Scheduler, TimerId};
|
use crate::scheduler::{Scheduler, TimerId};
|
||||||
use crate::url::{Url, Urls};
|
use crate::url::{Url, Urls};
|
||||||
|
@ -160,10 +160,7 @@ impl<T: EventListener> Execute<T> for Action {
|
||||||
let program = program.program();
|
let program = program.program();
|
||||||
trace!("Running command {} with args {:?}", program, args);
|
trace!("Running command {} with args {:?}", program, args);
|
||||||
|
|
||||||
match start_daemon(program, args) {
|
start_daemon(program, args);
|
||||||
Ok(_) => debug!("Spawned new proc"),
|
|
||||||
Err(err) => warn!("Couldn't run command {}", err),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Action::ClearSelection => ctx.clear_selection(),
|
Action::ClearSelection => ctx.clear_selection(),
|
||||||
Action::ToggleViMode => ctx.terminal_mut().toggle_vi_mode(),
|
Action::ToggleViMode => ctx.terminal_mut().toggle_vi_mode(),
|
||||||
|
|
|
@ -36,6 +36,7 @@ mod cli;
|
||||||
mod clipboard;
|
mod clipboard;
|
||||||
mod config;
|
mod config;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
|
mod daemon;
|
||||||
mod display;
|
mod display;
|
||||||
mod event;
|
mod event;
|
||||||
mod input;
|
mod input;
|
||||||
|
|
|
@ -24,7 +24,7 @@ use alacritty_terminal::index::{Column, Line};
|
||||||
use alacritty_terminal::term::cell::{self, Flags};
|
use alacritty_terminal::term::cell::{self, Flags};
|
||||||
use alacritty_terminal::term::color::Rgb;
|
use alacritty_terminal::term::color::Rgb;
|
||||||
use alacritty_terminal::term::{self, CursorKey, RenderableCell, RenderableCellContent, SizeInfo};
|
use alacritty_terminal::term::{self, CursorKey, RenderableCell, RenderableCellContent, SizeInfo};
|
||||||
use alacritty_terminal::util;
|
use alacritty_terminal::thread;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
pub mod rects;
|
pub mod rects;
|
||||||
|
@ -660,7 +660,7 @@ impl QuadRenderer {
|
||||||
let (msg_tx, msg_rx) = mpsc::channel();
|
let (msg_tx, msg_rx) = mpsc::channel();
|
||||||
|
|
||||||
if cfg!(feature = "live-shader-reload") {
|
if cfg!(feature = "live-shader-reload") {
|
||||||
util::thread::spawn_named("live shader reload", move || {
|
thread::spawn_named("live shader reload", move || {
|
||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
// The Duration argument is a debouncing period.
|
// The Duration argument is a debouncing period.
|
||||||
let mut watcher =
|
let mut watcher =
|
||||||
|
|
120
alacritty_terminal/src/config/bell.rs
Normal file
120
alacritty_terminal/src/config/bell.rs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use log::error;
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
|
use serde_yaml::Value;
|
||||||
|
|
||||||
|
use crate::config::{failure_default, Program, LOG_TARGET_CONFIG};
|
||||||
|
use crate::term::color::Rgb;
|
||||||
|
|
||||||
|
const DEFAULT_BELL_COLOR: Rgb = Rgb { r: 255, g: 255, b: 255 };
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct BellConfig {
|
||||||
|
/// Visual bell animation function.
|
||||||
|
#[serde(deserialize_with = "failure_default")]
|
||||||
|
pub animation: BellAnimation,
|
||||||
|
|
||||||
|
/// Visual bell duration in milliseconds.
|
||||||
|
#[serde(deserialize_with = "failure_default")]
|
||||||
|
duration: u16,
|
||||||
|
|
||||||
|
/// Visual bell flash color.
|
||||||
|
#[serde(deserialize_with = "deserialize_bell_color")]
|
||||||
|
pub color: Rgb,
|
||||||
|
|
||||||
|
/// Command to run on bell.
|
||||||
|
#[serde(deserialize_with = "deserialize_bell_command")]
|
||||||
|
pub command: Option<Program>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BellConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
animation: Default::default(),
|
||||||
|
duration: Default::default(),
|
||||||
|
command: Default::default(),
|
||||||
|
color: DEFAULT_BELL_COLOR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BellConfig {
|
||||||
|
/// Visual bell duration in milliseconds.
|
||||||
|
#[inline]
|
||||||
|
pub fn duration(&self) -> Duration {
|
||||||
|
Duration::from_millis(u64::from(self.duration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_bell_color<'a, D>(deserializer: D) -> Result<Rgb, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'a>,
|
||||||
|
{
|
||||||
|
let value = Value::deserialize(deserializer)?;
|
||||||
|
match Rgb::deserialize(value) {
|
||||||
|
Ok(value) => Ok(value),
|
||||||
|
Err(err) => {
|
||||||
|
error!(
|
||||||
|
target: LOG_TARGET_CONFIG,
|
||||||
|
"Problem with config: {}, using default color value {}", err, DEFAULT_BELL_COLOR
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(DEFAULT_BELL_COLOR)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_bell_command<'a, D>(deserializer: D) -> Result<Option<Program>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'a>,
|
||||||
|
{
|
||||||
|
// Deserialize to generic value.
|
||||||
|
let val = Value::deserialize(deserializer)?;
|
||||||
|
|
||||||
|
// Accept `None` to disable the bell command.
|
||||||
|
if val.as_str().filter(|v| v.to_lowercase() == "none").is_some() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
match Program::deserialize(val) {
|
||||||
|
Ok(command) => Ok(Some(command)),
|
||||||
|
Err(err) => {
|
||||||
|
error!(target: LOG_TARGET_CONFIG, "Problem with config: {}; ignoring field", err);
|
||||||
|
Ok(None)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `VisualBellAnimations` are modeled after a subset of CSS transitions and Robert
|
||||||
|
/// Penner's Easing Functions.
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
|
||||||
|
pub enum BellAnimation {
|
||||||
|
// CSS animation.
|
||||||
|
Ease,
|
||||||
|
// CSS animation.
|
||||||
|
EaseOut,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutSine,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutQuad,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutCubic,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutQuart,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutQuint,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutExpo,
|
||||||
|
// Penner animation.
|
||||||
|
EaseOutCirc,
|
||||||
|
// Penner animation.
|
||||||
|
Linear,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BellAnimation {
|
||||||
|
fn default() -> Self {
|
||||||
|
BellAnimation::EaseOutExpo
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,20 +6,20 @@ use log::error;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use serde_yaml::Value;
|
use serde_yaml::Value;
|
||||||
|
|
||||||
|
mod bell;
|
||||||
mod colors;
|
mod colors;
|
||||||
mod debug;
|
mod debug;
|
||||||
mod font;
|
mod font;
|
||||||
mod scrolling;
|
mod scrolling;
|
||||||
mod visual_bell;
|
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
use crate::ansi::CursorStyle;
|
use crate::ansi::CursorStyle;
|
||||||
|
|
||||||
|
pub use crate::config::bell::{BellAnimation, BellConfig};
|
||||||
pub use crate::config::colors::Colors;
|
pub use crate::config::colors::Colors;
|
||||||
pub use crate::config::debug::Debug;
|
pub use crate::config::debug::Debug;
|
||||||
pub use crate::config::font::{Font, FontDescription};
|
pub use crate::config::font::{Font, FontDescription};
|
||||||
pub use crate::config::scrolling::Scrolling;
|
pub use crate::config::scrolling::Scrolling;
|
||||||
pub use crate::config::visual_bell::{VisualBellAnimation, VisualBellConfig};
|
|
||||||
pub use crate::config::window::{Decorations, Dimensions, StartupMode, WindowConfig, DEFAULT_NAME};
|
pub use crate::config::window::{Decorations, Dimensions, StartupMode, WindowConfig, DEFAULT_NAME};
|
||||||
|
|
||||||
pub const LOG_TARGET_CONFIG: &str = "alacritty_config";
|
pub const LOG_TARGET_CONFIG: &str = "alacritty_config";
|
||||||
|
@ -69,9 +69,9 @@ pub struct Config<T> {
|
||||||
#[serde(default, deserialize_with = "failure_default")]
|
#[serde(default, deserialize_with = "failure_default")]
|
||||||
pub config_path: Option<PathBuf>,
|
pub config_path: Option<PathBuf>,
|
||||||
|
|
||||||
/// Visual bell configuration.
|
/// Bell configuration.
|
||||||
#[serde(default, deserialize_with = "failure_default")]
|
#[serde(default, deserialize_with = "failure_default")]
|
||||||
pub visual_bell: VisualBellConfig,
|
bell: BellConfig,
|
||||||
|
|
||||||
/// Use dynamic title.
|
/// Use dynamic title.
|
||||||
#[serde(default, deserialize_with = "failure_default")]
|
#[serde(default, deserialize_with = "failure_default")]
|
||||||
|
@ -114,6 +114,10 @@ pub struct Config<T> {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub hold: bool,
|
pub hold: bool,
|
||||||
|
|
||||||
|
// TODO: DEPRECATED
|
||||||
|
#[serde(default, deserialize_with = "failure_default")]
|
||||||
|
pub visual_bell: Option<BellConfig>,
|
||||||
|
|
||||||
// TODO: REMOVED
|
// TODO: REMOVED
|
||||||
#[serde(default, deserialize_with = "failure_default")]
|
#[serde(default, deserialize_with = "failure_default")]
|
||||||
pub tabspaces: Option<usize>,
|
pub tabspaces: Option<usize>,
|
||||||
|
@ -176,6 +180,11 @@ impl<T> Config<T> {
|
||||||
pub fn background_opacity(&self) -> f32 {
|
pub fn background_opacity(&self) -> f32 {
|
||||||
self.background_opacity.0 as f32
|
self.background_opacity.0 as f32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn bell(&self) -> &BellConfig {
|
||||||
|
self.visual_bell.as_ref().unwrap_or(&self.bell)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
use crate::config::failure_default;
|
|
||||||
use crate::term::color::Rgb;
|
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub struct VisualBellConfig {
|
|
||||||
/// Visual bell animation function.
|
|
||||||
#[serde(deserialize_with = "failure_default")]
|
|
||||||
pub animation: VisualBellAnimation,
|
|
||||||
|
|
||||||
/// Visual bell duration in milliseconds.
|
|
||||||
#[serde(deserialize_with = "failure_default")]
|
|
||||||
pub duration: u16,
|
|
||||||
|
|
||||||
/// Visual bell flash color.
|
|
||||||
#[serde(deserialize_with = "failure_default")]
|
|
||||||
pub color: Rgb,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for VisualBellConfig {
|
|
||||||
fn default() -> VisualBellConfig {
|
|
||||||
VisualBellConfig {
|
|
||||||
animation: Default::default(),
|
|
||||||
duration: Default::default(),
|
|
||||||
color: default_visual_bell_color(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VisualBellConfig {
|
|
||||||
/// Visual bell duration in milliseconds.
|
|
||||||
#[inline]
|
|
||||||
pub fn duration(&self) -> Duration {
|
|
||||||
Duration::from_millis(u64::from(self.duration))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `VisualBellAnimations` are modeled after a subset of CSS transitions and Robert
|
|
||||||
/// Penner's Easing Functions.
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
|
|
||||||
pub enum VisualBellAnimation {
|
|
||||||
// CSS animation.
|
|
||||||
Ease,
|
|
||||||
// CSS animation.
|
|
||||||
EaseOut,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutSine,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutQuad,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutCubic,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutQuart,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutQuint,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutExpo,
|
|
||||||
// Penner animation.
|
|
||||||
EaseOutCirc,
|
|
||||||
// Penner animation.
|
|
||||||
Linear,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for VisualBellAnimation {
|
|
||||||
fn default() -> Self {
|
|
||||||
VisualBellAnimation::EaseOutExpo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_visual_bell_color() -> Rgb {
|
|
||||||
Rgb { r: 255, g: 255, b: 255 }
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ pub enum Event {
|
||||||
ClipboardStore(ClipboardType, String),
|
ClipboardStore(ClipboardType, String),
|
||||||
ClipboardLoad(ClipboardType, Arc<dyn Fn(&str) -> String + Sync + Send + 'static>),
|
ClipboardLoad(ClipboardType, Arc<dyn Fn(&str) -> String + Sync + Send + 'static>),
|
||||||
Wakeup,
|
Wakeup,
|
||||||
Urgent,
|
Bell,
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ impl Debug for Event {
|
||||||
Event::ClipboardStore(ty, text) => write!(f, "ClipboardStore({:?}, {})", ty, text),
|
Event::ClipboardStore(ty, text) => write!(f, "ClipboardStore({:?}, {})", ty, text),
|
||||||
Event::ClipboardLoad(ty, _) => write!(f, "ClipboardLoad({:?})", ty),
|
Event::ClipboardLoad(ty, _) => write!(f, "ClipboardLoad({:?})", ty),
|
||||||
Event::Wakeup => write!(f, "Wakeup"),
|
Event::Wakeup => write!(f, "Wakeup"),
|
||||||
Event::Urgent => write!(f, "Urgent"),
|
Event::Bell => write!(f, "Bell"),
|
||||||
Event::Exit => write!(f, "Exit"),
|
Event::Exit => write!(f, "Exit"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::fs::File;
|
||||||
use std::io::{self, ErrorKind, Read, Write};
|
use std::io::{self, ErrorKind, Read, Write};
|
||||||
use std::marker::Send;
|
use std::marker::Send;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::thread::JoinHandle;
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
|
@ -18,8 +19,8 @@ use crate::config::Config;
|
||||||
use crate::event::{self, Event, EventListener};
|
use crate::event::{self, Event, EventListener};
|
||||||
use crate::sync::FairMutex;
|
use crate::sync::FairMutex;
|
||||||
use crate::term::{SizeInfo, Term};
|
use crate::term::{SizeInfo, Term};
|
||||||
|
use crate::thread;
|
||||||
use crate::tty;
|
use crate::tty;
|
||||||
use crate::util::thread;
|
|
||||||
|
|
||||||
/// Max bytes to read from the PTY.
|
/// Max bytes to read from the PTY.
|
||||||
const MAX_READ: usize = 0x10_000;
|
const MAX_READ: usize = 0x10_000;
|
||||||
|
@ -300,7 +301,7 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(mut self) -> thread::JoinHandle<(Self, State)> {
|
pub fn spawn(mut self) -> JoinHandle<(Self, State)> {
|
||||||
thread::spawn_named("PTY reader", move || {
|
thread::spawn_named("PTY reader", move || {
|
||||||
let mut state = State::default();
|
let mut state = State::default();
|
||||||
let mut buf = [0u8; MAX_READ];
|
let mut buf = [0u8; MAX_READ];
|
||||||
|
|
|
@ -22,8 +22,8 @@ pub mod panic;
|
||||||
pub mod selection;
|
pub mod selection;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
pub mod term;
|
pub mod term;
|
||||||
|
pub mod thread;
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
pub mod util;
|
|
||||||
pub mod vi_mode;
|
pub mod vi_mode;
|
||||||
|
|
||||||
pub use crate::grid::Grid;
|
pub use crate::grid::Grid;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt;
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::ops::{Index, IndexMut, Mul};
|
use std::ops::{Index, IndexMut, Mul};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl<'de> Deserialize<'de> for Rgb {
|
||||||
impl<'a> Visitor<'a> for RgbVisitor {
|
impl<'a> Visitor<'a> for RgbVisitor {
|
||||||
type Value = Rgb;
|
type Value = Rgb;
|
||||||
|
|
||||||
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str("hex color like #ff00ff")
|
f.write_str("hex color like #ff00ff")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,12 @@ impl<'de> Deserialize<'de> for Rgb {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Rgb {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Rgb {
|
impl FromStr for Rgb {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use unicode_width::UnicodeWidthChar;
|
||||||
use crate::ansi::{
|
use crate::ansi::{
|
||||||
self, Attr, CharsetIndex, Color, CursorStyle, Handler, NamedColor, StandardCharset,
|
self, Attr, CharsetIndex, Color, CursorStyle, Handler, NamedColor, StandardCharset,
|
||||||
};
|
};
|
||||||
use crate::config::{Config, VisualBellAnimation};
|
use crate::config::{BellAnimation, BellConfig, Config};
|
||||||
use crate::event::{Event, EventListener};
|
use crate::event::{Event, EventListener};
|
||||||
use crate::grid::{Dimensions, DisplayIter, Grid, IndexRegion, Indexed, Scroll};
|
use crate::grid::{Dimensions, DisplayIter, Grid, IndexRegion, Indexed, Scroll};
|
||||||
use crate::index::{self, Boundary, Column, Direction, IndexRange, Line, Point, Side};
|
use crate::index::{self, Boundary, Column, Direction, IndexRange, Line, Point, Side};
|
||||||
|
@ -467,7 +467,7 @@ pub use crate::term::mode::TermMode;
|
||||||
|
|
||||||
pub struct VisualBell {
|
pub struct VisualBell {
|
||||||
/// Visual bell animation.
|
/// Visual bell animation.
|
||||||
animation: VisualBellAnimation,
|
animation: BellAnimation,
|
||||||
|
|
||||||
/// Visual bell duration.
|
/// Visual bell duration.
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
|
@ -484,15 +484,6 @@ fn cubic_bezier(p0: f64, p1: f64, p2: f64, p3: f64, x: f64) -> f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VisualBell {
|
impl VisualBell {
|
||||||
pub fn new<C>(config: &Config<C>) -> VisualBell {
|
|
||||||
let visual_bell_config = &config.visual_bell;
|
|
||||||
VisualBell {
|
|
||||||
animation: visual_bell_config.animation,
|
|
||||||
duration: visual_bell_config.duration(),
|
|
||||||
start_time: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ring the visual bell, and return its intensity.
|
/// Ring the visual bell, and return its intensity.
|
||||||
pub fn ring(&mut self) -> f64 {
|
pub fn ring(&mut self) -> f64 {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
@ -557,19 +548,17 @@ impl VisualBell {
|
||||||
// VisualBell. When `time` is 0.0, `inverse_intensity` is 0.0,
|
// VisualBell. When `time` is 0.0, `inverse_intensity` is 0.0,
|
||||||
// and when `time` is 1.0, `inverse_intensity` is 1.0.
|
// and when `time` is 1.0, `inverse_intensity` is 1.0.
|
||||||
let inverse_intensity = match self.animation {
|
let inverse_intensity = match self.animation {
|
||||||
VisualBellAnimation::Ease | VisualBellAnimation::EaseOut => {
|
BellAnimation::Ease | BellAnimation::EaseOut => {
|
||||||
cubic_bezier(0.25, 0.1, 0.25, 1.0, time)
|
cubic_bezier(0.25, 0.1, 0.25, 1.0, time)
|
||||||
},
|
},
|
||||||
VisualBellAnimation::EaseOutSine => cubic_bezier(0.39, 0.575, 0.565, 1.0, time),
|
BellAnimation::EaseOutSine => cubic_bezier(0.39, 0.575, 0.565, 1.0, time),
|
||||||
VisualBellAnimation::EaseOutQuad => cubic_bezier(0.25, 0.46, 0.45, 0.94, time),
|
BellAnimation::EaseOutQuad => cubic_bezier(0.25, 0.46, 0.45, 0.94, time),
|
||||||
VisualBellAnimation::EaseOutCubic => {
|
BellAnimation::EaseOutCubic => cubic_bezier(0.215, 0.61, 0.355, 1.0, time),
|
||||||
cubic_bezier(0.215, 0.61, 0.355, 1.0, time)
|
BellAnimation::EaseOutQuart => cubic_bezier(0.165, 0.84, 0.44, 1.0, time),
|
||||||
},
|
BellAnimation::EaseOutQuint => cubic_bezier(0.23, 1.0, 0.32, 1.0, time),
|
||||||
VisualBellAnimation::EaseOutQuart => cubic_bezier(0.165, 0.84, 0.44, 1.0, time),
|
BellAnimation::EaseOutExpo => cubic_bezier(0.19, 1.0, 0.22, 1.0, time),
|
||||||
VisualBellAnimation::EaseOutQuint => cubic_bezier(0.23, 1.0, 0.32, 1.0, time),
|
BellAnimation::EaseOutCirc => cubic_bezier(0.075, 0.82, 0.165, 1.0, time),
|
||||||
VisualBellAnimation::EaseOutExpo => cubic_bezier(0.19, 1.0, 0.22, 1.0, time),
|
BellAnimation::Linear => time,
|
||||||
VisualBellAnimation::EaseOutCirc => cubic_bezier(0.075, 0.82, 0.165, 1.0, time),
|
|
||||||
VisualBellAnimation::Linear => time,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Since we want the `intensity` of the VisualBell to decay over
|
// Since we want the `intensity` of the VisualBell to decay over
|
||||||
|
@ -580,9 +569,19 @@ impl VisualBell {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_config<C>(&mut self, config: &Config<C>) {
|
pub fn update_config<C>(&mut self, config: &Config<C>) {
|
||||||
let visual_bell_config = &config.visual_bell;
|
let bell_config = config.bell();
|
||||||
self.animation = visual_bell_config.animation;
|
self.animation = bell_config.animation;
|
||||||
self.duration = visual_bell_config.duration();
|
self.duration = bell_config.duration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&BellConfig> for VisualBell {
|
||||||
|
fn from(bell_config: &BellConfig) -> VisualBell {
|
||||||
|
VisualBell {
|
||||||
|
animation: bell_config.animation,
|
||||||
|
duration: bell_config.duration(),
|
||||||
|
start_time: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +762,7 @@ impl<T> Term<T> {
|
||||||
|
|
||||||
Term {
|
Term {
|
||||||
dirty: false,
|
dirty: false,
|
||||||
visual_bell: VisualBell::new(config),
|
visual_bell: config.bell().into(),
|
||||||
grid,
|
grid,
|
||||||
inactive_grid: alt,
|
inactive_grid: alt,
|
||||||
active_charset: Default::default(),
|
active_charset: Default::default(),
|
||||||
|
@ -1617,7 +1616,7 @@ impl<T: EventListener> Handler for Term<T> {
|
||||||
fn bell(&mut self) {
|
fn bell(&mut self) {
|
||||||
trace!("Bell");
|
trace!("Bell");
|
||||||
self.visual_bell.ring();
|
self.visual_bell.ring();
|
||||||
self.event_proxy.send_event(Event::Urgent);
|
self.event_proxy.send_event(Event::Bell);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
11
alacritty_terminal/src/thread.rs
Normal file
11
alacritty_terminal/src/thread.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
use std::thread::{Builder, JoinHandle};
|
||||||
|
|
||||||
|
/// Like `thread::spawn`, but with a `name` argument.
|
||||||
|
pub fn spawn_named<F, T, S>(name: S, f: F) -> JoinHandle<T>
|
||||||
|
where
|
||||||
|
F: FnOnce() -> T + Send + 'static,
|
||||||
|
T: Send + 'static,
|
||||||
|
S: Into<String>,
|
||||||
|
{
|
||||||
|
Builder::new().name(name.into()).spawn(f).expect("thread spawn works")
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue