Display Braille Characters btop, 25.11, kde plasma

Hey everyone

(I’m new to NixOS and besides the ease of being able to have a declarative approach to system management, I’ve found my way here, because I really wanted to give hyperland a try. And I didn’t feel like fucking and unfucking my Kubuntu install several times to get that to work. So here I am.)

I was trying to slowly migrate my configuration over to my new NixOS when I came across the first problem I didn’t manage to resolve on my own. Running btop, there’s a “halo” where the empty Braille characters are. This Github issue has some pictures of the problem. The issue only exists with Konsole, KWrite and Kate. Using Wezterm, the problem disappears. My guess is, under the hood, the kde applications fall back on some other font that has this horrible rendering. This means I a) need to find that setting and change the font to something usable or b) I uninstall all fonts that display Braille so poorly.

What I have done so far:

  • Initially I installed nerd-fonts.* packages (so all nerdfonts that are available) to have the best chance of working. It didn’t.
  • Changed the Font inside Konsole to be JetbrainsMono Nerd Font
  • Changed the Fixed-Width Font ins System Settings to JetbrainsMono Nerd Font
  • Attempted to find Gnu-Free-Fonts inside my fonts and also inside my packages without success.

Did somebody also encounter this issue? How did you fix it? And how do I figure out what font or what font render setting is responsible for displaying such a beautiful application like btop in such a poor way?

Thank you for your support.

AS2k

I’ve got some news: I found the font responsible for the ugly rendering!

I had ChatGPT whip up this script to test which fonts can display the Braille characters:

#!/usr/bin/env bash

BRAILLE_STR="⣸⣀⣸⣶⣤⣀⣀⣀⣀⣄⣀"

echo -e "Font Family \t\t\t | Rendering"
echo -e "----------------------------------------------------------------"

# 1. Get all fonts that are Monospace (spacing=100)
# 2. Filter for those that contain the Braille range (charset=2800)
# 3. Loop through and print the name + the string
fc-list ":spacing=100:charset=2800" family | cut -d',' -f1 | sort -u | while read -r font; do
    # We use python or perl to print because bash 'echo' can sometimes
    # struggle with specific unicode escapes in older shells
    printf "%-32s | %b\n" "$font" "$BRAILLE_STR"
done

Using that I came to the conclusion, that FreeMono is the culprit for the ugly rendering. Looking at it on nixpkgs, this is also not really surprising as it is an “outline” font apparently. It is provided by freefont_ttf.

I’m not entirely sure, if this is in fact the same font as the one in the Github Issue or if it’s something else.

I’m now facing the question, solve this problem by somehow telling nix to keep freefont_ttf out of my system (which I’d prefer honestly) or if I work with the font config and somehow define another font or fonts as a fallback if the current font cannot render a given unicode charcter.

— I’ll keep this post up to date with whatever solution I end up choosing. Tho suggestions are always appreciated.

AS2k

After a probably superfluous rabbit hole on the topic of fontconfig I’ve finally settled on a way to so solve the problem:

I’m going to

  1. Remove the default fonts and add them myself
  2. Add Noto-Fonts by Google (not all of it only what LLM suggested - so no ancient Egyptian Glyphs…)
  3. I modified the fontconfig.defaultFonts to set it according to my tasts to make sure the noto fonts take precedence in what is being used as a fallback.

To figure out what fonts are in the fonts.enableDefaultPackages = false; I ended up consulting this file. From that, I lifted the remainder, added my new noto fonts as a replacement for freefont_ttl and then I added some extra fonts I want.

fonts.packages = with pkgs; [

    dejavu_fonts
    # freefont_ttf disable this font because it looks abolutely shit.
    gyre-fonts # TrueType substitutes for standard PostScript fonts
    liberation_ttf
    unifont
    noto-fonts-color-emoji

    # To replace freefont_ttl:
    noto-fonts-cjk-sans
    noto-fonts

    # Extra fonts I put because I like.
    dina-font
    proggyfonts
  ] ++ (builtins.filter lib.isDerivation (builtins.attrValues pkgs.nerd-fonts));

Besides that - and here I’m trusting the LLM again - but so far it seems to have worked:

  fonts.fontconfig.defaultFonts = {
    # This ensures the system prefers your Nerd Font first,
    # then Noto (Solid dots), then finally Unifont (Pixelated)
    monospace = [ "JetBrainsMono Nerd Font" "Noto Sans Mono" "DejaVu Sans Mono" ];
    sansSerif = [ "Noto Sans" "DejaVu Sans" ];
    serif     = [ "Noto Serif" "DejaVu Serif" ];
  };

That way, we should hopefully never fall back to (according to the LLM) unifont - and even if that happens, what are the odds, the character we want to render is for a TUI and this one is a poor variant of it.

All in all, my font snippet for my system looks something like this. As it was slowly added, bit by bit, it may not have the most efficient layout but it works.

  # Fonts and stuff
  fonts.enableDefaultPackages = false;
  fonts.fontconfig.enable = true;
  fonts.fontDir.enable = true;
  fonts.packages = with pkgs; [

    dejavu_fonts
    # freefont_ttf disable this font because it looks abolutely shit.
    gyre-fonts # TrueType substitutes for standard PostScript fonts
    liberation_ttf
    unifont
    noto-fonts-color-emoji

    # To replace freefont_ttl:
    noto-fonts-cjk-sans
    noto-fonts

    # Extra fonts I put because I like.
    dina-font
    proggyfonts
  ] ++ (builtins.filter lib.isDerivation (builtins.attrValues pkgs.nerd-fonts));

  # Font config to force the setting of certain defaults.
  fonts.fontconfig.defaultFonts = {
    # This ensures the system prefers your Nerd Font first,
    # then Noto (Solid dots), then finally Unifont (Pixelated)
    monospace = [ "JetBrainsMono Nerd Font" "Noto Sans Mono" "DejaVu Sans Mono" ];
    sansSerif = [ "Noto Sans" "DejaVu Sans" ];
    serif     = [ "Noto Serif" "DejaVu Serif" ];
  };

On a personal note: I hope newer releases of the project no longer use this freefont_ttl and instead opt to use any other font with good / full unicode coverage.

AS2k