Replacing the GNOME Shell font in GNOME 3.16

[Edit: see the comment by Hugo Roy after the article, describing a much simpler, more “official” way to achieve this]

When using Linux on a touchscreen laptop, I generally use the GNOME 3 desktop — logical design, big touch targets, good support for high-resolution displays, nice to look at.

While I mostly approve of the design decisions made for GNOME 3, there is one thing about it that I don’t get on with, and that’s its use of the Cantarell font. Cantarell is clear and readable, and a fine default for most UI text, but at the middle of the top of the screen there lives a digital clock:

Clock in Cantarelland I find this strangely annoying to look at. I think it has a lot to do with the excessively round zero. Since it’s always there, it annoys me a surprising amount.

Until GNOME 3.15, it was easy to change the font used throughout GNOME Shell by editing one property in a CSS file. Unfortunately GNOME 3.16 moved that CSS file into an opaque resource bundle and made it accessible only through some awkwardly-designed tools. I can’t fathom how that appeared to be a good idea, but there it is.

Anyway, with help from this forum post I knocked out a script to update this resource file so as to make it prefer the Fira Sans font from FirefoxOS. It makes a copy of the existing resource file with a .dist suffix.

This may be specific to Arch Linux (the distro I’m using), so caution advised if you refer to this for any reason. It’s necessary to have the glib2 and otf-fira-sans packages installed for this to work.

#!/bin/bash

set -eu

rname=gnome-shell-theme.gresource
resource="/usr/share/gnome-shell/$rname"

ext="$(date +%s)$$"
tmpdir="./fix_$ext"
mkdir "$tmpdir"
trap "rm -f $tmpdir/* ; rmdir $tmpdir" 0

manifest="$rname.xml"
cat > "$tmpdir/$manifest" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/theme">
EOF

for file in $(gresource list "$resource"); do
    base=$(basename "$file")
    out="$tmpdir/$base"
    gresource extract "$resource" "$file" > "$out"
    echo "<file>$base</file>" >> "$tmpdir/$manifest"
done

cat >> "$tmpdir/$manifest" <<EOF
</gresource>
</gresources>
EOF

(
    cd "$tmpdir"
    perl -i -p -e 's/font-family:.*;/font-family: "Fira Sans", Cantarell, Sans-Serif;/' gnome-shell.css
    glib-compile-resources "$manifest"
)

sudo cp "$resource" "$resource.dist.$ext"
sudo cp "$tmpdir/$rname" "$resource"

Of course every time an update comes along, it overwrites the resource file and I have to run this again. Which is one reason I’m posting this as a reminder to myself.

2 thoughts on “Replacing the GNOME Shell font in GNOME 3.16

    • Ah, that’s brilliant, thanks! Much simpler.

      Is this stuff documented somewhere? How did you come to know that you could do this? Presumably it’s “obvious” given a certain level of familiarity with the code project, I’m just wondering about the ignorant end-user case (like me!)

Comments are closed.