wez / wezterm

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

OSC 50 support (Set Font) #4181

Open AlexKurisu opened 1 year ago

AlexKurisu commented 1 year ago

Is your feature request related to a problem? Please describe. As far as i understand, WezTerm doesn't support setting a terminal font with an escape sequence. OSC 50 is an XTerm OSC that allows you to do so.

Describe the solution you'd like Support for XTerm OSC 50 to allow programs to set terminal font.

Describe alternatives you've considered Setting up terminal-specific klugdes.

Additional context Links, if needed: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html, https://www.xfree86.org/current/ctlseqs.html

wez commented 1 year ago

https://github.com/xtermjs/xterm.js/issues/3367 has some relevant insights/discussion

acook commented 6 months ago

I am primarily interesting in querying the primary font, to be able to guess at certain font features to use fun things like Fira Code's spinners, intelligently choose when to use powerline symbols, or use some of the KreativeKorp or Iosevka legacy computing symbols that aren't yet officially released as part of Unicode.

But being able to set fonts would be cool too. But it is a bonus.

I've done a decent amount of research on OSC 50 and compiled or installed many terminals to test capabilities.

It seems like most of the terminals with open issues are all waiting for someone else to do it first. With some people claiming it was invented by Xterm or that it is brand new.

There at least 5 separate terminals which support OSC 50 to one degree or another.

A very similar way to set change between fonts in terminals was defined in ECMA-48 from 1991. But as far as I am aware it did not specify 50 as the escape sequence.

Terminals with Support

(please let me know if you find more)

The way ECMA-48 formats their encodings is weird to me, so I'm not sure if OSC 50 specifically was what they meant or not, but the standard matches almost identically to XTerm's documentation.

Contour additionally supports their own OSC 60 which avoids overloading OSC 50 with extra features. It allows setting fallback fonts and more. Their implementation is nice. I'm not sold on it being at 60, but I am under the impression they would like to be able to add features without feeling steamrolled by XTerm, and I can respect that. I don't think that OSC 60 provides fallback fonts, so it is of limited usefulness beyond OSC 50 for application developers looking for particular font features.

URXVT requires a fully qualified XLFD name with style suffix and xft: prefix when setting the font, which differs from the other implementations. But it is still pretty easy to generate that directly from fc-list output. URXVT responds with ^G in place of the font when queried, but considering it renders input differently than other terminals, this may be an artifact of that.

Terminals with Open Issues

Terminals Without Support

There are almost certainly open issues for some of these too, I just haven't looked for them.

Workarounds

Wezterm allows for wezterm ls-fonts --text "x" to pull the font from the config, with some cleanup this can be used to query the font. Honestly one of the better workarounds. I believe URXVT and XTerm have something similar as well.

FastFetch reads from a bunch of different terminals' configurations to guess what their font is. I would really rather not implement that as it is fragile and requires a lot of bespoke code and potentially external binaries that may or may not be present (like gsettings).

It is also possible to hook the terminal emulator's open file handles and see which font files it is accessing. But how this interacts with fallback fonts (which is the primary font?) or if the particular terminal even keeps an open file handle at all makes this unreliable.

Alternatives

Querying

An escape sequence which could be shared among terminals which responded to queries about populated glyphs in their multiple font and fallback repertoire. Similar to wezterm ls-fonts, but simplified so that applications could do feature detection on the fonts.

Setting

An improved and (at least informally) standardized way to set fonts that is relatively stable cross-platform and supports a reasonable set of features that many terminals have or may in the future have which uses something other than OSC 50.

Mission Statement

It is not reasonable to think that library and application developers are going to want to support every terminal's bespoke out-of-band way to query and set fonts.

Terminfo is limited, and we should probably come up with something better, but even that better thing is probably not going to support a bunch of different commands and bits of embedded code which might get you something similar.

Disclaimer

Please note that none of this is criticism of any single dev or project! I understand that this is a fluid and organic situation with many different people involved with different use cases.

The reason I am posting all of this in this particular issue is because Wezterm is the terminal I use, I like Wezterm, I have contributed a tiny amount to it, and had positive interactions here so Wezterm is my priority.

I will support Wezterm's implementation specifically in my projects regardless because this is the one I use. I just doubt I will end up writing much more code beyond getting Wezterm and OSC 50 working. There's just too much divergence.

If nothing else, I hope this information will be useful to someone.

Changelog