From b4954196ed7d491d5ad9fb1230a1cf928427eb6b Mon Sep 17 00:00:00 2001 From: Mohammad AlSaleh Date: Fri, 16 Aug 2024 14:30:58 +0300 Subject: [PATCH] Only update default colors when needed, and `update()` when it's done With commit 7c5d5440e5a560238de3666d7ead6970477a7dd6, it became possible that `update_colors()` may run without being immediately followed by an `update()`. But `update_colors()` creates a new `metadata_set`, which means `attr_list` may now contain out-of-date metadata indices to the old cleared `metadata_set`. With this commit: * A `metadata_set` is only cleared and recreated in `update_colors()` if default colors have actually changed. * A `bool` is returned and set it to `true` from `update_colors()` if a color update happened. * An `update()` is run if we get a `true` from `update_colors()`. * And finally, `update_colors()` is renamed to `update_default_colors()`. Fixes #291. Signed-off-by: Mohammad AlSaleh --- src/terminal.rs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/terminal.rs b/src/terminal.rs index 07434b3..2ce5dc2 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -580,31 +580,39 @@ impl Terminal { } } - //TODO: this is done on every set_config because the changed boolean above does not capture + // NOTE: this is done on every set_config because the changed boolean above does not capture // WINDOW_BG changes - self.update_colors(config); + let default_colors_updated = self.update_default_colors(config); if update_cell_size { self.update_cell_size(); - } else if update { + } else if update || default_colors_updated { self.update(); } } - pub fn update_colors(&mut self, config: &AppConfig) { - self.metadata_set.clear(); + pub fn update_default_colors(&mut self, config: &AppConfig) -> bool { let default_bg = convert_color(&self.colors, Color::Named(NamedColor::Background)); let default_fg = convert_color(&self.colors, Color::Named(NamedColor::Foreground)); - let default_metadata = Metadata::new(default_bg, default_fg); - let (default_metadata_idx, _) = self.metadata_set.insert_full(default_metadata); + let new_default_metadata = Metadata::new(default_bg, default_fg); + let curr_metada_idx = self.default_attrs().metadata; - self.default_attrs = Attrs::new() - .family(Family::Monospace) - .weight(Weight(config.font_weight)) - .stretch(config.typed_font_stretch()) - .color(default_fg) - .metadata(default_metadata_idx); + let updated = new_default_metadata != self.metadata_set[curr_metada_idx]; + + if updated { + self.metadata_set.clear(); + let (default_metadata_idx, _) = self.metadata_set.insert_full(new_default_metadata); + + self.default_attrs = Attrs::new() + .family(Family::Monospace) + .weight(Weight(config.font_weight)) + .stretch(config.typed_font_stretch()) + .color(default_fg) + .metadata(default_metadata_idx); + } + + updated } pub fn update_cell_size(&mut self) {