mirror of
https://github.com/alacritty/alacritty.git
synced 2025-08-28 22:34:13 -04:00
Add option to drain PTY on shutdown
This patch removes the `hold` option on `alacritty_terminal` in favor of a `drain_on_exit` option, which will drain the PTY before shutdown. The hold logic is instead handled in `alacritty`.
This commit is contained in:
parent
c9c41e637a
commit
5e78d20c70
9 changed files with 41 additions and 23 deletions
|
@ -189,7 +189,7 @@ impl TerminalOptions {
|
||||||
pty_config.shell = Some(command.into());
|
pty_config.shell = Some(command.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pty_config.hold |= self.hold;
|
pty_config.drain_on_exit |= self.hold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ impl From<TerminalOptions> for PtyOptions {
|
||||||
PtyOptions {
|
PtyOptions {
|
||||||
working_directory: options.working_directory.take(),
|
working_directory: options.working_directory.take(),
|
||||||
shell: options.command().map(Into::into),
|
shell: options.command().map(Into::into),
|
||||||
hold: options.hold,
|
drain_on_exit: options.hold,
|
||||||
env: HashMap::new(),
|
env: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ impl UiConfig {
|
||||||
let shell = self.terminal.shell.clone().or_else(|| self.shell.clone()).map(Into::into);
|
let shell = self.terminal.shell.clone().or_else(|| self.shell.clone()).map(Into::into);
|
||||||
let working_directory =
|
let working_directory =
|
||||||
self.working_directory.clone().or_else(|| self.general.working_directory.clone());
|
self.working_directory.clone().or_else(|| self.general.working_directory.clone());
|
||||||
PtyOptions { working_directory, shell, hold: false, env: HashMap::new() }
|
PtyOptions { working_directory, shell, drain_on_exit: false, env: HashMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate key bindings for all keyboard hints.
|
/// Generate key bindings for all keyboard hints.
|
||||||
|
|
|
@ -109,6 +109,9 @@ pub struct Window {
|
||||||
/// Flag indicating whether redraw was requested.
|
/// Flag indicating whether redraw was requested.
|
||||||
pub requested_redraw: bool,
|
pub requested_redraw: bool,
|
||||||
|
|
||||||
|
/// Hold the window when terminal exits.
|
||||||
|
pub hold: bool,
|
||||||
|
|
||||||
window: WinitWindow,
|
window: WinitWindow,
|
||||||
|
|
||||||
/// Current window title.
|
/// Current window title.
|
||||||
|
@ -127,7 +130,7 @@ impl Window {
|
||||||
event_loop: &ActiveEventLoop,
|
event_loop: &ActiveEventLoop,
|
||||||
config: &UiConfig,
|
config: &UiConfig,
|
||||||
identity: &Identity,
|
identity: &Identity,
|
||||||
_options: &mut WindowOptions,
|
options: &mut WindowOptions,
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
||||||
x11_visual: Option<X11VisualInfo>,
|
x11_visual: Option<X11VisualInfo>,
|
||||||
|
@ -139,7 +142,7 @@ impl Window {
|
||||||
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
|
||||||
x11_visual,
|
x11_visual,
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
&_options.window_tabbing_id.take(),
|
&options.window_tabbing_id.take(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(position) = config.window.position {
|
if let Some(position) = config.window.position {
|
||||||
|
@ -148,7 +151,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "macos", windows)))]
|
#[cfg(not(any(target_os = "macos", windows)))]
|
||||||
if let Some(token) = _options
|
if let Some(token) = options
|
||||||
.activation_token
|
.activation_token
|
||||||
.take()
|
.take()
|
||||||
.map(ActivationToken::from_raw)
|
.map(ActivationToken::from_raw)
|
||||||
|
@ -199,6 +202,7 @@ impl Window {
|
||||||
let is_x11 = matches!(window.window_handle().unwrap().as_raw(), RawWindowHandle::Xlib(_));
|
let is_x11 = matches!(window.window_handle().unwrap().as_raw(), RawWindowHandle::Xlib(_));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
hold: options.terminal_options.hold,
|
||||||
requested_redraw: false,
|
requested_redraw: false,
|
||||||
title: identity.title,
|
title: identity.title,
|
||||||
current_mouse_cursor,
|
current_mouse_cursor,
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::ConfigMonitor;
|
||||||
use glutin::config::GetGlConfig;
|
use glutin::config::GetGlConfig;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
|
@ -380,9 +381,14 @@ impl ApplicationHandler<Event> for Processor {
|
||||||
},
|
},
|
||||||
(EventType::Terminal(TerminalEvent::Exit), Some(window_id)) => {
|
(EventType::Terminal(TerminalEvent::Exit), Some(window_id)) => {
|
||||||
// Remove the closed terminal.
|
// Remove the closed terminal.
|
||||||
let window_context = match self.windows.remove(window_id) {
|
let window_context = match self.windows.entry(*window_id) {
|
||||||
Some(window_context) => window_context,
|
// Don't exit when terminal exits if user asked to hold the window.
|
||||||
None => return,
|
Entry::Occupied(window_context)
|
||||||
|
if !window_context.get().display.window.hold =>
|
||||||
|
{
|
||||||
|
window_context.remove()
|
||||||
|
},
|
||||||
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Unschedule pending events.
|
// Unschedule pending events.
|
||||||
|
@ -1793,7 +1799,11 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
|
||||||
},
|
},
|
||||||
WinitEvent::WindowEvent { event, .. } => {
|
WinitEvent::WindowEvent { event, .. } => {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::CloseRequested => self.ctx.terminal.exit(),
|
WindowEvent::CloseRequested => {
|
||||||
|
// User asked to close the window, so no need to hold it.
|
||||||
|
self.ctx.window().hold = false;
|
||||||
|
self.ctx.terminal.exit();
|
||||||
|
},
|
||||||
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
|
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
|
||||||
let old_scale_factor =
|
let old_scale_factor =
|
||||||
mem::replace(&mut self.ctx.window().scale_factor, scale_factor);
|
mem::replace(&mut self.ctx.window().scale_factor, scale_factor);
|
||||||
|
|
|
@ -324,7 +324,10 @@ impl<T: EventListener> Execute<T> for Action {
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
Action::Hide => ctx.window().set_visible(false),
|
Action::Hide => ctx.window().set_visible(false),
|
||||||
Action::Minimize => ctx.window().set_minimized(true),
|
Action::Minimize => ctx.window().set_minimized(true),
|
||||||
Action::Quit => ctx.terminal_mut().exit(),
|
Action::Quit => {
|
||||||
|
ctx.window().hold = false;
|
||||||
|
ctx.terminal_mut().exit();
|
||||||
|
},
|
||||||
Action::IncreaseFontSize => ctx.change_font_size(FONT_SIZE_STEP),
|
Action::IncreaseFontSize => ctx.change_font_size(FONT_SIZE_STEP),
|
||||||
Action::DecreaseFontSize => ctx.change_font_size(-FONT_SIZE_STEP),
|
Action::DecreaseFontSize => ctx.change_font_size(-FONT_SIZE_STEP),
|
||||||
Action::ResetFontSize => ctx.reset_font_size(),
|
Action::ResetFontSize => ctx.reset_font_size(),
|
||||||
|
|
|
@ -212,7 +212,7 @@ impl WindowContext {
|
||||||
Arc::clone(&terminal),
|
Arc::clone(&terminal),
|
||||||
event_proxy.clone(),
|
event_proxy.clone(),
|
||||||
pty,
|
pty,
|
||||||
pty_config.hold,
|
pty_config.drain_on_exit,
|
||||||
config.debug.ref_test,
|
config.debug.ref_test,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,11 @@ sections should follow the order `Added`, `Changed`, `Deprecated`, `Fixed` and
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## 0.24.3-dev
|
## 0.25.0-dev
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Replaced `Options::hold` with `Options::drain_on_exit` that drains, but doesn't hold, since holding can be done outside of alacritty_terminal
|
||||||
|
|
||||||
## 0.24.2
|
## 0.24.2
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub struct EventLoop<T: tty::EventedPty, U: EventListener> {
|
||||||
tx: Sender<Msg>,
|
tx: Sender<Msg>,
|
||||||
terminal: Arc<FairMutex<Term<U>>>,
|
terminal: Arc<FairMutex<Term<U>>>,
|
||||||
event_proxy: U,
|
event_proxy: U,
|
||||||
hold: bool,
|
drain_on_exit: bool,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ where
|
||||||
terminal: Arc<FairMutex<Term<U>>>,
|
terminal: Arc<FairMutex<Term<U>>>,
|
||||||
event_proxy: U,
|
event_proxy: U,
|
||||||
pty: T,
|
pty: T,
|
||||||
hold: bool,
|
drain_on_exit: bool,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
) -> io::Result<EventLoop<T, U>> {
|
) -> io::Result<EventLoop<T, U>> {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
@ -76,7 +76,7 @@ where
|
||||||
rx: PeekableReceiver::new(rx),
|
rx: PeekableReceiver::new(rx),
|
||||||
terminal,
|
terminal,
|
||||||
event_proxy,
|
event_proxy,
|
||||||
hold,
|
drain_on_exit,
|
||||||
ref_test,
|
ref_test,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -261,13 +261,10 @@ where
|
||||||
if let Some(code) = code {
|
if let Some(code) = code {
|
||||||
self.event_proxy.send_event(Event::ChildExit(code));
|
self.event_proxy.send_event(Event::ChildExit(code));
|
||||||
}
|
}
|
||||||
if self.hold {
|
if self.drain_on_exit {
|
||||||
// With hold enabled, make sure the PTY is drained.
|
|
||||||
let _ = self.pty_read(&mut state, &mut buf, pipe.as_mut());
|
let _ = self.pty_read(&mut state, &mut buf, pipe.as_mut());
|
||||||
} else {
|
|
||||||
// Without hold, shutdown the terminal.
|
|
||||||
self.terminal.lock().exit();
|
|
||||||
}
|
}
|
||||||
|
self.terminal.lock().exit();
|
||||||
self.event_proxy.send_event(Event::Wakeup);
|
self.event_proxy.send_event(Event::Wakeup);
|
||||||
break 'event_loop;
|
break 'event_loop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ pub struct Options {
|
||||||
/// Shell startup directory.
|
/// Shell startup directory.
|
||||||
pub working_directory: Option<PathBuf>,
|
pub working_directory: Option<PathBuf>,
|
||||||
|
|
||||||
/// Remain open after child process exits.
|
/// Drain the child process output before exiting the terminal.
|
||||||
pub hold: bool,
|
pub drain_on_exit: bool,
|
||||||
|
|
||||||
/// Extra environment variables.
|
/// Extra environment variables.
|
||||||
pub env: HashMap<String, String>,
|
pub env: HashMap<String, String>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue