Aral Balkan

Mastodon icon RSS feed icon

How to change the colour of the underline in gspell

gspell is GNOME’s spell-checking library.

When it discovers misspelld wrds, it underlines them in dark red.

(Only, it can’t do wavy underlines so it does solid ones.)

To change the colour, say to Dracula pink for dark mode, you set gspell_text_view.underline_color = "#ff79c6";

Haha, just kidding, you can’t.

There’s a 5-year issue open to ask for an option to change the colour.

Being the Henry Ford of library makers, GNOME likely sees this lack of customisability as a feature not a bug (it’s available in any colour as long as it’s dark red).

That said, it’s both a usability and accessibility issue, so here’s a workaround for wrestling control back from the library.

Workaround

The way I ended up managing to change the colour of the underline in gspell was to apply a tag to the entire text every time the text buffer changes or someone pastes into it.

The tag sets the underline colour and I make sure the priority of the tag is set to the highest in the buffer’s tag table, thereby making it override the colour that gspell uses.

Here are the relevant bits from my app, with a pink underline.

private string PINK_UNDERLINE = "pink-underline";

private Gtk.TextView text_view;
private Gtk.TextBuffer text_buffer;
private Gspell.TextView g_spell_text_view;

private Gtk.TextTag pink_underline_tag;

construct {
    text_view = new Gtk.TextView ();
    text_buffer = text_view.get_buffer ();

    g_spell_text_view =
        Gspell.TextView.get_from_gtk_text_view (text_view);

    g_spell_text_view.basic_setup ();

    Gtk.TextTag pink_underline_tag =
        new Gtk.TextTag (PINK_UNDERLINE);

    var pink = Gdk.RGBA ();
    pink.parse ("#ff79c6");

    pink_underline_tag.underline_rgba = pink;
    text_buffer.tag_table.add (pink_underline_tag);

    text_buffer.changed.connect (override_underline_colour);
    text_buffer.paste_done.connect (override_underline_colour);
}

// …

// Workaround for the underline colour
// not being configurable in gspell.
private void override_underline_colour () {
    Gtk.TextIter text_start;
    Gtk.TextIter text_end;
    text_buffer.get_start_iter (out text_start);
    text_buffer.get_end_iter (out text_end);

    text_buffer.remove_tag_by_name (
        PINK_UNDERLINE,
        text_start,
        text_end
    );

    text_buffer.apply_tag (
        pink_underline_tag,
        text_start,
        text_end
    );

    pink_underline_tag.set_priority (
        text_buffer.get_tag_table ().get_size () - 1
    );
}

Also, as a little bonus, if you’re using gspell in your own elementary OS apps, don’t forget that you have to specify it as a dependency both for Meson/Ninja and for Flatpak separately.

In your meson.build file:

executable(
    # …
    dependencies: [
      # …
      dependency('gspell-1', version: '>=1.8.0'),
    ],
    # …
)

For Flatpak declare it as a module in your Flatpak manifest. Below is the YAML version I’m using:

modules:
  - name: gspell-1
    config-opts:
      - '--disable-static'
      - '--disable-gtk-doc'
    sources:
      - type: 'archive'
        url: 'https://download.gnome.org/sources/gspell/1.8/gspell-1.8.3.tar.xz'
        sha256: '5ae514dd0216be069176accf6d0049d6a01cfa6a50df4bc06be85f7080b62de8'
    cleanup:
      - '/bin'

Like this? Fund us!

Small Technology Foundation is a tiny, independent not-for-profit.

We exist in part thanks to patronage by people like you. If you share our vision and want to support our work, please become a patron or donate to us today and help us continue to exist.