Open gbraad opened 3 years ago
So I think this issue is actually several:
I think we're going to add the new RedHatMono font as the default here. I'm guessing it doesn't user powerlines, so we might need to fork it and run it through a patcher tool to add powerlines. https://redhatofficial.github.io/RedHatFont/
(* nerd-fonts has a patcher tool @ https://github.com/ryanoasis/nerd-fonts#font-patcher)
Or perhaps we could use CSS font subsetting to monkey-patch all fonts with powerline support in-browser?
There's an article explaining this @ https://www.sitepoint.com/joy-of-subsets-web-fonts/
The gist is:
This is probably what we want to do, as long as the height metrics match. (Otherwise I might need to adjust the powerline.otf for RedHatMono by default and then we might need to ship two. Or see if we can use size-adjust (spoiler: probably not, as it doesn't work on Safari yet and it might not work as expected anyway).
If we do have a font switcher, we might need to rethink the settings anyway and perhaps just move to the menu redesign outright (perhaps with a bar when embedded in a page and then have an option to turn off the bar otherwise). In other words: A font switcher would add more widgets and our current UI won't scale.
Also, a font switcher should have system-available fonts in addition to RedHatMono (which we should have soon), and we'd have to detect the fonts. We'd probably have to have a shortlist of fonts to vet (on macOS, Windows, and various Linuxes) and have native monospace font as well. And then possibly a way to have a manual font name. (This sounds like an autocomplete widget would make sense here.)
Saving the preference
Totally
(in a cookie)
Not so much...
Cookies to store preferences is probably not the best idea. These get sent back and forth with each request and respons. It would be better to utilize session storage, or local storage.
It might even be possible in that case to sync the storage from the cockpit backend to the frontend, to allow this kind of setting to persist between sessions on different machines. But that is a detail and improvement. Cookies are bad... But usable for token and authentication information to binds a session. Not so much for settings unless they are needed to be shared with the backend as state.
Cookies to store preferences is probably not the best idea. These get sent back and forth with each request and respons. It would be better to utilize session storage, or local storage.
Sure, I mean local storage in the browser, not on the server. We do these elsewhere in Cockpit.
It might even be possible in that case to sync the storage from the cockpit backend to the frontend, to allow this kind of setting to persist between sessions on different machines. But that is a detail and improvement.
No, it's not. We specifically do not set Cockpit-specific settings on the host. We only ever save system-related data. This is why I was talking about browser storage, as we use that for other Cockpit-specific settings.
(I meant browser's local storage independent of technology, not necessarily a cookie.)
Not so much for settings unless they are needed to be shared with the backend as state.
User preference settings are a state that need to be shared with the backend.
Hi guys, is there a solution, even not out of the box, for cockpit's font issue or we have to wait ? Thanks
You'd think you could do this with Stylus with custom CSS...
...however, the terminal uses Canvas, so this won't work... at least after the canvas is rendered.
Here's what it the DOM looks like in Firefox's developer tools:
In other words, it's trickier than what you'd expect.
Oddly, the font stack is "Menlo, Monaco, Consolas, monospace"... And I see this is in pkg/lib/console.css
and in pkg/lib/cockpit-components-terminal.jsx
(Those are macOS and Windows fonts, with a fallback to just monospace
. I guess it was copied from some example or something.)
It's possible that it's pulling in the font and rendering it. So perhaps a CSS override would work, if it's done before the page loads and renders. Swapping it out after rendering doesn't work.
Or, we could try to load system fonts that are more optimal by adjusting the font stack, including powerline fonts (on the system where the browser is), if they're there. That should provide better defaults without having to do the font switching.
IntelliJ Mono font is popular among my friends - https://www.jetbrains.com/lp/mono/ It has support for Powerline and foreign languages.
I'd be very interested in this too
In a more recent version this seems to work for me:
In a more recent version this seems to work for me:
@gbraad That's interesting, I cannot reproduce that with the latest version of cockpit-ws
(294.1). Still only font-family: Menlo, Monaco, Consolas, monospace;
are set. Which version are you using on which OS/browser, and which special characters are supported there? Can you see which fonts are used to render them?
For example, I am using https://github.com/spotsnel/cockpit-tailscale (start from GitPod: https://gitpod.io/#https://github.com/spotsnel/cockpit-tailscale). This a F38 docker image and I open this on Vivaldi (a chrome-based browser) on Windows due to cross-platform work.
The image installs:
cockpit-ws-294.1-1.fc38.x86_64 79/99
$ sudo passwd gitpod
$ npm run cockpit
but similarly, a local install on my T14 or T460p behave the same (based on the same install images).
Vivaldi:
Firefox: Note: interesting glitch (dark mode not working as expected)?!?
~I'll also check on my F38 install, as this might well be OS specific.~
Vivaldi:
Firefox:
Vivaldi:
Firefox:
So, as you can see. My original problem is actually solved, as the glyphs (mostly) render correctly. Except for mobile, though even this is more than 50% there.
without having to do the font switching.
I am in this case less concerned about the actual font.
Thanks for the insights! I can reproduce the prompt above, that looks fine, however I cannot figure out which font is used to render the arrowheads there, as they are not part of any of the standard monospace fonts I can find in the CSS. But those appear to be the only working characters. All other glyphs like icons for OS, git provider, the home directory, CPU, RAM, network, battery state etc. are still not supported. This is reproducable in the gitpod by switching to the ~/.oh-my-zsh
directory – this is shown on the right side:
My personal prompt looks even worse at the moment:
So from my perspective it would still be relevant to have the possibility to either be able to provide a custom font or have Cockpit use a font supporting more than just the basic Powerline characters.
however I cannot figure out which font is used to render the arrowheads there
As you can see, in some of the targets it does render the lock, but on mobile not at all. On Linux I can check but expect this to also work.
So, yeah. it looks like special glyphs are problematic, while the powerline-specific glyphs work.
Checked Linux just to be sure:
Vivaldi:
Firefox:
Note: Vivaldi does not render the special glyphs.
On Windows, the Git branch glyph does render:
So it still really depends on the OS+browser how this renders. For my machines this does not seem to be overall an issue, except for mobile browsers... but these are known to have limited font support.
Since this is a complex topic and there are many unanswered questions, I'll try to share my knowledge…
Rendering of unknown characters in browsers varies from vendor to vendor, but basically all of them use the first available (locally installed or hosted) font.
What @gbraad found was, that some browser-vendors provide an override, that when a glyph in the used font is not available, it goes to the next font in the font-family list for that glyph.
The problem with that solution is that typefaces are inconsistent when it comes to missing characters: Some leave them empty, so the above mentioned override can work, others fill that missing glyph w/ a placeholder, so the browser render the placeholder instead of trying the next font in the list.
Cockpit styles are provided in form of pre-built static CSS files and as it turns out each Linux distribution has their own preference of what to set and then built in to those CSS files. (just checked misc distributions; and this may be also the reason, why some have more problems than others.)
/etc/cockpit/<SOMETHING>
and use its value shouldn't be too difficult to implement, but we shouldn't use system-fonts (.ttf
, etc.) and use web-fonts (.woff
) instead (Just Google it! - Don't want ot open that can of worms here. :wink: ) - Therefore we would have to figure out a mechanism to host those web-fonts.font-family: monospace;
for any monospaced font in Cockpit.NOTE: This suggested solution only works on desktop-browsers, since at least I don't know of any mobile-browser that allows for customization of any fonts. Therefore, if the default monospace font on mobile is problematic, I'd suggest to use a query-selector for mobile and use @garrett suggested sugared font on mobile only.
@saturated-white Safari on macOS also offers no possibility to change the default monospace font, so this issue is not restricted to mobile devices.
Therefore I like the option to use a config flag, perhaps in combination with a CSS class holding the font-family
value which can easily be overridden by clients if desired.
Sadly, these suggestions would not work.
I'm happy that it's working in some places (as seen in the screenshots above), but, yes, this still needs work to work everywhere. If anyone figures out a solution and sends a PR, it'd be great to look at.
It looks like this is a problem in XTerm.js
(which is what Cockpit uses in the stack) loading things in canvas, and there's a workaround @ https://www.npmjs.com/package/xterm-webfont which would need to be loaded and configured.
Perhaps the best solution is still:
Note:
Meanwhile, there are a lot of powerline-related issues and PRs at Xterm.js: https://github.com/xtermjs/xterm.js/issues?q=powerline (only 2 open currently; just saying that a lot of people have been hard at work on it, and that's why we're seeing it work in some places)
Thanks @marvinruder , I wasn't aware that Apple removed this feature from Safari.
I'm not going to dispute any of the "would not work" bullet-points, despite some look more like "design-decisions" by the Cockpit-Team to me. - Therefore they are still valid in their own way.
But I think I was misunderstood regarding one thing: "Fonts per distribution doesn't matter on the Cockpit server side of things." - I just wanted to point out, that for example Ubuntu (e.g. v20.04) ships their official package of Cockpit w/ "Menlo, Monaco, Consolas, monospace" and not the "RedHatFont". Therefore it may be another factor, why it may only work for some people in this issue discussion.
Regarding "best solution" by @garrett : I'd also be for a new font w/ complete support of the Powerline glyphs then. (If I read RedHatFont's License correctly, there shouldn't be a legal problem to create a new Powerline glyphs sugared font under a different name.)
more like "design-decisions" by the Cockpit-Team to me
Which ones? Not a single one in that list is a decision decision. They're all due to technical reasons. This is just how the web and web browsers and UNIX permissions.
(I'd know. I'm the designer on the team and I've been using Linux and doing web stuff since 1996.)
Ubuntu (e.g. v20.04) ships their official package of Cockpit w/ "Menlo, Monaco, Consolas, monospace" and not the "RedHatFont".
This is news to me. It would break our screenshot testing, if it were the case. Where are you seeing this?
I can 100% guarantee Ubuntu doesn't ship those fonts. Menlo and Monaco are proprietary macOS fonts; Consolas is proprietary Windows.
https://en.wikipedia.org/wiki/Menlo_(typeface)
I guess they're possibly listed in the font stack somewhere? Possibly just in the terminal widget? But mention of a font doesn't mean it is shipped or being used.
If I read RedHatFont's License correctly
SIL Open Font License is pretty much the de facto open source font license; there's nothing specific to RedHatFont. It's approved by FSF, OSI, and DFSG.
The rename requirement is due to how fonts are implemented on computers. They're unversioned, so you reference a font by name. If the font is different with the same name, it will cause unexpected things to happen. Therefore: Rename.
https://en.wikipedia.org/wiki/SIL_Open_Font_License
Even still: It is possible to patch a font at runtime and expose the same name to the browser. The font name needs to be different, but the CSS can "monkeypatch" / "hotpatch" it live. We've extended fonts like this within Cockpit for various reasons (adding icons back when we used icon fonts, swapping out the slashed zero with an unslashed one, etc.).
You cannot really detect fonts like that (query selector) on the web.
We actually had no choice in a legacy closed-source project, but to add/implement such "query selector". - Maybe the term was chosen badly, since it is a combination of: HTTP-Headers, checking misc avail. CSS-Selectors and checking misc avail. JS functions/objects. - This solutions seems to work pretty stable for months now, since we had no customer complaints regarding that.
We are not going to remove monospace font support across Cockpit just for the terminal (nor is it necessary to do so).
The "we are not going to" part clearly sounds like a design-choice.😉
We cannot serve a system file directly; there are file permissions and such.
Maybe I misinterpreted the "system" part of that sentence, but in my previous post I tried to suggest following:
/etc/cockpit/terminal-fonts
(…since system (TTF) fonts are troublesome anyway)This solution should address following problems/points:
(I'd know. I'm the designer on the team and I've been using Linux and doing web stuff since 1996.)
Respect!! - I'm not that long in that business, but still developing for the Web since 2001 and using Linux since 2002.
This is news to me. It would break our screenshot testing, if it were the case. Where are you seeing this?
Maybe I find time to re-confirm it by re-installing the system, but basically we currently need a plain Ubuntu 20.04 server for in-house integration testing, since that customer only support that selected system in their environment. For that we just used the official Ubuntu 20.04 server ISO, installed the latest updates, cockpit and a few libraries needed for that mentioned integration test. And when connecting to Cockpit of that machine, the Dev-Tools state:
.console-ct {
font-family: Menlo, Monaco, Consolas, monospace;
/* … */
}
To clarify: They don't "host" any of the declared fonts, they seemingly just changed the CSS and hope the user has one of the listed fonts on their system.
They're unversioned, so you reference a font by name. …
Yeah, additionally to the version-state, there's actually an additional problem, that W3C doesn't specify what has precedence, when a font is locally installed + served by the website. Therefore some browser (on some systems) load the local font, whereas others load the web-hosted one.
It is possible to patch a font at runtime and expose the same name to the browser.
You're absolutely right, but my personal experience has shown, that monkey-patches usually bite you in the a*** at some point. Therefore I'd still suggest to go the renamed+extended font route.
I had the same issue recently. 2024 March.
@LittleNewton: Which issue? That you cannot change the font? (Which is expected, as that's not an issue; there isn't a font switcher.) Or that powerline looks wrong for you?
Could you share more details, like your system information (OS of server with Cockpit and client OS with the browser), browser and version, Cockpit version, etc.
For reference, here's Cockpit with powerline installed on my Fedora 40 beta system using Firefox 124.0.2 (server and client are the same; I'm running Cockpit locally):
@garrett, I am sorry for not providing details about my shell profile and OS internals.
12.5
, the latest version.123.0.6312.105
cockpit-389-ds/stable 2.3.1+dfsg1-1 all
I am using zsh as my shell. My personal profile is built based on Oh-My-Zsh. All the details about my zsh config can be found here.
Here is my Windows client's (Windows Terminal) display:
Cockpit in chrome display:
I hope those information would be helpful.
PS. I'd like to contribute to the functionality of cockpit. However, I need to become more familiar with Web UI design.
It would be nice if the font that is used for the terminal can be changed. When for instance a airline/powerline is used, the glyphs aren't properly rendered as the default font might not have these.
Since the size can be changed, it might be possible to allow free-editing of the font, pretty much like vscode or codesandbox allows with comma separation, or provide several well-known options (which might avoid the need to sanitize input).