From e79f4b22d809d12b5f09543872443d0fa818fee2 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 4 Jan 2025 09:34:44 +0300 Subject: Pass activation token in alacritty msg create-window Fixes #8337. --- CHANGELOG.md | 1 + alacritty/src/cli.rs | 5 +++++ alacritty/src/display/window.rs | 16 +++++++++++----- alacritty/src/main.rs | 10 +++++++++- alacritty/src/window_context.rs | 12 +++++------- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f23f442f..882c7c1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Config option `window.level = "AlwaysOnTop"` to force Alacritty to always be the toplevel window - Escape sequence to move cursor forward tabs ( CSI Ps I ) +- Pass activation token in `alacritty msg create-window` on Wayland/X11 ### Changed diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index bb0a24f4..5010ffc8 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -300,6 +300,11 @@ pub struct WindowOptions { /// The window tabbing identifier to use when building a window. pub window_tabbing_id: Option, + #[clap(skip)] + #[cfg(not(any(target_os = "macos", windows)))] + /// `ActivationToken` that we pass to winit. + pub activation_token: Option, + /// Override configuration file options [example: 'cursor.style="Beam"']. #[clap(short = 'o', long, num_args = 1..)] option: Vec, diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index 1c8089bc..fe40fab5 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -2,6 +2,8 @@ use winit::platform::startup_notify::{ self, EventLoopExtStartupNotify, WindowAttributesExtStartupNotify, }; +#[cfg(not(any(target_os = "macos", windows)))] +use winit::window::ActivationToken; #[cfg(all(not(feature = "x11"), not(any(target_os = "macos", windows))))] use winit::platform::wayland::WindowAttributesExtWayland; @@ -38,6 +40,7 @@ use winit::window::{ use alacritty_terminal::index::Point; +use crate::cli::WindowOptions; use crate::config::window::{Decorations, Identity, WindowConfig}; use crate::config::UiConfig; use crate::display::SizeInfo; @@ -124,9 +127,7 @@ impl Window { event_loop: &ActiveEventLoop, config: &UiConfig, identity: &Identity, - #[rustfmt::skip] - #[cfg(target_os = "macos")] - tabbing_id: &Option, + _options: &mut WindowOptions, #[rustfmt::skip] #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual: Option, @@ -138,7 +139,7 @@ impl Window { #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual, #[cfg(target_os = "macos")] - tabbing_id, + &_options.window_tabbing_id.take(), ); if let Some(position) = config.window.position { @@ -147,7 +148,12 @@ impl Window { } #[cfg(not(any(target_os = "macos", windows)))] - if let Some(token) = event_loop.read_token_from_env() { + if let Some(token) = _options + .activation_token + .take() + .map(ActivationToken::from_raw) + .or_else(|| event_loop.read_token_from_env()) + { log::debug!("Activating window with token: {token:?}"); window_attributes = window_attributes.with_activation_token(token); diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 6bbf8dfd..5382e475 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -55,6 +55,8 @@ mod gl { #[cfg(unix)] use crate::cli::MessageOptions; +#[cfg(not(any(target_os = "macos", windows)))] +use crate::cli::SocketMessage; use crate::cli::{Options, Subcommands}; use crate::config::monitor::ConfigMonitor; use crate::config::UiConfig; @@ -89,7 +91,13 @@ fn main() -> Result<(), Box> { /// `msg` subcommand entrypoint. #[cfg(unix)] -fn msg(options: MessageOptions) -> Result<(), Box> { +#[allow(unused_mut)] +fn msg(mut options: MessageOptions) -> Result<(), Box> { + #[cfg(not(any(target_os = "macos", windows)))] + if let SocketMessage::CreateWindow(window_options) = &mut options.message { + window_options.activation_token = + env::var("XDG_ACTIVATION_TOKEN").or_else(|_| env::var("DESKTOP_STARTUP_ID")).ok(); + } ipc::send_message(options.socket, options.message).map_err(|err| err.into()) } diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index cfc3cd96..e3c39382 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -73,7 +73,7 @@ impl WindowContext { event_loop: &ActiveEventLoop, proxy: EventLoopProxy, config: Rc, - options: WindowOptions, + mut options: WindowOptions, ) -> Result> { let raw_display_handle = event_loop.display_handle().unwrap().as_raw(); @@ -83,7 +83,7 @@ impl WindowContext { // Windows has different order of GL platform initialization compared to any other platform; // it requires the window first. #[cfg(windows)] - let window = Window::new(event_loop, &config, &identity)?; + let window = Window::new(event_loop, &config, &identity, &mut options)?; #[cfg(windows)] let raw_window_handle = Some(window.raw_window_handle()); @@ -102,10 +102,9 @@ impl WindowContext { event_loop, &config, &identity, + &mut options, #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] gl_config.x11_visual(), - #[cfg(target_os = "macos")] - &options.window_tabbing_id, )?; // Create context. @@ -123,7 +122,7 @@ impl WindowContext { event_loop: &ActiveEventLoop, proxy: EventLoopProxy, config: Rc, - options: WindowOptions, + mut options: WindowOptions, config_overrides: ParsedOptions, ) -> Result> { let gl_display = gl_config.display(); @@ -135,10 +134,9 @@ impl WindowContext { event_loop, &config, &identity, + &mut options, #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] gl_config.x11_visual(), - #[cfg(target_os = "macos")] - &options.window_tabbing_id, )?; // Create context. -- cgit From f0e5ec4d05b6a7719aac526eb332c33176d099a4 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 5 Jan 2025 11:42:00 +0300 Subject: Fix changelog entries being in past release --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 882c7c1c..9c1c369f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Always focus new windows on macOS - Don't switch to semantic/line selection when control is pressed +- Always emit `1` for the first parameter when having modifiers in kitty keyboard protocol ### Fixed @@ -30,6 +31,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Migrating nonexistent toml import breaking the entire migration - First daemon mode window ignoring window options passed through CLI - Report of Enter/Tab/Backspace in kitty keyboard's report event types mode +- Crash when pressing certain modifier keys on macOS 15+ ## 0.14.0 @@ -53,7 +55,6 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Moved config option `shell` to `terminal.shell` - `ctrl+shift+u` binding to open links to `ctrl+shift+o` to avoid collisions with IMEs - Use `Beam` cursor for single char cursor inside the IME preview -- Always emit `1` for the first parameter when having modifiers in kitty keyboard protocol ### Fixed @@ -75,7 +76,6 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Invalid URL highlights after terminal scrolling - Hollow block cursor not spanning multiple chars being edited inside the IME preview - Vi inline search only working for direct key input without modifiers -- Crash when pressing certain modifier keys on macOS 15+ ## 0.13.2 -- cgit From a26174890e2184fa29b68fde7b72de5a566ad711 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Mon, 6 Jan 2025 07:23:36 +0300 Subject: Bump development version to 0.16.0-dev This is only an update to the development version and does not represent a stable release. --- CHANGELOG.md | 4 +++- Cargo.lock | 4 ++-- alacritty/Cargo.toml | 4 ++-- alacritty/windows/wix/alacritty.wxs | 2 +- alacritty_terminal/CHANGELOG.md | 4 +++- alacritty_terminal/Cargo.toml | 2 +- extra/osx/Alacritty.app/Contents/Info.plist | 2 +- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c1c369f..9fe121d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Notable changes to the `alacritty_terminal` crate are documented in its [CHANGELOG](./alacritty_terminal/CHANGELOG.md). -## 0.15.0-dev +## 0.16.0-dev + +## 0.15.0 ### Added diff --git a/Cargo.lock b/Cargo.lock index b7a2d9b8..74210710 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,7 +32,7 @@ dependencies = [ [[package]] name = "alacritty" -version = "0.15.0-dev" +version = "0.16.0-dev" dependencies = [ "ahash", "alacritty_config", @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.24.2-dev" +version = "0.24.3-dev" dependencies = [ "base64", "bitflags 2.6.0", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 6d05983a..c5251597 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty" -version = "0.15.0-dev" +version = "0.16.0-dev" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "A fast, cross-platform, OpenGL terminal emulator" @@ -12,7 +12,7 @@ rust-version = "1.74.0" [dependencies.alacritty_terminal] path = "../alacritty_terminal" -version = "0.24.2-dev" +version = "0.24.3-dev" [dependencies.alacritty_config_derive] path = "../alacritty_config_derive" diff --git a/alacritty/windows/wix/alacritty.wxs b/alacritty/windows/wix/alacritty.wxs index 5c05d821..bcf59cf5 100644 --- a/alacritty/windows/wix/alacritty.wxs +++ b/alacritty/windows/wix/alacritty.wxs @@ -1,5 +1,5 @@ - + diff --git a/alacritty_terminal/CHANGELOG.md b/alacritty_terminal/CHANGELOG.md index a6ee32b2..55c21d3f 100644 --- a/alacritty_terminal/CHANGELOG.md +++ b/alacritty_terminal/CHANGELOG.md @@ -8,7 +8,9 @@ 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/). -## 0.24.2-dev +## 0.24.3-dev + +## 0.24.2 ### Added diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 32e09a72..53e0be10 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty_terminal" -version = "0.24.2-dev" +version = "0.24.3-dev" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "Library for writing terminal emulators" diff --git a/extra/osx/Alacritty.app/Contents/Info.plist b/extra/osx/Alacritty.app/Contents/Info.plist index 59c70ff2..ca8d2d7b 100644 --- a/extra/osx/Alacritty.app/Contents/Info.plist +++ b/extra/osx/Alacritty.app/Contents/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.15.0-dev + 0.16.0-dev CFBundleSupportedPlatforms MacOSX -- cgit From 8833551b0da3fdace94e1e6c07c6f57f45d9065e Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 8 Jan 2025 17:26:48 +0300 Subject: Fix crash during live output search Sometimes points could end up outside of viewport, thus the screen will need to be invalidated. The default unwrapping does handle both cases. Fixes: a1ed79bd2c01 (Fix highlight invalidation on grid scroll) --- alacritty/src/display/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 4211da5f..6c685a2a 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -1349,6 +1349,8 @@ impl Display { (&mut self.highlighted_hint, &mut self.highlighted_hint_age, true), (&mut self.vi_highlighted_hint, &mut self.vi_highlighted_hint_age, false), ]; + + let num_lines = self.size_info.screen_lines(); for (hint, hint_age, reset_mouse) in hints { let (start, end) = match hint { Some(hint) => (*hint.bounds().start(), *hint.bounds().end()), @@ -1362,10 +1364,12 @@ impl Display { } // Convert hint bounds to viewport coordinates. - let start = term::point_to_viewport(display_offset, start).unwrap_or_default(); - let end = term::point_to_viewport(display_offset, end).unwrap_or_else(|| { - Point::new(self.size_info.screen_lines() - 1, self.size_info.last_column()) - }); + let start = term::point_to_viewport(display_offset, start) + .filter(|point| point.line < num_lines) + .unwrap_or_default(); + let end = term::point_to_viewport(display_offset, end) + .filter(|point| point.line < num_lines) + .unwrap_or_else(|| Point::new(num_lines - 1, self.size_info.last_column())); // Clear invalidated hints. if frame.intersects(start, end) { -- cgit From 8ab406d3fd51620a1ded910bc89fc02a2bcb838a Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Thu, 9 Jan 2025 10:02:20 +0000 Subject: Bump VTE to 0.14.0 Since this is a breaking change, it also bumps the alacritty_terminal development version to 0.25.0-dev. --- Cargo.lock | 12 ++++++------ alacritty/Cargo.toml | 2 +- alacritty_terminal/Cargo.toml | 4 ++-- alacritty_terminal/src/event_loop.rs | 6 ++---- alacritty_terminal/tests/ref.rs | 4 +--- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74210710..c55d1fc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.24.3-dev" +version = "0.25.0-dev" dependencies = [ "base64", "bitflags 2.6.0", @@ -2045,23 +2045,23 @@ dependencies = [ [[package]] name = "vte" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a0b683b20ef64071ff03745b14391751f6beab06a54347885459b77a3f2caa5" +checksum = "5507b53f7756f79bdb968d038a8f8db570d88028aee3c3cdc20427a8fb3482f4" dependencies = [ "bitflags 2.6.0", "cursor-icon", "log", + "memchr", "serde", - "utf8parse", "vte_generate_state_changes", ] [[package]] name = "vte_generate_state_changes" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" +checksum = "e658bbb246cd98d720db0b7553764f7e841e25d9ac0c9ecfbc09452dc95a8cce" dependencies = [ "proc-macro2", "quote", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index c5251597..6fb2ee2b 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.74.0" [dependencies.alacritty_terminal] path = "../alacritty_terminal" -version = "0.24.3-dev" +version = "0.25.0-dev" [dependencies.alacritty_config_derive] path = "../alacritty_config_derive" diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 53e0be10..a5c8e1ae 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty_terminal" -version = "0.24.3-dev" +version = "0.25.0-dev" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "Library for writing terminal emulators" @@ -24,7 +24,7 @@ parking_lot = "0.12.0" polling = "3.0.0" regex-automata = "0.4.3" unicode-width = "0.1" -vte = { version = "0.13.0", default-features = false, features = ["ansi"] } +vte = { version = "0.14.0", default-features = false, features = ["ansi"] } serde = { version = "1", features = ["derive", "rc"], optional = true } [target.'cfg(unix)'.dependencies] diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs index 62dd7440..2b78f853 100644 --- a/alacritty_terminal/src/event_loop.rs +++ b/alacritty_terminal/src/event_loop.rs @@ -17,8 +17,8 @@ use polling::{Event as PollingEvent, Events, PollMode}; use crate::event::{self, Event, EventListener, WindowSize}; use crate::sync::FairMutex; use crate::term::Term; -use crate::vte::ansi; use crate::{thread, tty}; +use vte::ansi; /// Max bytes to read from the PTY before forced terminal synchronization. pub(crate) const READ_BUFFER_SIZE: usize = 0x10_0000; @@ -151,9 +151,7 @@ where } // Parse the incoming bytes. - for byte in &buf[..unprocessed] { - state.parser.advance(&mut **terminal, *byte); - } + state.parser.advance(&mut **terminal, &buf[..unprocessed]); processed += unprocessed; unprocessed = 0; diff --git a/alacritty_terminal/tests/ref.rs b/alacritty_terminal/tests/ref.rs index 1f992941..454f2e5d 100644 --- a/alacritty_terminal/tests/ref.rs +++ b/alacritty_terminal/tests/ref.rs @@ -112,9 +112,7 @@ fn ref_test(dir: &Path) { let mut terminal = Term::new(options, &size, Mock); let mut parser: ansi::Processor = ansi::Processor::new(); - for byte in recording { - parser.advance(&mut terminal, byte); - } + parser.advance(&mut terminal, &recording); // Truncate invisible lines from the grid. let mut term_grid = terminal.grid().clone(); -- cgit From 28910e3adc9d48edc4f43008d987eecd869ded31 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 10 Jan 2025 06:57:21 +0300 Subject: Fix cut off wide characters in preedit string The wide char spacers must not be drawn, like we do for regular wide characters. --- CHANGELOG.md | 1 + alacritty/src/renderer/mod.rs | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fe121d4..6ab157db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - First daemon mode window ignoring window options passed through CLI - Report of Enter/Tab/Backspace in kitty keyboard's report event types mode - Crash when pressing certain modifier keys on macOS 15+ +- Cut off wide characters in preedit string ## 0.14.0 diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 16885b31..3362db42 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -206,10 +206,10 @@ impl Renderer { glyph_cache: &mut GlyphCache, ) { let mut wide_char_spacer = false; - let cells = string_chars.enumerate().map(|(i, character)| { + let cells = string_chars.enumerate().filter_map(|(i, character)| { let flags = if wide_char_spacer { wide_char_spacer = false; - Flags::WIDE_CHAR_SPACER + return None; } else if character.width() == Some(2) { // The spacer is always following the wide char. wide_char_spacer = true; @@ -218,7 +218,7 @@ impl Renderer { Flags::empty() }; - RenderableCell { + Some(RenderableCell { point: Point::new(point.line, point.column + i), character, extra: None, @@ -227,7 +227,7 @@ impl Renderer { fg, bg, underline: fg, - } + }) }); self.draw_cells(size_info, glyph_cache, cells); -- cgit From cd884c984bbd6a7c65965681083da61e091ff7e5 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 11 Jan 2025 08:47:32 +0300 Subject: Try to recover from GPU resets Use context robustness to get notified about GPU resets and try to recover from them by rebuilding the rendering pipeline. --- CHANGELOG.md | 1 + alacritty/build.rs | 1 + alacritty/src/display/mod.rs | 61 ++++++++++++++++++++++++++++++++++---- alacritty/src/renderer/mod.rs | 61 +++++++++++++++++++++++++++++++------- alacritty/src/renderer/platform.rs | 22 +++++++++----- 5 files changed, 123 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ab157db..c8666916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Report of Enter/Tab/Backspace in kitty keyboard's report event types mode - Crash when pressing certain modifier keys on macOS 15+ - Cut off wide characters in preedit string +- Crash when OpenGL context resets ## 0.14.0 diff --git a/alacritty/build.rs b/alacritty/build.rs index 7c33040e..0856e3a5 100644 --- a/alacritty/build.rs +++ b/alacritty/build.rs @@ -17,6 +17,7 @@ fn main() { Registry::new(Api::Gl, (3, 3), Profile::Core, Fallbacks::All, [ "GL_ARB_blend_func_extended", + "GL_KHR_robustness", "GL_KHR_debug", ]) .write_bindings(GlobalGenerator, &mut file) diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 6c685a2a..9f11ccf6 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -8,7 +8,10 @@ use std::num::NonZeroU32; use std::ops::{Deref, DerefMut}; use std::time::{Duration, Instant}; +use glutin::config::GetGlConfig; use glutin::context::{NotCurrentContext, PossiblyCurrentContext}; +use glutin::display::GetGlDisplay; +use glutin::error::ErrorKind; use glutin::prelude::*; use glutin::surface::{Surface, SwapInterval, WindowSurface}; @@ -33,6 +36,7 @@ use alacritty_terminal::term::{ }; use alacritty_terminal::vte::ansi::{CursorShape, NamedColor}; +use crate::config::debug::RendererPreference; use crate::config::font::Font; use crate::config::window::Dimensions; #[cfg(not(windows))] @@ -49,7 +53,7 @@ use crate::display::window::Window; use crate::event::{Event, EventType, Mouse, SearchState}; use crate::message_bar::{MessageBuffer, MessageType}; use crate::renderer::rects::{RenderLine, RenderLines, RenderRect}; -use crate::renderer::{self, GlyphCache, Renderer}; +use crate::renderer::{self, platform, GlyphCache, Renderer}; use crate::scheduler::{Scheduler, TimerId, Topic}; use crate::string::{ShortenDirection, StrShortener}; @@ -385,6 +389,7 @@ pub struct Display { hint_mouse_point: Option, renderer: ManuallyDrop, + renderer_preference: Option, surface: ManuallyDrop>, @@ -421,7 +426,7 @@ impl Display { } // Create the GL surface to draw into. - let surface = renderer::platform::create_gl_surface( + let surface = platform::create_gl_surface( &gl_context, window.inner_size(), window.raw_window_handle(), @@ -513,6 +518,7 @@ impl Display { context: ManuallyDrop::new(Replaceable::new(context)), visual_bell: VisualBell::from(&config.bell), renderer: ManuallyDrop::new(renderer), + renderer_preference: config.debug.renderer, surface: ManuallyDrop::new(surface), colors: List::from(&config.colors), frame_timer: FrameTimer::new(), @@ -552,10 +558,55 @@ impl Display { } } - pub fn make_current(&self) { - if !self.context.get().is_current() { - self.context.make_current(&self.surface).expect("failed to make context current") + pub fn make_current(&mut self) { + let is_current = self.context.get().is_current(); + + // Attempt to make the context current if it's not. + let context_loss = if is_current { + self.renderer.was_context_reset() + } else { + match self.context.make_current(&self.surface) { + Err(err) if err.error_kind() == ErrorKind::ContextLost => { + info!("Context lost for window {:?}", self.window.id()); + true + }, + _ => false, + } + }; + + if !context_loss { + return; + } + + let gl_display = self.context.display(); + let gl_config = self.context.config(); + let raw_window_handle = Some(self.window.raw_window_handle()); + let context = platform::create_gl_context(&gl_display, &gl_config, raw_window_handle) + .expect("failed to recreate context."); + + // Drop the old context and renderer. + unsafe { + ManuallyDrop::drop(&mut self.renderer); + ManuallyDrop::drop(&mut self.context); } + + // Activate new context. + let context = context.treat_as_possibly_current(); + self.context = ManuallyDrop::new(Replaceable::new(context)); + self.context.make_current(&self.surface).expect("failed to reativate context after reset."); + + // Recreate renderer. + let renderer = Renderer::new(&self.context, self.renderer_preference) + .expect("failed to recreate renderer after reset"); + self.renderer = ManuallyDrop::new(renderer); + + // Resize the renderer. + self.renderer.resize(&self.size_info); + + self.reset_glyph_cache(); + self.damage_tracker.frame().mark_fully_damaged(); + + debug!("Recovered window {:?} from gpu reset", self.window.id()); } fn swap_buffers(&self) { diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 3362db42..92998e58 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -9,7 +9,7 @@ use ahash::RandomState; use crossfont::Metrics; use glutin::context::{ContextApi, GlContext, PossiblyCurrentContext}; use glutin::display::{GetGlDisplay, GlDisplay}; -use log::{debug, error, info, warn, LevelFilter}; +use log::{debug, info, LevelFilter}; use unicode_width::UnicodeWidthChar; use alacritty_terminal::index::Point; @@ -97,6 +97,7 @@ enum TextRendererProvider { pub struct Renderer { text_renderer: TextRendererProvider, rect_renderer: RectRenderer, + robustness: bool, } /// Wrapper around gl::GetString with error checking and reporting. @@ -144,6 +145,9 @@ impl Renderer { info!("Running on {renderer}"); info!("OpenGL version {gl_version}, shader_version {shader_version}"); + // Check if robustness is supported. + let robustness = Self::supports_robustness(); + let is_gles_context = matches!(context.context_api(), ContextApi::Gles(_)); // Use the config option to enforce a particular renderer configuration. @@ -175,7 +179,7 @@ impl Renderer { } } - Ok(Self { text_renderer, rect_renderer }) + Ok(Self { text_renderer, rect_renderer, robustness }) } pub fn draw_cells>( @@ -281,6 +285,49 @@ impl Renderer { } } + /// Get the context reset status. + pub fn was_context_reset(&self) -> bool { + // If robustness is not supported, don't use its functions. + if !self.robustness { + return false; + } + + let status = unsafe { gl::GetGraphicsResetStatus() }; + if status == gl::NO_ERROR { + false + } else { + let reason = match status { + gl::GUILTY_CONTEXT_RESET_KHR => "guilty", + gl::INNOCENT_CONTEXT_RESET_KHR => "innocent", + gl::UNKNOWN_CONTEXT_RESET_KHR => "unknown", + _ => "invalid", + }; + + info!("GPU reset ({})", reason); + + true + } + } + + fn supports_robustness() -> bool { + let mut notification_strategy = 0; + if GlExtensions::contains("GL_KHR_robustness") { + unsafe { + gl::GetIntegerv(gl::RESET_NOTIFICATION_STRATEGY_KHR, &mut notification_strategy); + } + } else { + notification_strategy = gl::NO_RESET_NOTIFICATION_KHR as gl::types::GLint; + } + + if notification_strategy == gl::LOSE_CONTEXT_ON_RESET_KHR as gl::types::GLint { + info!("GPU reset notifications are enabled"); + true + } else { + info!("GPU reset notifications are disabled"); + false + } + } + pub fn finish(&self) { unsafe { gl::Finish(); @@ -349,7 +396,7 @@ impl GlExtensions { extern "system" fn gl_debug_log( _: gl::types::GLenum, - kind: gl::types::GLenum, + _: gl::types::GLenum, _: gl::types::GLuint, _: gl::types::GLenum, _: gl::types::GLsizei, @@ -357,11 +404,5 @@ extern "system" fn gl_debug_log( _: *mut std::os::raw::c_void, ) { let msg = unsafe { CStr::from_ptr(msg).to_string_lossy() }; - match kind { - gl::DEBUG_TYPE_ERROR | gl::DEBUG_TYPE_UNDEFINED_BEHAVIOR => { - error!("[gl_render] {}", msg) - }, - gl::DEBUG_TYPE_DEPRECATED_BEHAVIOR => warn!("[gl_render] {}", msg), - _ => debug!("[gl_render] {}", msg), - } + debug!("[gl_render] {}", msg); } diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs index 87ed29c2..3b2e2fce 100644 --- a/alacritty/src/renderer/platform.rs +++ b/alacritty/src/renderer/platform.rs @@ -4,9 +4,9 @@ use std::num::NonZeroU32; use glutin::config::{ColorBufferType, Config, ConfigTemplateBuilder, GetGlConfig}; use glutin::context::{ - ContextApi, ContextAttributesBuilder, GlProfile, NotCurrentContext, Version, + ContextApi, ContextAttributesBuilder, GlProfile, NotCurrentContext, Robustness, Version, }; -use glutin::display::{Display, DisplayApiPreference, GetGlDisplay}; +use glutin::display::{Display, DisplayApiPreference, DisplayFeatures, GetGlDisplay}; use glutin::error::Result as GlutinResult; use glutin::prelude::*; use glutin::surface::{Surface, SurfaceAttributesBuilder, WindowSurface}; @@ -110,18 +110,24 @@ pub fn create_gl_context( raw_window_handle: Option, ) -> GlutinResult { let debug = log::max_level() >= LevelFilter::Debug; + let mut builder = ContextAttributesBuilder::new().with_debug(debug); + + // Try to enable robustness. + if gl_display.supported_features().contains(DisplayFeatures::CONTEXT_ROBUSTNESS) { + builder = builder.with_robustness(Robustness::RobustLoseContextOnReset); + } + let mut profiles = [ - ContextAttributesBuilder::new() - .with_debug(debug) + builder + .clone() .with_context_api(ContextApi::OpenGl(Some(Version::new(3, 3)))) .build(raw_window_handle), // Try gles before OpenGL 2.1 as it tends to be more stable. - ContextAttributesBuilder::new() - .with_debug(debug) + builder + .clone() .with_context_api(ContextApi::Gles(Some(Version::new(2, 0)))) .build(raw_window_handle), - ContextAttributesBuilder::new() - .with_debug(debug) + builder .with_profile(GlProfile::Compatibility) .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1)))) .build(raw_window_handle), -- cgit From 2290afff02bc8470fb4abeb2a2ffc1c22dc2ede7 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 12 Jan 2025 22:30:27 +0300 Subject: Bump glutin to 0.32.2 This cleans up context managing. --- Cargo.lock | 16 +++++------ alacritty/Cargo.toml | 2 +- alacritty/src/display/mod.rs | 64 +++++++------------------------------------- 3 files changed, 18 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c55d1fc1..9f294793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -814,9 +814,9 @@ dependencies = [ [[package]] name = "glutin" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" +checksum = "03642b8b0cce622392deb0ee3e88511f75df2daac806102597905c3ea1974848" dependencies = [ "bitflags 2.6.0", "cfg_aliases", @@ -839,9 +839,9 @@ dependencies = [ [[package]] name = "glutin_egl_sys" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" dependencies = [ "gl_generator", "windows-sys 0.52.0", @@ -849,9 +849,9 @@ dependencies = [ [[package]] name = "glutin_glx_sys" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" dependencies = [ "gl_generator", "x11-dl", @@ -859,9 +859,9 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" dependencies = [ "gl_generator", ] diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 6fb2ee2b..fb961d8f 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -28,7 +28,7 @@ bitflags = "2.2.1" clap = { version = "4.2.7", features = ["derive", "env"] } copypasta = { version = "0.10.1", default-features = false } crossfont = "0.8.0" -glutin = { version = "0.32.0", default-features = false, features = ["egl", "wgl"] } +glutin = { version = "0.32.2", default-features = false, features = ["egl", "wgl"] } home = "0.5.5" libc = "0.2" log = { version = "0.4", features = ["std", "serde"] } diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 9f11ccf6..6a84bf0f 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -5,7 +5,7 @@ use std::cmp; use std::fmt::{self, Formatter}; use std::mem::{self, ManuallyDrop}; use std::num::NonZeroU32; -use std::ops::{Deref, DerefMut}; +use std::ops::Deref; use std::time::{Duration, Instant}; use glutin::config::GetGlConfig; @@ -393,7 +393,7 @@ pub struct Display { surface: ManuallyDrop>, - context: ManuallyDrop>, + context: ManuallyDrop, glyph_cache: GlyphCache, meter: Meter, @@ -515,7 +515,7 @@ impl Display { } Ok(Self { - context: ManuallyDrop::new(Replaceable::new(context)), + context: ManuallyDrop::new(context), visual_bell: VisualBell::from(&config.bell), renderer: ManuallyDrop::new(renderer), renderer_preference: config.debug.renderer, @@ -544,22 +544,17 @@ impl Display { #[inline] pub fn gl_context(&self) -> &PossiblyCurrentContext { - self.context.get() + &self.context } pub fn make_not_current(&mut self) { - if self.context.get().is_current() { - self.context.replace_with(|context| { - context - .make_not_current() - .expect("failed to disable context") - .treat_as_possibly_current() - }); + if self.context.is_current() { + self.context.make_not_current_in_place().expect("failed to disable context"); } } pub fn make_current(&mut self) { - let is_current = self.context.get().is_current(); + let is_current = self.context.is_current(); // Attempt to make the context current if it's not. let context_loss = if is_current { @@ -592,7 +587,7 @@ impl Display { // Activate new context. let context = context.treat_as_possibly_current(); - self.context = ManuallyDrop::new(Replaceable::new(context)); + self.context = ManuallyDrop::new(context); self.context.make_current(&self.surface).expect("failed to reativate context after reset."); // Recreate renderer. @@ -611,7 +606,7 @@ impl Display { fn swap_buffers(&self) { #[allow(clippy::single_match)] - let res = match (self.surface.deref(), &self.context.get()) { + let res = match (self.surface.deref(), &self.context.deref()) { #[cfg(not(any(target_os = "macos", windows)))] (Surface::Egl(surface), PossiblyCurrentContext::Egl(context)) if matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) @@ -1555,47 +1550,6 @@ pub struct RendererUpdate { clear_font_cache: bool, } -/// Struct for safe in-place replacement. -/// -/// This struct allows easily replacing struct fields that provide `self -> Self` methods in-place, -/// without having to deal with constantly unwrapping the underlying [`Option`]. -struct Replaceable(Option); - -impl Replaceable { - pub fn new(inner: T) -> Self { - Self(Some(inner)) - } - - /// Replace the contents of the container. - pub fn replace_with T>(&mut self, f: F) { - self.0 = self.0.take().map(f); - } - - /// Get immutable access to the wrapped value. - pub fn get(&self) -> &T { - self.0.as_ref().unwrap() - } - - /// Get mutable access to the wrapped value. - pub fn get_mut(&mut self) -> &mut T { - self.0.as_mut().unwrap() - } -} - -impl Deref for Replaceable { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.get() - } -} - -impl DerefMut for Replaceable { - fn deref_mut(&mut self) -> &mut Self::Target { - self.get_mut() - } -} - /// The frame timer state. pub struct FrameTimer { /// Base timestamp used to compute sync points. -- cgit From 05368ea6a7061fa5e88b01d3e2982cbfd202f15a Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Mon, 13 Jan 2025 02:32:42 +0300 Subject: Bump vte to 0.14.1 This fixes a crash with partial utf8 input and also speeds up parsing in some cases. --- Cargo.lock | 15 ++------------- alacritty_terminal/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f294793..2e277d09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2045,26 +2045,15 @@ dependencies = [ [[package]] name = "vte" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5507b53f7756f79bdb968d038a8f8db570d88028aee3c3cdc20427a8fb3482f4" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" dependencies = [ "bitflags 2.6.0", "cursor-icon", "log", "memchr", "serde", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e658bbb246cd98d720db0b7553764f7e841e25d9ac0c9ecfbc09452dc95a8cce" -dependencies = [ - "proc-macro2", - "quote", ] [[package]] diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index a5c8e1ae..73ffbc24 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -24,7 +24,7 @@ parking_lot = "0.12.0" polling = "3.0.0" regex-automata = "0.4.3" unicode-width = "0.1" -vte = { version = "0.14.0", default-features = false, features = ["ansi"] } +vte = { version = "0.14.1", default-features = false, features = ["ansi"] } serde = { version = "1", features = ["derive", "rc"], optional = true } [target.'cfg(unix)'.dependencies] -- cgit From bc3b7a2c1f4137f3879de6317f24171643c925c9 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Tue, 14 Jan 2025 00:03:52 +0300 Subject: Error when failed to create socket with --daemon The daemon without socket is not that useful. --- CHANGELOG.md | 4 ++++ alacritty/src/ipc.rs | 15 ++++++--------- alacritty/src/main.rs | 9 ++++++++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8666916..d4835758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Notable changes to the `alacritty_terminal` crate are documented in its ## 0.16.0-dev +### Changed + +- Error out when socket fails to create with `--daemon` + ## 0.15.0 ### Added diff --git a/alacritty/src/ipc.rs b/alacritty/src/ipc.rs index 3d14c4ce..919035a6 100644 --- a/alacritty/src/ipc.rs +++ b/alacritty/src/ipc.rs @@ -19,7 +19,10 @@ use crate::event::{Event, EventType}; const ALACRITTY_SOCKET_ENV: &str = "ALACRITTY_SOCKET"; /// Create an IPC socket. -pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy) -> Option { +pub fn spawn_ipc_socket( + options: &Options, + event_proxy: EventLoopProxy, +) -> IoResult { // Create the IPC socket and export its path as env. let socket_path = options.socket.clone().unwrap_or_else(|| { @@ -28,13 +31,7 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy) - path }); - let listener = match UnixListener::bind(&socket_path) { - Ok(listener) => listener, - Err(err) => { - warn!("Unable to create socket: {:?}", err); - return None; - }, - }; + let listener = UnixListener::bind(&socket_path)?; env::set_var(ALACRITTY_SOCKET_ENV, socket_path.as_os_str()); if options.daemon { @@ -80,7 +77,7 @@ pub fn spawn_ipc_socket(options: &Options, event_proxy: EventLoopProxy) - } }); - Some(socket_path) + Ok(socket_path) } /// Send a message to the active Alacritty socket. diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 5382e475..9260bfa4 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -183,7 +183,14 @@ fn alacritty(mut options: Options) -> Result<(), Box> { // Create the IPC socket listener. #[cfg(unix)] let socket_path = if config.ipc_socket() { - ipc::spawn_ipc_socket(&options, window_event_loop.create_proxy()) + match ipc::spawn_ipc_socket(&options, window_event_loop.create_proxy()) { + Ok(path) => Some(path), + Err(err) if options.daemon => return Err(err.into()), + Err(err) => { + log::warn!("Unable to create socket: {:?}", err); + None + }, + } } else { None }; -- cgit From c9c41e637ac49f3cd67cf0362c596ae9d947f896 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Tue, 14 Jan 2025 06:41:35 +0000 Subject: Fix OpenGL reset changelog entry --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4835758..59480b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Error out when socket fails to create with `--daemon` +### Fixed + +- Crash when OpenGL context resets + ## 0.15.0 ### Added @@ -39,7 +43,6 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Report of Enter/Tab/Backspace in kitty keyboard's report event types mode - Crash when pressing certain modifier keys on macOS 15+ - Cut off wide characters in preedit string -- Crash when OpenGL context resets ## 0.14.0 -- cgit From 5e78d20c709cb1ab8d44ca7a8702cc26d779227c Mon Sep 17 00:00:00 2001 From: "Andrew Borg (Kashin)" <1192958+aborg-dev@users.noreply.github.com> Date: Thu, 16 Jan 2025 15:04:21 +0000 Subject: 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`. --- alacritty/src/cli.rs | 4 ++-- alacritty/src/config/ui_config.rs | 2 +- alacritty/src/display/window.rs | 10 +++++++--- alacritty/src/event.rs | 18 ++++++++++++++---- alacritty/src/input/mod.rs | 5 ++++- alacritty/src/window_context.rs | 2 +- alacritty_terminal/CHANGELOG.md | 6 +++++- alacritty_terminal/src/event_loop.rs | 13 +++++-------- alacritty_terminal/src/tty/mod.rs | 4 ++-- 9 files changed, 41 insertions(+), 23 deletions(-) diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs index 5010ffc8..feac41bd 100644 --- a/alacritty/src/cli.rs +++ b/alacritty/src/cli.rs @@ -189,7 +189,7 @@ impl TerminalOptions { pty_config.shell = Some(command.into()); } - pty_config.hold |= self.hold; + pty_config.drain_on_exit |= self.hold; } } @@ -198,7 +198,7 @@ impl From for PtyOptions { PtyOptions { working_directory: options.working_directory.take(), shell: options.command().map(Into::into), - hold: options.hold, + drain_on_exit: options.hold, env: HashMap::new(), } } diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index b44bda0d..53310090 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -130,7 +130,7 @@ impl UiConfig { let shell = self.terminal.shell.clone().or_else(|| self.shell.clone()).map(Into::into); let working_directory = 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. diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index fe40fab5..f9fb9272 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -109,6 +109,9 @@ pub struct Window { /// Flag indicating whether redraw was requested. pub requested_redraw: bool, + /// Hold the window when terminal exits. + pub hold: bool, + window: WinitWindow, /// Current window title. @@ -127,7 +130,7 @@ impl Window { event_loop: &ActiveEventLoop, config: &UiConfig, identity: &Identity, - _options: &mut WindowOptions, + options: &mut WindowOptions, #[rustfmt::skip] #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual: Option, @@ -139,7 +142,7 @@ impl Window { #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual, #[cfg(target_os = "macos")] - &_options.window_tabbing_id.take(), + &options.window_tabbing_id.take(), ); if let Some(position) = config.window.position { @@ -148,7 +151,7 @@ impl Window { } #[cfg(not(any(target_os = "macos", windows)))] - if let Some(token) = _options + if let Some(token) = options .activation_token .take() .map(ActivationToken::from_raw) @@ -199,6 +202,7 @@ impl Window { let is_x11 = matches!(window.window_handle().unwrap().as_raw(), RawWindowHandle::Xlib(_)); Ok(Self { + hold: options.terminal_options.hold, requested_redraw: false, title: identity.title, current_mouse_cursor, diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 2ac6279d..888bec4f 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -4,6 +4,7 @@ use crate::ConfigMonitor; use glutin::config::GetGlConfig; use std::borrow::Cow; use std::cmp::min; +use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet, VecDeque}; use std::error::Error; use std::ffi::OsStr; @@ -380,9 +381,14 @@ impl ApplicationHandler for Processor { }, (EventType::Terminal(TerminalEvent::Exit), Some(window_id)) => { // Remove the closed terminal. - let window_context = match self.windows.remove(window_id) { - Some(window_context) => window_context, - None => return, + let window_context = match self.windows.entry(*window_id) { + // Don't exit when terminal exits if user asked to hold the window. + Entry::Occupied(window_context) + if !window_context.get().display.window.hold => + { + window_context.remove() + }, + _ => return, }; // Unschedule pending events. @@ -1793,7 +1799,11 @@ impl input::Processor> { }, WinitEvent::WindowEvent { 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, .. } => { let old_scale_factor = mem::replace(&mut self.ctx.window().scale_factor, scale_factor); diff --git a/alacritty/src/input/mod.rs b/alacritty/src/input/mod.rs index 60a50529..3f85512f 100644 --- a/alacritty/src/input/mod.rs +++ b/alacritty/src/input/mod.rs @@ -324,7 +324,10 @@ impl Execute for Action { #[cfg(not(target_os = "macos"))] Action::Hide => ctx.window().set_visible(false), 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::DecreaseFontSize => ctx.change_font_size(-FONT_SIZE_STEP), Action::ResetFontSize => ctx.reset_font_size(), diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index e3c39382..a0e66cc0 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -212,7 +212,7 @@ impl WindowContext { Arc::clone(&terminal), event_proxy.clone(), pty, - pty_config.hold, + pty_config.drain_on_exit, config.debug.ref_test, )?; diff --git a/alacritty_terminal/CHANGELOG.md b/alacritty_terminal/CHANGELOG.md index 55c21d3f..1b4824fb 100644 --- a/alacritty_terminal/CHANGELOG.md +++ b/alacritty_terminal/CHANGELOG.md @@ -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/). -## 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 diff --git a/alacritty_terminal/src/event_loop.rs b/alacritty_terminal/src/event_loop.rs index 2b78f853..1bef1d4f 100644 --- a/alacritty_terminal/src/event_loop.rs +++ b/alacritty_terminal/src/event_loop.rs @@ -50,7 +50,7 @@ pub struct EventLoop { tx: Sender, terminal: Arc>>, event_proxy: U, - hold: bool, + drain_on_exit: bool, ref_test: bool, } @@ -64,7 +64,7 @@ where terminal: Arc>>, event_proxy: U, pty: T, - hold: bool, + drain_on_exit: bool, ref_test: bool, ) -> io::Result> { let (tx, rx) = mpsc::channel(); @@ -76,7 +76,7 @@ where rx: PeekableReceiver::new(rx), terminal, event_proxy, - hold, + drain_on_exit, ref_test, }) } @@ -261,13 +261,10 @@ where if let Some(code) = code { self.event_proxy.send_event(Event::ChildExit(code)); } - if self.hold { - // With hold enabled, make sure the PTY is drained. + if self.drain_on_exit { 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); break 'event_loop; } diff --git a/alacritty_terminal/src/tty/mod.rs b/alacritty_terminal/src/tty/mod.rs index eed2a76d..208547ba 100644 --- a/alacritty_terminal/src/tty/mod.rs +++ b/alacritty_terminal/src/tty/mod.rs @@ -28,8 +28,8 @@ pub struct Options { /// Shell startup directory. pub working_directory: Option, - /// Remain open after child process exits. - pub hold: bool, + /// Drain the child process output before exiting the terminal. + pub drain_on_exit: bool, /// Extra environment variables. pub env: HashMap, -- cgit From 5b189bca684c046a43be7f1c168c3bc37109fc5b Mon Sep 17 00:00:00 2001 From: Kaylem Brown-Malone Date: Tue, 28 Jan 2025 18:29:22 -0700 Subject: Add backslash to invalid characters for URL regex This adds the `\` character to the list of characters which will terminate matches in Alacritty's default hint for URL recognition. --- CHANGELOG.md | 1 + alacritty/src/config/ui_config.rs | 2 +- extra/man/alacritty.5.scd | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59480b09..4316de2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Changed - Error out when socket fails to create with `--daemon` +- Default URL hints now stop before backslashes ### Fixed diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index 53310090..960bdbbc 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -37,7 +37,7 @@ use crate::config::LOG_TARGET_CONFIG; /// Regex used for the default URL hint. #[rustfmt::skip] const URL_REGEX: &str = "(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)\ - [^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`]+"; + [^\u{0000}-\u{001F}\u{007F}-\u{009F}<>\"\\s{-}\\^⟨⟩`\\\\]+"; #[derive(ConfigDeserialize, Default, Clone, Debug, PartialEq)] pub struct UiConfig { diff --git a/extra/man/alacritty.5.scd b/extra/man/alacritty.5.scd index 18172487..e2f5b252 100644 --- a/extra/man/alacritty.5.scd +++ b/extra/man/alacritty.5.scd @@ -740,7 +740,8 @@ post_processing = _true_++ persist = _false_++ mouse.enabled = _true_++ binding = { key = _"O"_, mods = _"Control|Shift"_ }++ -regex = _"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\\"\\\\s{-}\\\\^⟨⟩`]+"_ +regex = +_"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file:|git://|ssh:|ftp://)[^\\u0000-\\u001F\\u007F-\\u009F<>\\"\\\\s{-}\\\\^⟨⟩`\\\\\\\\]+"_ # KEYBOARD -- cgit From 463a86798401927d463424aff3639dda18a7a27d Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Tue, 4 Feb 2025 18:23:07 +0300 Subject: Bump vte to 0.15.0 --- Cargo.lock | 5 +++-- alacritty_terminal/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e277d09..cbeff686 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2045,10 +2045,11 @@ dependencies = [ [[package]] name = "vte" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" +checksum = "a5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbd" dependencies = [ + "arrayvec", "bitflags 2.6.0", "cursor-icon", "log", diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 73ffbc24..2c3de7eb 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -24,7 +24,7 @@ parking_lot = "0.12.0" polling = "3.0.0" regex-automata = "0.4.3" unicode-width = "0.1" -vte = { version = "0.14.1", default-features = false, features = ["ansi"] } +vte = { version = "0.15.0", default-features = false, features = ["std", "ansi"] } serde = { version = "1", features = ["derive", "rc"], optional = true } [target.'cfg(unix)'.dependencies] -- cgit From 441c9c6eb39a101c9d8d8cd633c61a9c20f7e1a6 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Thu, 6 Feb 2025 20:37:40 +0300 Subject: Bump winit to 0.30.9 Fixes #7916. --- CHANGELOG.md | 1 + Cargo.lock | 4 ++-- alacritty/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4316de2f..51ddf861 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Fixed - Crash when OpenGL context resets +- Modifiers being out of sync for fast/synthetic input on X11 ## 0.15.0 diff --git a/Cargo.lock b/Cargo.lock index cbeff686..78a81e47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2516,9 +2516,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.8" +version = "0.30.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f" +checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0" dependencies = [ "ahash", "android-activity", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index fb961d8f..c778d616 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -41,7 +41,7 @@ tempfile = "3.12.0" toml = "0.8.2" toml_edit = "0.22.21" unicode-width = "0.1" -winit = { version = "0.30.8", default-features = false, features = ["rwh_06", "serde"] } +winit = { version = "0.30.9", default-features = false, features = ["rwh_06", "serde"] } [build-dependencies] gl_generator = "0.14.0" -- cgit From 3c7a323ef5b0cb0631f857a96d7d874008ee515a Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Sat, 8 Feb 2025 03:01:56 -0500 Subject: Dont fail exec() on deleted directories Use the `std::env::set_current_dir` from the `pre_exec` and ignore error, since not changing working directory is a side effect which shouldn't break spawning a program or block window creation. Signed-off-by: Tycho Andersen Co-authored-by: Kirill Chibisov Co-authored-by: Christian Duerr --- CHANGELOG.md | 1 + alacritty/src/daemon.rs | 13 +++++++++---- alacritty/src/event.rs | 7 +++---- alacritty_terminal/src/tty/unix.rs | 11 ++++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ddf861..32934a17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Crash when OpenGL context resets - Modifiers being out of sync for fast/synthetic input on X11 +- Child process creation failing while inside a deleted directory ## 0.15.0 diff --git a/alacritty/src/daemon.rs b/alacritty/src/daemon.rs index c8fb88d1..fa530fa0 100644 --- a/alacritty/src/daemon.rs +++ b/alacritty/src/daemon.rs @@ -9,6 +9,7 @@ use std::process::{Command, Stdio}; #[rustfmt::skip] #[cfg(not(windows))] use { + std::env, std::error::Error, std::os::unix::process::CommandExt, std::os::unix::io::RawFd, @@ -58,18 +59,22 @@ where { let mut command = Command::new(program); command.args(args).stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null()); - if let Ok(cwd) = foreground_process_path(master_fd, shell_pid) { - command.current_dir(cwd); - } + + let working_directory = foreground_process_path(master_fd, shell_pid).ok(); unsafe { command - .pre_exec(|| { + .pre_exec(move || { match libc::fork() { -1 => return Err(io::Error::last_os_error()), 0 => (), _ => libc::_exit(0), } + // Copy foreground process' working directory, ignoring invalid paths. + if let Some(working_directory) = working_directory.as_ref() { + let _ = env::set_current_dir(working_directory); + } + if libc::setsid() == -1 { return Err(io::Error::last_os_error()); } diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 888bec4f..c761f5ae 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -844,9 +844,8 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon #[cfg(not(windows))] fn create_new_window(&mut self, #[cfg(target_os = "macos")] tabbing_id: Option) { let mut options = WindowOptions::default(); - if let Ok(working_directory) = foreground_process_path(self.master_fd, self.shell_pid) { - options.terminal_options.working_directory = Some(working_directory); - } + options.terminal_options.working_directory = + foreground_process_path(self.master_fd, self.shell_pid).ok(); #[cfg(target_os = "macos")] { @@ -875,7 +874,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon match result { Ok(_) => debug!("Launched {} with args {:?}", program, args), - Err(_) => warn!("Unable to launch {} with args {:?}", program, args), + Err(err) => warn!("Unable to launch {program} with args {args:?}: {err}"), } } diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index 6565f20b..e3db51fb 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -231,6 +231,7 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd builder.env_remove("XDG_ACTIVATION_TOKEN"); builder.env_remove("DESKTOP_STARTUP_ID"); + let working_directory = config.working_directory.clone(); unsafe { builder.pre_exec(move || { // Create a new process group. @@ -239,6 +240,11 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd return Err(Error::new(ErrorKind::Other, "Failed to set session id")); } + // Set working directory, ignoring invalid paths. + if let Some(working_directory) = working_directory.as_ref() { + let _ = env::set_current_dir(working_directory); + } + set_controlling_terminal(slave_fd); // No longer need slave/master fds. @@ -256,11 +262,6 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd }); } - // Handle set working directory option. - if let Some(dir) = &config.working_directory { - builder.current_dir(dir); - } - // Prepare signal handling before spawning child. let (signals, sig_id) = { let (sender, recv) = UnixStream::pair()?; -- cgit From 6fefa78eafa43f13998439cb9eaf15bc0441f004 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sun, 9 Feb 2025 08:39:01 +0300 Subject: Don't report unshifted key when Shift was not pressed --- CHANGELOG.md | 1 + alacritty/src/input/keyboard.rs | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32934a17..ba177deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its - Crash when OpenGL context resets - Modifiers being out of sync for fast/synthetic input on X11 - Child process creation failing while inside a deleted directory +- Shifted key reported without a shift when using kitty keyboard protocol ## 0.15.0 diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs index af9bfbb2..417f599b 100644 --- a/alacritty/src/input/keyboard.rs +++ b/alacritty/src/input/keyboard.rs @@ -342,18 +342,21 @@ impl SequenceBuilder { }; if character.chars().count() == 1 { - let character = character.chars().next().unwrap(); - let base_character = character.to_lowercase().next().unwrap(); + let shift = self.modifiers.contains(SequenceModifiers::SHIFT); - let alternate_key_code = u32::from(character); - let mut unicode_key_code = u32::from(base_character); + let ch = character.chars().next().unwrap(); + let unshifted_ch = if shift { ch.to_lowercase().next().unwrap() } else { ch }; + + let alternate_key_code = u32::from(ch); + let mut unicode_key_code = u32::from(unshifted_ch); // Try to get the base for keys which change based on modifier, like `1` for `!`. - match key.key_without_modifiers().as_ref() { - Key::Character(unmodded) if alternate_key_code == unicode_key_code => { - unicode_key_code = u32::from(unmodded.chars().next().unwrap_or(base_character)); - }, - _ => (), + // + // However it should only be performed when `SHIFT` is pressed. + if shift && alternate_key_code == unicode_key_code { + if let Key::Character(unmodded) = key.key_without_modifiers().as_ref() { + unicode_key_code = u32::from(unmodded.chars().next().unwrap_or(unshifted_ch)); + } } // NOTE: Base layouts are ignored, since winit doesn't expose this information -- cgit From be911fead8b568797862ebfd41bbad32b46d42bf Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Mon, 17 Feb 2025 14:27:54 +0000 Subject: Add latest release to changelog This is only an update to the development version and does not represent a stable release. --- CHANGELOG.md | 7 ++++++- Cargo.lock | 2 +- alacritty/Cargo.toml | 2 +- alacritty_terminal/CHANGELOG.md | 6 ++++-- alacritty_terminal/Cargo.toml | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba177deb..49984568 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ Notable changes to the `alacritty_terminal` crate are documented in its ## 0.16.0-dev +### Fixed + +- Crash when OpenGL context resets + +## 0.15.1 + ### Changed - Error out when socket fails to create with `--daemon` @@ -17,7 +23,6 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Fixed -- Crash when OpenGL context resets - Modifiers being out of sync for fast/synthetic input on X11 - Child process creation failing while inside a deleted directory - Shifted key reported without a shift when using kitty keyboard protocol diff --git a/Cargo.lock b/Cargo.lock index 78a81e47..ad701e17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,7 +93,7 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.25.0-dev" +version = "0.25.1-dev" dependencies = [ "base64", "bitflags 2.6.0", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index c778d616..0d118229 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -12,7 +12,7 @@ rust-version = "1.74.0" [dependencies.alacritty_terminal] path = "../alacritty_terminal" -version = "0.25.0-dev" +version = "0.25.1-dev" [dependencies.alacritty_config_derive] path = "../alacritty_config_derive" diff --git a/alacritty_terminal/CHANGELOG.md b/alacritty_terminal/CHANGELOG.md index 1b4824fb..90f300f7 100644 --- a/alacritty_terminal/CHANGELOG.md +++ b/alacritty_terminal/CHANGELOG.md @@ -8,11 +8,13 @@ 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/). -## 0.25.0-dev +## 0.25.1-dev + +## 0.25.0 ### Changed -- Replaced `Options::hold` with `Options::drain_on_exit` that drains, but doesn't hold, since holding can be done outside of alacritty_terminal +- Replaced `Options::hold` with `Options::drain_on_exit` ## 0.24.2 diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index 2c3de7eb..47a39fa7 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alacritty_terminal" -version = "0.25.0-dev" +version = "0.25.1-dev" authors = ["Christian Duerr ", "Joe Wilm "] license = "Apache-2.0" description = "Library for writing terminal emulators" -- cgit From 03c2907b44b4189aac5fdeaea331f5aab5c7072e Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 19 Feb 2025 18:12:29 -0800 Subject: Hide macOS login message with ~/.hushlogin present On macOS every shell is a login shell, which will always print information about the last login when the terminal is started. The macOS standard for disabling this is to place a `.hushlogin` file in the user's home directory, but this did not work with Alacritty since `login` only looks for this file in the current directory. To ensure the login message is properly suppressed, Alacritty's default shell will now check for the presence of the `.hushlogin` file in the user's home directory and append `-q` to the `login` arguments if it is present, which will behave as if a `.hushlogin` file was found by `login`. Co-authored-by: Thomas Co-authored-by: Anthony --- CHANGELOG.md | 4 ++++ alacritty_terminal/CHANGELOG.md | 4 ++++ alacritty_terminal/src/tty/unix.rs | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49984568..cf13eb7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Notable changes to the `alacritty_terminal` crate are documented in its ## 0.16.0-dev +### Changed + +- Hide login message if `~/.hushlogin` is present + ### Fixed - Crash when OpenGL context resets diff --git a/alacritty_terminal/CHANGELOG.md b/alacritty_terminal/CHANGELOG.md index 90f300f7..9b2f9ebf 100644 --- a/alacritty_terminal/CHANGELOG.md +++ b/alacritty_terminal/CHANGELOG.md @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 0.25.1-dev +### Changed + +- Pass `-q` to `login` on macOS if `~/.hushlogin` is present + ## 0.25.0 ### Changed diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index e3db51fb..884cb5c1 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -8,6 +8,8 @@ use std::os::fd::OwnedFd; use std::os::unix::io::AsRawFd; use std::os::unix::net::UnixStream; use std::os::unix::process::CommandExt; +#[cfg(target_os = "macos")] +use std::path::Path; use std::process::{Child, Command}; use std::sync::Arc; use std::{env, ptr}; @@ -158,12 +160,12 @@ impl ShellUser { } #[cfg(not(target_os = "macos"))] -fn default_shell_command(shell: &str, _user: &str) -> Command { +fn default_shell_command(shell: &str, _user: &str, _home: &str) -> Command { Command::new(shell) } #[cfg(target_os = "macos")] -fn default_shell_command(shell: &str, user: &str) -> Command { +fn default_shell_command(shell: &str, user: &str, home: &str) -> Command { let shell_name = shell.rsplit('/').next().unwrap(); // On macOS, use the `login` command so the shell will appear as a tty session. @@ -173,12 +175,20 @@ fn default_shell_command(shell: &str, user: &str) -> Command { // `login` normally does this itself, but `-l` disables this. let exec = format!("exec -a -{} {}", shell_name, shell); + // Since we use -l, `login` will not change directory to the user's home. However, + // `login` only checks the current working directory for a .hushlogin file, causing + // it to miss any in the user's home directory. We can fix this by doing the check + // ourselves and passing `-q` + let has_home_hushlogin = Path::new(home).join(".hushlogin").exists(); + // -f: Bypasses authentication for the already-logged-in user. // -l: Skips changing directory to $HOME and prepending '-' to argv[0]. // -p: Preserves the environment. + // -q: Act as if `.hushlogin` exists. // // XXX: we use zsh here over sh due to `exec -a`. - login_command.args(["-flp", user, "/bin/zsh", "-fc", &exec]); + let flags = if has_home_hushlogin { "-qflp" } else { "-flp" }; + login_command.args([flags, user, "/bin/zsh", "-fc", &exec]); login_command } @@ -208,7 +218,7 @@ pub fn from_fd(config: &Options, window_id: u64, master: OwnedFd, slave: OwnedFd cmd.args(shell.args.as_slice()); cmd } else { - default_shell_command(&user.shell, &user.user) + default_shell_command(&user.shell, &user.user, &user.home) }; // Setup child stdin/stdout/stderr as slave fd of PTY. -- cgit