From 2a676dfad837d1784ed0911d314bc263804ef4ef Mon Sep 17 00:00:00 2001 From: Chris Copeland Date: Fri, 15 Jul 2022 14:56:26 -0700 Subject: [PATCH] Fix thin strokes on macOS Remove the `font.use_thin_strokes` config, which only did anything on macOS and only prior to Big Sur. Instead, we will enable or disable "font smoothing" on macOS based on the `AppleFontSmoothing` user default. These changes let users get the "thin strokes" behavior by setting `AppleFontSmoothing` to 0 with: ```sh $ defaults write -g AppleFontSmoothing -int 0 ``` (Or replace `-g` with `org.alacritty` to apply this setting only to Alacritty.app, rather than the whole system.) Add a `removed` config attribute to show helpful warnings to users who are using config options that don't do anything anymore, and apply this attribute to `font.use_thin_strokes`. Bump `crossfont` to 0.5.0 to pick up the new font smoothing behavior. This release also includes a fix for a crash when trying to load a disabled font. Fixes #4616. Fixes #6108. --- CHANGELOG.md | 10 +++++++++- Cargo.lock | 6 ++++-- alacritty.yml | 6 ------ alacritty/Cargo.toml | 2 +- alacritty/src/config/font.rs | 3 ++- alacritty/src/display/mod.rs | 6 +----- alacritty/src/renderer/text/builtin_font.rs | 11 ++++++++++- alacritty/src/window_context.rs | 4 ---- alacritty_config_derive/src/de_struct.rs | 8 ++++---- alacritty_config_derive/tests/config.rs | 10 ++++++++-- 10 files changed, 39 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6b31e05..4b585df9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,10 +34,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `SpawnNewInstance` no longer inherits initial `--command` - Blinking cursor will timeout after `5` seconds by default - Deprecated `colors.search.bar`, use `colors.footer_bar` instead +- On macOS, Alacritty now reads `AppleFontSmoothing` from user defaults to control font smoothing ### Fixed -- Creating the IPC socket failing if WAYLAND_DISPLAY contains an absolute path +- Creating the IPC socket failing if `WAYLAND_DISPLAY` contains an absolute path - Crash when resetting the terminal while in vi mode - `font.glyph_offset` not live reloading - Failure when running on 10-bit color system @@ -50,6 +51,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Window flickering on resize on Wayland - Unnecessary config reload when using `/dev/null` as a config file - Windows `Open Alacritty Here` on root of drive displaying error +- On macOS, `font.use_thin_strokes` did not work since Big Sur +- On macOS, trying to load a disabled font would crash + +### Removed + +- `font.use_thin_strokes` config field; to use thin strokes on macOS, set + `AppleFontSmoothing` to 0 with `$ defaults write -g AppleFontSmoothing -int 0` ## 0.10.1 diff --git a/Cargo.lock b/Cargo.lock index 1f579348..a25d5129 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,9 +383,9 @@ dependencies = [ [[package]] name = "crossfont" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1299695a4c6417b7e4a6957bd963478406e148b7b0351e2f2ce31296b0518251" +checksum = "f66b1c1979c4362323f03ab6bf7fb522902bfc418e0c37319ab347f9561d980f" dependencies = [ "cocoa", "core-foundation 0.9.3", @@ -397,6 +397,8 @@ dependencies = [ "freetype-rs", "libc", "log", + "objc", + "once_cell", "pkg-config", "servo-fontconfig", "winapi 0.3.9", diff --git a/alacritty.yml b/alacritty.yml index fcd46dfb..d8f05d3f 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -172,12 +172,6 @@ # x: 0 # y: 0 - # Thin stroke font rendering (macOS only) - # - # Thin strokes are suitable for retina displays, but for non-retina screens - # it is recommended to set `use_thin_strokes` to `false`. - #use_thin_strokes: true - # Use built-in font for box drawing characters. # # If `true`, Alacritty will use a custom built-in font for box drawing diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 85b23c0a..9b610d86 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -28,7 +28,7 @@ serde_json = "1" glutin = { version = "0.28.0", default-features = false, features = ["serde"] } notify = "4" parking_lot = "0.11.0" -crossfont = { version = "0.3.1", features = ["force_system_fontconfig"] } +crossfont = { version = "0.5.0", features = ["force_system_fontconfig"] } copypasta = { version = "0.8.0", default-features = false } libc = "0.2" unicode-width = "0.1" diff --git a/alacritty/src/config/font.rs b/alacritty/src/config/font.rs index cdd84ff9..d3431171 100644 --- a/alacritty/src/config/font.rs +++ b/alacritty/src/config/font.rs @@ -22,6 +22,7 @@ pub struct Font { /// Glyph offset within character cell. pub glyph_offset: Delta, + #[config(removed = "set the AppleFontSmoothing user default instead")] pub use_thin_strokes: bool, /// Normal font face. @@ -79,8 +80,8 @@ impl Default for Font { fn default() -> Font { Self { builtin_box_drawing: true, - use_thin_strokes: Default::default(), glyph_offset: Default::default(), + use_thin_strokes: Default::default(), bold_italic: Default::default(), italic: Default::default(), offset: Default::default(), diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index f1f51ec7..79e57307 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -411,7 +411,7 @@ impl Display { // Guess the target window dimensions. debug!("Loading \"{}\" font", &config.font.normal().family); let font = &config.font; - let rasterizer = Rasterizer::new(estimated_scale_factor as f32, font.use_thin_strokes)?; + let rasterizer = Rasterizer::new(estimated_scale_factor as f32)?; let mut glyph_cache = GlyphCache::new(rasterizer, font)?; let metrics = glyph_cache.font_metrics(); let (cell_width, cell_height) = compute_cell_size(config, &metrics); @@ -488,10 +488,6 @@ impl Display { let background_color = config.colors.primary.background; renderer.clear(background_color, config.window_opacity()); - // Set subpixel anti-aliasing. - #[cfg(target_os = "macos")] - crossfont::set_font_smoothing(config.font.use_thin_strokes); - // Disable shadows for transparent windows on macOS. #[cfg(target_os = "macos")] window.set_has_shadow(config.window_opacity() >= 1.0); diff --git a/alacritty/src/renderer/text/builtin_font.rs b/alacritty/src/renderer/text/builtin_font.rs index 36d1ccdc..a4bf65e3 100644 --- a/alacritty/src/renderer/text/builtin_font.rs +++ b/alacritty/src/renderer/text/builtin_font.rs @@ -90,6 +90,7 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta) -> Raster left: 0, height: height as i32, width: width as i32, + advance: (0, 0), buffer, }; }, @@ -479,7 +480,15 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta) -> Raster let top = height as i32 + metrics.descent as i32; let buffer = BitmapBuffer::Rgb(canvas.into_raw()); - RasterizedGlyph { character, top, left: 0, height: height as i32, width: width as i32, buffer } + RasterizedGlyph { + character, + top, + left: 0, + height: height as i32, + width: width as i32, + advance: (0, 0), + buffer, + } } #[repr(packed)] diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index a45b9404..7fe33fd0 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -210,10 +210,6 @@ impl WindowContext { self.display.window.set_title(config.window.identity.title.clone()); } - // Set subpixel anti-aliasing. - #[cfg(target_os = "macos")] - crossfont::set_font_smoothing(config.font.use_thin_strokes); - // Disable shadows for transparent windows on macOS. #[cfg(target_os = "macos")] self.display.window.set_has_shadow(config.window_opacity() >= 1.0); diff --git a/alacritty_config_derive/src/de_struct.rs b/alacritty_config_derive/src/de_struct.rs index ceb32fd9..cf7ea141 100644 --- a/alacritty_config_derive/src/de_struct.rs +++ b/alacritty_config_derive/src/de_struct.rs @@ -135,14 +135,14 @@ fn field_deserializer(field_streams: &mut FieldStreams, field: &Field) -> Result config.#ident = serde::Deserialize::deserialize(unused).unwrap_or_default(); }); }, - "deprecated" => { - // Construct deprecation message and append optional attribute override. - let mut message = format!("Config warning: {} is deprecated", literal); + "deprecated" | "removed" => { + // Construct deprecation/removal message with optional attribute override. + let mut message = format!("Config warning: {} has been {}", literal, parsed.ident); if let Some(warning) = parsed.param { message = format!("{}; {}", message, warning.value()); } - // Append stream to log deprecation warning. + // Append stream to log deprecation/removal warning. match_assignment_stream.extend(quote! { log::warn!(target: #LOG_TARGET, #message); }); diff --git a/alacritty_config_derive/tests/config.rs b/alacritty_config_derive/tests/config.rs index 58ad8bd4..2cdae613 100644 --- a/alacritty_config_derive/tests/config.rs +++ b/alacritty_config_derive/tests/config.rs @@ -35,6 +35,8 @@ struct Test { enom_big: TestEnum, #[config(deprecated)] enom_error: TestEnum, + #[config(removed = "it's gone")] + gone: bool, } impl Default for Test { @@ -48,6 +50,7 @@ impl Default for Test { enom_small: TestEnum::default(), enom_big: TestEnum::default(), enom_error: TestEnum::default(), + gone: false, } } } @@ -90,6 +93,7 @@ fn config_deserialize() { enom_small: "one" enom_big: "THREE" enom_error: "HugaBuga" + gone: false "#, ) .unwrap(); @@ -101,6 +105,7 @@ fn config_deserialize() { assert_eq!(test.enom_small, TestEnum::One); assert_eq!(test.enom_big, TestEnum::Three); assert_eq!(test.enom_error, Test::default().enom_error); + assert_eq!(test.gone, false); assert_eq!(test.nesting.field1, Test::default().nesting.field1); assert_eq!(test.nesting.field2, None); assert_eq!(test.nesting.field3, Test::default().nesting.field3); @@ -116,8 +121,9 @@ fn config_deserialize() { ]); let warn_logs = logger.warn_logs.lock().unwrap(); assert_eq!(warn_logs.as_slice(), [ - "Config warning: field1 is deprecated; use field2 instead", - "Config warning: enom_error is deprecated", + "Config warning: field1 has been deprecated; use field2 instead", + "Config warning: enom_error has been deprecated", + "Config warning: gone has been removed; it's gone", ]); }