wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
16.69k stars 746 forks source link

Allow reduced opacity for dim text #6026

Open dhruvkb opened 3 weeks ago

dhruvkb commented 3 weeks ago

Is your feature request related to a problem? Please describe. Currently font_rules uses lighter weight for dim text.

This is a bit of an accessibility issue as I have a hard time both reading the light text and differentiating it from regular text as the difference is extremely small.

Describe the solution you'd like

It would be better if there was an option to keep the same weight, and use a reduced opacity for dim text. It would be more similar to what other terminals are doing w.r.t. intensity.

Additional context

Here is how the same output looks in iTerm2 (left, with reduced opacity) and WezTerm (right, with reduced font weight).

Screenshot 2024-08-24 at 7 52 12 PM
dhruvkb commented 3 weeks ago

I have attempted to fix this using a foreground setting as below, but it does not work when the app specifies a text color, which seems to take priority over the foreground configuration.

-- `mid_color()` returns a color between the foreground and background,
-- i.e. emulates reduced opacity
config.font_rules = {
  {
    intensity = 'Half',
    font = wezterm.font_with_fallback(
      { 'JetBrainsMono Nerd Font' },
      { foreground = mid_color(), weight = 'Thin' }
    ),
  },
}
dhruvkb commented 2 weeks ago

I also noticed an additional "bug" when using a thinner font instead of reduced opacity, it does not affect Nerd Font icons.

If you look closely, iTerm2's approach of reduced opacity also affects the icons in the dimmed text making them less prominent, whereas WezTerm's approach of reduced font weight has no effect on the icons and leaves them looking just as prominent as without dimming.

@wez could you reclassify this issue as a "bug" instead of "enhancement"? Thanks.

jameshurst commented 1 week ago

TLDR: Try using JetBrainsMono NF instead of JetBrainsMono Nerd Font.

I've also been trying to figure out how to get dimmed text to render at a reduced opacity instead of using a light font variant.

I tried playing around with font_rules as suggested in https://github.com/wez/wezterm/discussions/4026#discussioncomment-6652091, but specifying the regular font weight does not result in wezterm synthesizing a dim font and simply renders dimmed text as regular text.

I had also tried using the font's full name and postscript name as described in https://wezfurlong.org/wezterm/config/lua/wezterm/font.html, but both resulted in wezterm being unable to locate the font.

I'm also using JetBrainsMono Nerd Font and noticed using wezterm ls-fonts that the font was also available under the name JetBrainsMono NF.

Using JetBrainsMono NF does result in wezterm synthesizing a dim font instead of using the light variant.

> function try_font() { wezterm -n --config font="wezterm.font(\"$*\")" ls-fonts | rg -PU '(?sU)(When\b.*\bIntensity=Half\b.*)\n.*\{\n(.*)\n\n' -r $'$1\n$2' }

> try_font JetBrainsMono Nerd Font
When Intensity=Half Italic=true:
  -- /Users/jameshurst/Library/Fonts/HomeManager/truetype/NerdFonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf, CoreText
  -- AKA: "JetBrainsMono NF"
  -- AKA: "JetBrainsMono NF ExtraLight"
  {family="JetBrainsMono Nerd Font", weight="ExtraLight", style="Italic"},
When Intensity=Half Italic=false:
  -- /Users/jameshurst/Library/Fonts/HomeManager/truetype/NerdFonts/JetBrainsMonoNerdFont-ExtraLight.ttf, CoreText
  -- AKA: "JetBrainsMono NF"
  -- AKA: "JetBrainsMono NF ExtraLight"
  {family="JetBrainsMono Nerd Font", weight="ExtraLight"},

> try_font JetBrainsMono NF
When Intensity=Half Italic=true:
  -- /Users/jameshurst/Library/Fonts/HomeManager/truetype/NerdFonts/JetBrainsMonoNerdFont-Italic.ttf, CoreText
  -- Will synthesize dim
  -- AKA: "JetBrainsMono NF"
  {family="JetBrainsMono Nerd Font", style="Italic"},
When Intensity=Half Italic=false:
  -- /Users/jameshurst/Library/Fonts/HomeManager/truetype/NerdFonts/JetBrainsMonoNerdFont-Regular.ttf, CoreText
  -- Will synthesize dim
  -- AKA: "JetBrainsMono NF"
  "JetBrainsMono Nerd Font",

I believe the reason JetBrainsMono NF works is due to AKA: JetBrainsMono NF only fully matching the AKA for the regular and bold weights.

> wezterm -n ls-fonts --list-system >/dev/null 2>&1 | rg '(.*)\(AKA:.*\bJetBrainsMono NF\b.*\)' -o
wezterm.font("JetBrainsMono Nerd Font", {weight="Thin", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Thin)
wezterm.font("JetBrainsMono Nerd Font", {weight="Thin", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Thin)
wezterm.font("JetBrainsMono Nerd Font", {weight="ExtraLight", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF ExtraLight)
wezterm.font("JetBrainsMono Nerd Font", {weight="ExtraLight", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF ExtraLight)
wezterm.font("JetBrainsMono Nerd Font", {weight="Light", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Light)
wezterm.font("JetBrainsMono Nerd Font", {weight="Light", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Light)
wezterm.font("JetBrainsMono Nerd Font", {weight="Regular", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF)
wezterm.font("JetBrainsMono Nerd Font", {weight="Regular", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF)
wezterm.font("JetBrainsMono Nerd Font", {weight="Medium", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Medium)
wezterm.font("JetBrainsMono Nerd Font", {weight="Medium", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF Medium)
wezterm.font("JetBrainsMono Nerd Font", {weight="DemiBold", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF SemiBold)
wezterm.font("JetBrainsMono Nerd Font", {weight="DemiBold", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF SemiBold)
wezterm.font("JetBrainsMono Nerd Font", {weight="Bold", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF)
wezterm.font("JetBrainsMono Nerd Font", {weight="Bold", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF)
wezterm.font("JetBrainsMono Nerd Font", {weight="ExtraBold", stretch="Normal", style="Normal"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF ExtraBold)
wezterm.font("JetBrainsMono Nerd Font", {weight="ExtraBold", stretch="Normal", style="Italic"}) -- (AKA: JetBrainsMono NF, JetBrainsMono NF ExtraBold)

This still has the issue though of being unable to render bold+dim text (https://github.com/wez/wezterm/discussions/5187). I don't believe bold+dim can work using the current font_rules since bold is defined as intensity = "Bold" and dim is intensity = "Half". To render bold+dim I believe intensity = "Half" would have to be removed and another configuration option for how to render dimmed text would have to be introduced.

dhruvkb commented 1 week ago

I ultimately ended up using a cascading system of {"Monaspace Neon", "Symbols Nerd Font"} and manually deleted all the weights of Monaspace Neon below 400 to force the synthesized dim. It would be really great if I didn't have to do that everytime the fonts are updated.