element-desktop
element-desktop copied to clipboard
Text appears blurry on Desktop (Windows)
Description
Compared to other applications and Element Web in Firefox, text appears blurry in Element Desktop.
Steps to reproduce
- Open Element
- Observe any text
Example screenshot taken with system font Arial, 14pt in a random matrix room:
(open in new tab so it is unscaled)
All fonts in the UI are affected, not just chat messages. I don't have any other applications where I have seen this problem before. In other applications and Firefox, fonts look very sharp by comparison. This is the same text screenshotted from Element Web in Firefox 82:
Through older issues I've found https://github.com/electron/electron/blob/master/docs/faq.md#the-font-looks-blurry-what-is-this-and-what-can-i-do and it very much looks like that problem, but as I understand this is supposed to be fixed already?
Logs being sent: no
Version information
- Platform: Desktop
- OS: Windows 10 2004 x64
- Version: 1.7.12
Hmm, that is quite curious... We have already applied the recommended fix in that Electron FAQ entry, yes. I'll try to get some feedback from other Windows users to see if this affects them as well.
Can you try reproducing this on another Electron app, e.g. Atom, VSCodium, etc.?
VSCodium (1.50.1 w/ Electron 9.2.1 based on Chrome 83.0.4103.122) looks sharp:
Used the same font - Arial - again, but I had to set 13pt to get the same size.
Zooming into the text shows that Element Desktop renders fonts very differently (I don't know much about fonts myself).
Element Web in Firefox:
Element Desktop:
This shows why the font appears so blurry: Look at the word "spell" in the first and second line; the "l"s are rendered differently each time. The "i"s in the last line are also a good example.
VSCodium:
Hmm, this is quite a perplexing one... Other people in the community have said they are not affected by this on Windows, so it suggests to me that something system specific is happening here...
@AgentOak Are you perhaps pinning Element to a specific GPU, or have you made any other "customisation" to the app like that, which might explain the difference between Element vs. your other apps?
Other people in the community have said they are not affected by this on Windows, so it suggests to me that something system specific is happening here...
I have seen one such image posted in #element-web:matrix.org where the poster said they weren't affected, but zooming in to the text shows that it's using the same grayscale rendering as in my screen
It's just not as noticeable with fonts this large/on HiDPI.
@AgentOak Are you perhaps pinning Element to a specific GPU, or have you made any other "customisation" to the app like that, which might explain the difference between Element vs. your other apps?
The system I'm on only has one GPU, a Geforce GTX 670 with recent Nvidia Drivers 456.71. The GPU doesn't seem to affect anything anyway; launching Element with --disable-gpu changes nothing about the font rendering. It's a plain installation from the official installer and the blurry font was already there when I started Element for the first time.
FWIW, I was able to reproduce it with a fresh installation on another Windows 10 PC (with a Geforce GTX1080 on 457.09), but both PCs were set up by me so they pretty much use the same settings and software.
For completeness, this is the default font on default size (15pt).
I wonder if the problem here is that the fix we use to make the fonts look crisp at retina on macOS (i.e. to use pure greyscale antialiasing rather than colour-fringing subpixel antialiasing) is now having the opposite effect on Windows (despite us thinking otherwise at https://github.com/vector-im/element-web/issues/11425#issuecomment-555486636:
// needed to match the designs correctly on macOS
// see https://github.com/vector-im/element-web/issues/11425
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@AgentOak can you try opening the network inspector in Electron and hunting down the -webkit-font-smoothing
property on the body tag and toggling it on & off to see if that fixes it?
DevTools show that the -moz-osx-font-smoothing
property is not used at all. For -webkit-font-smoothing
, the values antialiased
, subpixel-antialiased
, none
and disabling the property all look the same.
I don't think you're going to need any -moz
prefixed properties in Electron. Unless you're planning to switch to XUL for the app 🤷♂️
For me the difference is also quite noticable, as I can switch the app between my 4K primary monitor and "regular" secondary monitor. The app looks crisp in 4K (where blurry antialiasing is "hidden" by pixels that are too tiny to see anyway), but more blurry than it ought to on my secondary monitor. And since I'm on Windows 10 20H2, I really doubt any OSX-specific properties are going to fix anything.
Shouldn't text just render crisp without any of those properties? Same as Chrome, essentially. The default should be good, as most websites don't use those tacky platform-specific properties, and they all render absolutely fine on all three platforms.
That's what I thought as well. Element continues to be the only application I use suffering from this poor font rendering.
The Electron wiki mentions some other causes for this issue (besides the opaque window background) like transforms or subpixel positioning, but for lack of experience with Chromium/Electron I'm not able to diagnose this issue on my own.
I'm making some progress here... I can reproduce the issue in Element and the Electron Fiddle does not exhibit the problem, so it's definitely something specific to what we are doing.
It's not the font smoothing settings either. I'll need to dig a few steps further, but hoping to have a cause isolated soon. 😄
Current Status
From my perspective, this is effectively a Chromium rendering choice / regression, and you can find many bugs across the Chromium bug tracker around different variants of this issue over the last few years, such as https://bugs.chromium.org/p/chromium/issues/detail?id=1016062.
It appears we can apply various CSS workarounds to regain ClearType's subpixel antialiasing, by adding things like:
-
contain: paint
-
background: some-opaque-color
-
transform: translate3d(0px, 0px, 0px)
to force a compositing layer
However, it feels like a nasty hack to me, as it may force other browsers to use less optimal paths purely to solve a Chromium-specific issue. There's nothing specific to Electron here, as the same issue is observable in Chrome as well.
Other Apps
Looking at how other similar apps perform in Chrome on Windows:
App | Antialiasing |
---|---|
Element | grayscale |
Hydrogen | grayscale |
Slack | grayscale |
Discord | subpixel |
Next Steps
Rather than applying the hacks above, it would be better to work out precisely which things are causing Chromium to fall back to grayscale in our case. This will likely require some painful CSS bisection. 😖
Slack definitely doesn't look nowhere near as blurry as Element does, even though it does indeed appear to render with greyscale antialiasing... So there might be something else at play than just subpixel vs greyscale.
I'm curious to know if there's any progress being made. I thought the fix could be copypasted from any other opensource electron-based application.
There are two issues at play:
- Greyscale rendering instead of subpixel rendering
- Blurrier rendering regardless of (1).
The second issue is solved in a number of other electron-based applications, among which are Slack and VScode. Having their fix in Element as well, may solve the problem. They too have greyscale rendering rather than subpixel. But they do render sharp text regardless.
As for greyscale rendering vs subpixel, that's an additional improvement that could further improve clarity.
No further progress has been made. I'm sure this issue will be updated when it happens.
Sad to hear it. Anything I can do to help?
Isn't the actual issue that the Inter font used by Element does not have hinting? Same for the Inconsolata font for code, etc. No amount of messing with rendering settings is going to fix that, you need to either (auto)hint the fonts or use different ones.
@madig I tested with the Arial system font (which can be set in Element settings -> Appearance -> Show advanced) in the screenshots above. It's better than the default font which is completely unbearable to me, but still blurry.
Trying to figure out how VSCode team solved this problem, as I remember even last year that VSCode was super blurry on my windows machine for some reason, but I didn't investigate.
It seems that in Discord in Chrome the sub-pixel rendering is not turned on for every layer. It's not working for rooms, your chats, etc, but works for the general chat. Generally the rendering is very inconsistent even though it looks good. Probably this issue should consist of two separate things: 1: Figuring out how to improve fonts legibility on Windows 2: Turning on subpixel rendering in Chrome/Electron for at least the Timeline/Chat window
Found the culprit: It's this line of css:
backdrop-filter: blur
seems that for some, still unknown to me reason, chrome decides to make a layer that's of a size of the entire window, even if you constraint it. If you want to use backdrop-layer: blur
you need to use it extremely sparingly and surgically, otherwise it thrashes the Chrome's layers and breaks font rendering. This surgical precision may still not be enough, though.
Currently looking for a solution that won't screw up our designs.
I wonder if it shouldn't be using ::backdrop
instead, since backdrop-filter
appears to be useful for elements (dialogs I suppose, like the settings?) that show the background through, which Element doesn't do.
Pull request solving this problem (in progress): https://github.com/matrix-org/matrix-react-sdk/pull/6262
Related, as it should reduce layout trashing and remove the case where we have couple of frames of improper font (grayscale) when loading new messages https://github.com/matrix-org/matrix-react-sdk/pull/6054
Just so it won't get lost, the VSCode team fought with the same problem and found a solution, that unfortunately doesn't look like it works for us: https://bugs.chromium.org/p/chromium/issues/detail?id=1016062#c22 If someone could figure out how to use their solution for our problem, that would be actually pretty awesome!
@AgentOak @thany @madig can you check now if it's better? There's still some grayscale fonts antialiasing on the left column, but the entire timeline should have proper antialiasing now.
Just to write a post-mortem of this issue: there was a few things breaking the fonts rendering.
- Invalid DOM tree - our left panel wasn't separated from the timeline in the a clear way, which made Chrome treat everything that happened on that tree on the same layer as the timeline (it was a direct sibling instead of it's container being a sibling to timeline container)
- CSS transforms not behaving nicely with the above; instead of being able to clearly separate layers we had those merged together in the rendering pipeline
- backdrop-blur should still not be used, it's a very buggy and problematic property that additionally enforces lots of new layers, even if you try containing it
Generally, we had too many layers that weren't properly contained. We now have a bit less layers with proper containers, which additionally makes the rendering a tiny bit faster too (barely noticable on fast build, very noticable on slower machines, on Firefox in Windows VM it was 2-3x difference in terms of rendering speed for things like resizing the left panel).
Thank you, font rendering has subpixel-AA in the main chat window now. Very nice!
The contact/room names in the sidebar are still grayscale as you said, and all in-window overlays like the settings are completely grayscale as well.
Sounds good! I'm closing this issue, if the contact room/left bar is going to be unreadable then let's make another issue for that, as it's going to be another round of unrelated bugfixes. For now I think we're good though!
The issue may be closed, but the problem is not fixed. Is this going to be released soon or have you been fixing something else?