Lagrange v1.5: UI Polish

This version focuses on improving the user interface, with the biggest changes in identity management and text input. There are also various rendering enhancements, a new (work-in-progress) Emoji/symbol font, and a Polish UI translation.

As usual, this post is more of a director's commentary about the changes. For the detailed change log, please see the release notes.

Footer buttons

Sometimes there are specific actions that are most relevant for a given page. For example, when you've opened a file that cannot be displayed in the app, you're prompted to save it to Downloads. It improves usability to show these actions more prominently and consistently.

In this release, these buttons are used for streamlining identity management and enabling Gempub navigation (more about these below).

Identity management

The Identities sidebar has been a bit rudimentary. While v1.5 doesn't fundamentally change it, there are many little improvements that should streamline identity management nicely both when creating identities and when selecting them for use.

Among the issues with the old implementation were:

All of these issues are resolved in v1.5. Furthermore, selecting or deselecting an identity will automatically reload the current page so its state reflects the user's actions.

On certificate related error pages, the footer buttons are used for conveniently directing you to create a new identity or see the list of available ones. Below is a series of screenshots highlighting the changes.

Text input

Lagrange's text input widgets have been limited to a single horizontally scrolling line. The user experience of typing a longer message was quite poor on sites like Station. Several improvements were needed to make text entry adequate for this use case.

In v1.5, all input fields expand vertically instead of scrolling horizontally, and you can insert newlines with Shift+Return. Also, very importantly, there is now an indication of how much content can fit into the response (Gemini has a 1024 byte length limitation for URLs).

Adding word wrapping to the input widget wasn't too difficult since all the required code was already present for typesetting page content. The bigger challenges were in UI layout: dialogs needed to be dynamically updated to keep labels aligned with input fields after they expand. I chose to add a new option for widgets to keep their height synced with the height of another widget. The added complexity was quite minimal.

Smol Emoji

Lagrange has been using a font called Symbola for various symbols and some of the Emoji. However, it was pointed out that its license is not free enough to allow distributing the font with the app, so it had to go. While Symbola has good Unicode 13 coverage, it also has its problems: the font is several megabytes in size, the visual appearance of the glyphs isn’t all that nice (the face Emojis in particular are a bit tough to look at), and many of the other glyphs have an excessive amount of detail.

I am now relying heavily on Google Noto fonts for emoji and symbols, but the black and white version of Noto Emoji is out of date (six years old) and will not be updated any longer apparently. It does have many good glyphs, but the face Emoticons are downright useless.

I couldn’t find a black and white OFL font that has nice-looking Emoji, so I decided to make one myself. It is called “Smol Emoji”. There will be hundreds of glyphs to draw, but:

After drawing a hundred face Emojis I can say that I’m glad I found a nice font editing app (Glyphs Mini via Setapp). I've always been fond of drawing, and this is a nice way to apply my skills. The minimalist challenge is a great constraint as it limits the effort needed to put into each glyph. The end result will also be a smaller TTF file.

I’ve been drawing inspiration from Apple’s Emoji that are perhaps the highest-quality ones around. They do tend toward photorealism, which goes against the visual style I’m going for in Lagrange, so using the system font directly wouldn’t be ideal in any case.

Custom symbol font

There is a new setting for specifying the path of a TrueType font for symbols (Preferences > Style > Symbol font). In practice, if the built-in fonts don't have the needed glyphs, the custom symbol font is checked as a fallback.

Symbola is a good choice for the symbol font also because it covers many different scripts, so it provides non-Emoji glyphs missing from the other fonts. It is free for personal use, so if you would like to continue using it, you can download a copy from

The font must be converted to TrueType for Lagrange to use.


One advantage of having one's own custom UI toolkit is that there are no limits on adding things like transition animations. These have already been implemented for the mobile port, so I thought it was time to use them on the desktop as well. From a usability point of view, animations make it easier to understand changes in UI state. In this release, UI animations are enabled by default and affect the showing and hiding of sidebars and dialogs, so these elements don't just suddenly (dis)appear.

If you find these distracting and/or too slow on your system, the new setting Preferences > Interface > Animations can be used to disable them.

Switching up the fonts brought up minor glitches in the UI, e.g., with alignment of icons in lists. Various minor issues like this have been addressed in this release.


Next up

There are some opportunities for optimization that are pretty urgent: page layout is redone from scratch multiple times during fetching, and some events cause repeated rearrangement of the UI (particularly when there are many input fields that resize themselves). Both of these cause excess CPU use, which is an issue on mobile devices.

Having a custom font setting is a good start, but the status of the text renderer is unchanged: it needs to support bidirectional text and have a glyph compositing algorithm.

I think the Bookmarks sidebar is now due for an upgrade: it should at least have folders for better organization and for hiding groups of bookmarks. Filtering by keyword or tag could also be useful.

Summer is vacation season, though, so I'll likely end up spending more time with the family and less time typing away at the laptop. It's possible I'll skip a month in the release cycle, but we'll see how it goes.

📅 2021-05-30

🏷 Lagrange

CC-BY-SA 4.0