1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-27 15:37:29 +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 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 {
fn from(cp: ColorPalette) -> Palette {
let mut p = Palette::default();
@ -291,37 +341,101 @@ impl TabBarColor {
/// 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
/// 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 {
/// The background color for the tab bar
#[dynamic(default = "default_background")]
pub background: RgbaColor,
#[dynamic(default)]
pub background: Option<RgbaColor>,
/// Styling for the active tab
#[dynamic(default = "default_active_tab")]
pub active_tab: TabBarColor,
#[dynamic(default)]
pub active_tab: Option<TabBarColor>,
/// Styling for other inactive tabs
#[dynamic(default = "default_inactive_tab")]
pub inactive_tab: TabBarColor,
#[dynamic(default)]
pub inactive_tab: Option<TabBarColor>,
/// Styling for an inactive tab with a mouse hovering
#[dynamic(default = "default_inactive_tab_hover")]
pub inactive_tab_hover: TabBarColor,
#[dynamic(default)]
pub inactive_tab_hover: Option<TabBarColor>,
/// Styling for the new tab button
#[dynamic(default = "default_inactive_tab")]
pub new_tab: TabBarColor,
#[dynamic(default)]
pub new_tab: Option<TabBarColor>,
/// Styling for the new tab button with a mouse hovering
#[dynamic(default = "default_inactive_tab_hover")]
pub new_tab_hover: TabBarColor,
#[dynamic(default)]
pub new_tab_hover: Option<TabBarColor>,
#[dynamic(default = "default_inactive_tab_edge")]
pub inactive_tab_edge: RgbaColor,
#[dynamic(default)]
pub inactive_tab_edge: Option<RgbaColor>,
#[dynamic(default = "default_inactive_tab_edge_hover")]
pub inactive_tab_edge_hover: RgbaColor,
#[dynamic(default)]
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 {
@ -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)]
pub struct TabBarStyle {
#[dynamic(default = "default_new_tab")]

View File

@ -993,8 +993,6 @@ impl Config {
cfg.load_color_schemes(&cfg.compute_color_scheme_dirs())
.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() {
match cfg.resolve_color_scheme() {
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) {
cfg.background.insert(0, bg);
}

View File

@ -17,6 +17,7 @@ As features stabilize some brief notes about them will accumulate here.
#### 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)
* [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)

View File

@ -17,13 +17,21 @@ return {
You can find a list of available color schemes and screenshots
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
Rather than using a color scheme, you can specify the color palette using the
`colors` configuration section. Note that `color_scheme` takes precedence
over this section.
You can specify the color palette using the `colors` configuration section.
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),

View File

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

View File

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