1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-20 11:17:15 +03:00

colors now override color_scheme

The prior mutually exclusive behavior kept surprising people so let's
just flip this around.

This is potentially a "breaking" change for folks, but I think it is
worth it.
This commit is contained in:
Wez Furlong 2022-08-20 11:48:22 -07:00
parent 8b2ef50ca7
commit 8b3a52ba9a
6 changed files with 208 additions and 85 deletions

View File

@ -171,6 +171,56 @@ pub struct Palette {
} }
impl_lua_conversion_dynamic!(Palette); impl_lua_conversion_dynamic!(Palette);
impl Palette {
pub fn overlay_with(&self, other: &Self) -> Self {
macro_rules! overlay {
($name:ident) => {
if let Some(c) = &other.$name {
Some(c.clone())
} else {
self.$name.clone()
}
};
}
Self {
foreground: overlay!(foreground),
background: overlay!(background),
cursor_fg: overlay!(cursor_fg),
cursor_bg: overlay!(cursor_bg),
cursor_border: overlay!(cursor_border),
selection_fg: overlay!(selection_fg),
selection_bg: overlay!(selection_bg),
ansi: overlay!(ansi),
brights: overlay!(brights),
tab_bar: match (&self.tab_bar, &other.tab_bar) {
(Some(a), Some(b)) => Some(a.overlay_with(&b)),
(None, Some(b)) => Some(b.clone()),
(Some(a), None) => Some(a.clone()),
(None, None) => None,
},
indexed: {
let mut map = self.indexed.clone();
for (k, v) in &other.indexed {
map.insert(k.clone(), v.clone());
}
map
},
scrollbar_thumb: overlay!(scrollbar_thumb),
split: overlay!(split),
visual_bell: overlay!(visual_bell),
compose_cursor: overlay!(compose_cursor),
copy_mode_active_highlight_fg: overlay!(copy_mode_active_highlight_fg),
copy_mode_active_highlight_bg: overlay!(copy_mode_active_highlight_bg),
copy_mode_inactive_highlight_fg: overlay!(copy_mode_inactive_highlight_fg),
copy_mode_inactive_highlight_bg: overlay!(copy_mode_inactive_highlight_bg),
quick_select_label_fg: overlay!(quick_select_label_fg),
quick_select_label_bg: overlay!(quick_select_label_bg),
quick_select_match_fg: overlay!(quick_select_match_fg),
quick_select_match_bg: overlay!(quick_select_match_bg),
}
}
}
impl From<ColorPalette> for Palette { impl From<ColorPalette> for Palette {
fn from(cp: ColorPalette) -> Palette { fn from(cp: ColorPalette) -> Palette {
let mut p = Palette::default(); let mut p = Palette::default();
@ -291,37 +341,101 @@ impl TabBarColor {
/// Specifies the colors to use for the tab bar portion of the UI. /// Specifies the colors to use for the tab bar portion of the UI.
/// These are not part of the terminal model and cannot be updated /// These are not part of the terminal model and cannot be updated
/// in the same way that the dynamic color schemes are. /// in the same way that the dynamic color schemes are.
#[derive(Debug, Clone, PartialEq, FromDynamic, ToDynamic)] #[derive(Default, Debug, Clone, PartialEq, FromDynamic, ToDynamic)]
pub struct TabBarColors { pub struct TabBarColors {
/// The background color for the tab bar /// The background color for the tab bar
#[dynamic(default = "default_background")] #[dynamic(default)]
pub background: RgbaColor, pub background: Option<RgbaColor>,
/// Styling for the active tab /// Styling for the active tab
#[dynamic(default = "default_active_tab")] #[dynamic(default)]
pub active_tab: TabBarColor, pub active_tab: Option<TabBarColor>,
/// Styling for other inactive tabs /// Styling for other inactive tabs
#[dynamic(default = "default_inactive_tab")] #[dynamic(default)]
pub inactive_tab: TabBarColor, pub inactive_tab: Option<TabBarColor>,
/// Styling for an inactive tab with a mouse hovering /// Styling for an inactive tab with a mouse hovering
#[dynamic(default = "default_inactive_tab_hover")] #[dynamic(default)]
pub inactive_tab_hover: TabBarColor, pub inactive_tab_hover: Option<TabBarColor>,
/// Styling for the new tab button /// Styling for the new tab button
#[dynamic(default = "default_inactive_tab")] #[dynamic(default)]
pub new_tab: TabBarColor, pub new_tab: Option<TabBarColor>,
/// Styling for the new tab button with a mouse hovering /// Styling for the new tab button with a mouse hovering
#[dynamic(default = "default_inactive_tab_hover")] #[dynamic(default)]
pub new_tab_hover: TabBarColor, pub new_tab_hover: Option<TabBarColor>,
#[dynamic(default = "default_inactive_tab_edge")] #[dynamic(default)]
pub inactive_tab_edge: RgbaColor, pub inactive_tab_edge: Option<RgbaColor>,
#[dynamic(default = "default_inactive_tab_edge_hover")] #[dynamic(default)]
pub inactive_tab_edge_hover: RgbaColor, pub inactive_tab_edge_hover: Option<RgbaColor>,
}
impl TabBarColors {
pub fn background(&self) -> RgbaColor {
self.background.unwrap_or_else(default_background)
}
pub fn active_tab(&self) -> TabBarColor {
self.active_tab.clone().unwrap_or_else(default_active_tab)
}
pub fn inactive_tab(&self) -> TabBarColor {
self.inactive_tab
.clone()
.unwrap_or_else(default_inactive_tab)
}
pub fn inactive_tab_hover(&self) -> TabBarColor {
self.inactive_tab_hover
.clone()
.unwrap_or_else(default_inactive_tab_hover)
}
pub fn new_tab(&self) -> TabBarColor {
self.new_tab.clone().unwrap_or_else(default_inactive_tab)
}
pub fn new_tab_hover(&self) -> TabBarColor {
self.new_tab_hover
.clone()
.unwrap_or_else(default_inactive_tab_hover)
}
pub fn inactive_tab_edge(&self) -> RgbaColor {
self.inactive_tab_edge
.unwrap_or_else(default_inactive_tab_edge)
}
pub fn inactive_tab_edge_hover(&self) -> RgbaColor {
self.inactive_tab_edge_hover
.unwrap_or_else(default_inactive_tab_edge_hover)
}
pub fn overlay_with(&self, other: &Self) -> Self {
macro_rules! overlay {
($name:ident) => {
if let Some(c) = &other.$name {
Some(c.clone())
} else {
self.$name.clone()
}
};
}
Self {
active_tab: overlay!(active_tab),
background: overlay!(background),
inactive_tab: overlay!(inactive_tab),
inactive_tab_hover: overlay!(inactive_tab_hover),
inactive_tab_edge: overlay!(inactive_tab_edge),
inactive_tab_edge_hover: overlay!(inactive_tab_edge_hover),
new_tab: overlay!(new_tab),
new_tab_hover: overlay!(new_tab_hover),
}
}
} }
fn default_background() -> RgbaColor { fn default_background() -> RgbaColor {
@ -359,21 +473,6 @@ fn default_active_tab() -> TabBarColor {
} }
} }
impl Default for TabBarColors {
fn default() -> Self {
Self {
background: default_background(),
inactive_tab: default_inactive_tab(),
inactive_tab_hover: default_inactive_tab_hover(),
active_tab: default_active_tab(),
new_tab: default_inactive_tab(),
new_tab_hover: default_inactive_tab_hover(),
inactive_tab_edge: default_inactive_tab_edge(),
inactive_tab_edge_hover: default_inactive_tab_edge_hover(),
}
}
}
#[derive(Debug, Clone, FromDynamic, ToDynamic)] #[derive(Debug, Clone, FromDynamic, ToDynamic)]
pub struct TabBarStyle { pub struct TabBarStyle {
#[dynamic(default = "default_new_tab")] #[dynamic(default = "default_new_tab")]

View File

@ -993,8 +993,6 @@ impl Config {
cfg.load_color_schemes(&cfg.compute_color_scheme_dirs()) cfg.load_color_schemes(&cfg.compute_color_scheme_dirs())
.ok(); .ok();
cfg.resolved_palette = cfg.colors.as_ref().cloned().unwrap_or(Default::default());
// Color scheme overrides any manually specified palette
if let Some(scheme) = cfg.color_scheme.as_ref() { if let Some(scheme) = cfg.color_scheme.as_ref() {
match cfg.resolve_color_scheme() { match cfg.resolve_color_scheme() {
None => { None => {
@ -1010,6 +1008,10 @@ impl Config {
} }
} }
if let Some(colors) = &cfg.colors {
cfg.resolved_palette = cfg.resolved_palette.overlay_with(colors);
}
if let Some(bg) = BackgroundLayer::with_legacy(self) { if let Some(bg) = BackgroundLayer::with_legacy(self) {
cfg.background.insert(0, bg); cfg.background.insert(0, bg);
} }

View File

@ -17,6 +17,7 @@ As features stabilize some brief notes about them will accumulate here.
#### Changed #### Changed
* `colors` now override colors from your selected `color_scheme`. Previously, `color_scheme` was mutually exclusive with `colors` and always took precedence. The new behavior is more in line with what most people expect.
* [ActivatePaneDirection](config/lua/keyassignment/ActivatePaneDirection.md) now uses recency to resolve ambiguous moves [#2374](https://github.com/wez/wezterm/issues/2374) * [ActivatePaneDirection](config/lua/keyassignment/ActivatePaneDirection.md) now uses recency to resolve ambiguous moves [#2374](https://github.com/wez/wezterm/issues/2374)
* [update-status](config/lua/window-events/update-status.md) is a more general event for updating left or right status. `update-right-status` is considered to be deprecated in favor of `update-status`. * [update-status](config/lua/window-events/update-status.md) is a more general event for updating left or right status. `update-right-status` is considered to be deprecated in favor of `update-status`.
* Cache XDG Portal Appearance values. Thanks to [@vimposter](https://github.com/vimpostor)! [#2402](https://github.com/wez/wezterm/pull/2402) * Cache XDG Portal Appearance values. Thanks to [@vimposter](https://github.com/vimpostor)! [#2402](https://github.com/wez/wezterm/pull/2402)

View File

@ -17,13 +17,21 @@ return {
You can find a list of available color schemes and screenshots You can find a list of available color schemes and screenshots
in [The Color Schemes Section](../colorschemes/index.md). in [The Color Schemes Section](../colorschemes/index.md).
The `color_scheme` option takes precedence over the `colors` section below. ### Precedence of `colors` vs `color_schemes`
The `color_scheme` option takes precedence over the `colors` section below,
and is mutually exclusive with it. If you want to merge/override colors
you need to use [wezterm.color.get_builtin_color_schemes()](../lua/wezterm.color/get_builtin_color_schemes.md) and explicitly merge them.
*Since: nightly builds only*
The behavior has been changed so that the `color_scheme` you have selected, if
any, is used to define the colors, and then any colors you define in the
`colors` section will override those colors.
### Defining your own colors ### Defining your own colors
Rather than using a color scheme, you can specify the color palette using the You can specify the color palette using the `colors` configuration section.
`colors` configuration section. Note that `color_scheme` takes precedence
over this section.
You can configure colors with a section like this. In addition to specifying You can configure colors with a section like this. In addition to specifying
[SVG/CSS3 color names](https://docs.rs/palette/0.4.1/palette/named/index.html#constants), [SVG/CSS3 color names](https://docs.rs/palette/0.4.1/palette/named/index.html#constants),

View File

@ -194,11 +194,11 @@ impl TabBarState {
) -> Self { ) -> Self {
let colors = colors.cloned().unwrap_or_else(TabBarColors::default); let colors = colors.cloned().unwrap_or_else(TabBarColors::default);
let active_cell_attrs = colors.active_tab.as_cell_attributes(); let active_cell_attrs = colors.active_tab().as_cell_attributes();
let inactive_hover_attrs = colors.inactive_tab_hover.as_cell_attributes(); let inactive_hover_attrs = colors.inactive_tab_hover().as_cell_attributes();
let inactive_cell_attrs = colors.inactive_tab.as_cell_attributes(); let inactive_cell_attrs = colors.inactive_tab().as_cell_attributes();
let new_tab_hover_attrs = colors.new_tab_hover.as_cell_attributes(); let new_tab_hover_attrs = colors.new_tab_hover().as_cell_attributes();
let new_tab_attrs = colors.new_tab.as_cell_attributes(); let new_tab_attrs = colors.new_tab().as_cell_attributes();
let new_tab = parse_status_text( let new_tab = parse_status_text(
&config.tab_bar_style.new_tab, &config.tab_bar_style.new_tab,
@ -262,7 +262,7 @@ impl TabBarState {
let black_cell = Cell::blank_with_attrs( let black_cell = Cell::blank_with_attrs(
CellAttributes::default() CellAttributes::default()
.set_background(ColorSpec::TrueColor(*colors.background)) .set_background(ColorSpec::TrueColor(*colors.background()))
.clone(), .clone(),
); );

View File

@ -525,6 +525,10 @@ impl super::TermWindow {
col => Some(palette.resolve_fg(col)), col => Some(palette.resolve_fg(col)),
}); });
let new_tab = colors.new_tab();
let new_tab_hover = colors.new_tab_hover();
let active_tab = colors.active_tab();
match item.item { match item.item {
TabBarItem::RightStatus | TabBarItem::LeftStatus | TabBarItem::None => element TabBarItem::RightStatus | TabBarItem::LeftStatus | TabBarItem::None => element
.item_type(UIItemType::TabBar(TabBarItem::None)) .item_type(UIItemType::TabBar(TabBarItem::None))
@ -571,13 +575,13 @@ impl super::TermWindow {
.border(BoxDimension::new(Dimension::Pixels(1.))) .border(BoxDimension::new(Dimension::Pixels(1.)))
.colors(ElementColors { .colors(ElementColors {
border: BorderColor::default(), border: BorderColor::default(),
bg: colors.new_tab.bg_color.to_linear().into(), bg: new_tab.bg_color.to_linear().into(),
text: colors.new_tab.fg_color.to_linear().into(), text: new_tab.fg_color.to_linear().into(),
}) })
.hover_colors(Some(ElementColors { .hover_colors(Some(ElementColors {
border: BorderColor::default(), border: BorderColor::default(),
bg: colors.new_tab_hover.bg_color.to_linear().into(), bg: new_tab_hover.bg_color.to_linear().into(),
text: colors.new_tab_hover.fg_color.to_linear().into(), text: new_tab_hover.fg_color.to_linear().into(),
})), })),
TabBarItem::Tab { active, .. } if active => element TabBarItem::Tab { active, .. } if active => element
.item_type(UIItemType::TabBar(item.item.clone())) .item_type(UIItemType::TabBar(item.item.clone()))
@ -611,15 +615,15 @@ impl super::TermWindow {
.colors(ElementColors { .colors(ElementColors {
border: BorderColor::new( border: BorderColor::new(
bg_color bg_color
.unwrap_or_else(|| colors.active_tab.bg_color.into()) .unwrap_or_else(|| active_tab.bg_color.into())
.to_linear(), .to_linear(),
), ),
bg: bg_color bg: bg_color
.unwrap_or_else(|| colors.active_tab.bg_color.into()) .unwrap_or_else(|| active_tab.bg_color.into())
.to_linear() .to_linear()
.into(), .into(),
text: fg_color text: fg_color
.unwrap_or_else(|| colors.active_tab.fg_color.into()) .unwrap_or_else(|| active_tab.fg_color.into())
.to_linear() .to_linear()
.into(), .into(),
}), }),
@ -661,10 +665,11 @@ impl super::TermWindow {
}, },
})) }))
.colors({ .colors({
let inactive_tab = colors.inactive_tab();
let bg = bg_color let bg = bg_color
.unwrap_or_else(|| colors.inactive_tab.bg_color.into()) .unwrap_or_else(|| inactive_tab.bg_color.into())
.to_linear(); .to_linear();
let edge = colors.inactive_tab_edge.to_linear(); let edge = colors.inactive_tab_edge().to_linear();
ElementColors { ElementColors {
border: BorderColor { border: BorderColor {
left: bg, left: bg,
@ -674,26 +679,29 @@ impl super::TermWindow {
}, },
bg: bg.into(), bg: bg.into(),
text: fg_color text: fg_color
.unwrap_or_else(|| colors.inactive_tab.fg_color.into()) .unwrap_or_else(|| inactive_tab.fg_color.into())
.to_linear() .to_linear()
.into(), .into(),
} }
}) })
.hover_colors(Some(ElementColors { .hover_colors({
let inactive_tab_hover = colors.inactive_tab_hover();
Some(ElementColors {
border: BorderColor::new( border: BorderColor::new(
bg_color bg_color
.unwrap_or_else(|| colors.inactive_tab_hover.bg_color.into()) .unwrap_or_else(|| inactive_tab_hover.bg_color.into())
.to_linear(), .to_linear(),
), ),
bg: bg_color bg: bg_color
.unwrap_or_else(|| colors.inactive_tab_hover.bg_color.into()) .unwrap_or_else(|| inactive_tab_hover.bg_color.into())
.to_linear() .to_linear()
.into(), .into(),
text: fg_color text: fg_color
.unwrap_or_else(|| colors.inactive_tab_hover.fg_color.into()) .unwrap_or_else(|| inactive_tab_hover.fg_color.into())
.to_linear() .to_linear()
.into(), .into(),
})), })
}),
} }
}; };
@ -736,23 +744,28 @@ impl super::TermWindow {
.vertical_align(VerticalAlign::Middle) .vertical_align(VerticalAlign::Middle)
.float(Float::Right) .float(Float::Right)
.item_type(UIItemType::CloseTab(tab_idx)) .item_type(UIItemType::CloseTab(tab_idx))
.hover_colors(Some(ElementColors { .hover_colors({
let inactive_tab_hover = colors.inactive_tab_hover();
let active_tab = colors.active_tab();
Some(ElementColors {
border: BorderColor::default(), border: BorderColor::default(),
bg: (if active { bg: (if active {
colors.inactive_tab_hover.bg_color inactive_tab_hover.bg_color
} else { } else {
colors.active_tab.bg_color active_tab.bg_color
}) })
.to_linear() .to_linear()
.into(), .into(),
text: (if active { text: (if active {
colors.inactive_tab_hover.fg_color inactive_tab_hover.fg_color
} else { } else {
colors.active_tab.fg_color active_tab.fg_color
}) })
.to_linear() .to_linear()
.into(), .into(),
})) })
})
.padding(BoxDimension { .padding(BoxDimension {
left: Dimension::Cells(0.25), left: Dimension::Cells(0.25),
right: Dimension::Cells(0.25), right: Dimension::Cells(0.25),