Lagrange v1.11: Multiple Windows

While most of v1.10 was focused on the mobile variant, this release is very much centered on the desktop. The split view mode that was added back in v1.4 is now finally expanded to also support creation of additional windows. There is also a bunch of smaller features for a better user experience.

Multiple windows

The UI changes for splitting the view intrinsically enabled multiple windows as well, because each window is basically just an additional "UI root". However, in practice a lot of behavior splits to being app, window, or root specific. Separating the window-specific code from everything else turned out to be quite a lot of work.

The app remains a single process: while one can now open multiple windows, the runtime state is still stored in a single directory as before, and if the app crashes, all the windows will disappear.

From the user point of view, multiple windows enable a lot of flexibility. For example, one could open a window dedicated for reading feeds, another for listening to music, and then use a third window to check out random bookmarks. Much better than switching between tabs/modes in a single window.

Fontpack search

This has eased the major shortcoming of having only a limited set of fonts. The text renderer remains platform-agnostic, which has both pros and cons: every platform (desktop and mobile) can show the same content in the same way, but there may be redundancies if the system already has the same fonts installed, and some characters are difficult to deal with using a simple monochrome rasterizer (e.g., Emoji).

While v1.11 makes no fundamental changes here, there has been a big missing piece: the app would tell you if some glyphs were unavailable, but it was cumbersome to find out which characters were missing, and what's worse, no way to determine which fonts needed to be installed. This problem is now dealt with in two ways:

The search feature is pretty simple and is performed on client-side. I've generated an index of all the code points defined in the fontpacks, and it's stored in a gzipped text file here:

Each line of cmap.txt has the format:

path;size: ranges

"path" is the path of the fontpack under gemini://skyjake.fi/fonts/, "size" is the fontpack size in bytes, and "ranges" is a list of code point ranges. When you press the button to search in the font library, Lagrange will download this file via a Gemini request, decompress it, and look through the list for matching code points.

Site-specific themes

This is a new site-specific setting, and like all the other such settings, it is stored in the "sitespec.ini" file.

To customize the color theme, open "Page Information" and click on "Settings" to open the Site-Specific Settings dialog. The default keyboard shortcut for this is Shift+Ctrl+Comma (macOS: ⇧⌘,).

The "Theme palette seed" is the input data given to the theme generator that determines a site's color palette. The theme generator is designed to algorithmically choose a palette whose colors go together. It is not possible to individually pick the colors of a theme. You can enter any text as the palette seed. By default, the seed is the site's hostname, or a user name found in the URL path (e.g., "gemini://example.com/~User/" → seed "User"). Examples of how to use this:

Theme tweaks

The theme generator has been using a set of twelve hues as the basis for themes. With single-color themes like Colorful Light, this has resulted in basically only twelve different themes. In v1.11, I'm now applying additional random offsets that triple the total number of hues. It should add a bit of subtle variety between capsules.

The Black and Grey themes needed a few improvements. Both now have slightly tinted link colors to match the primary theme hue. The Black theme's banner colors were also a bit too dark, particularly since the same colors are used for the mobile toolbar as well.

As a special case, when using themes that have a bold background color, the same color is also used for the active tab button. Using the regular UI accent color there was clashing quite badly especially on mobile, where the tab buttons are the only other colored element on screen.

Data URLs

One can opt in to automatically show images encoded into data URLs, if the links fit under the configured maximum length. This only supports JPEG, PNG, WebP, and GIF formats (no animations; they are not supported by the in-app image viewer).

Please be considerate with data URLs. With these, one is able to embed arbitrary data into a Gemtext file using link lines. This makes it possible to circumvent the intentional limitations of Gemini and override the clients' ability to choose which linked resources should be loaded and when. Without a length limit, a server could for example send an arbitrarily large image attachment as part of the page, with no regard to the user's or client's preferences or abilities to view images. Such behavior is downright rude — keep Gemtext pages small, and link to resources normally unless the user has clearly indicated otherwise. Also note that like any other non-Gemini scheme, "data" is not expected to be supported by clients.

Other changes

Next steps

With every big change comes unstability, and the support for multiple windows likely has introduced a few bugs that I've missed in my testing. Please file a bug report if your system is exhibiting odd window behavior.

There's a long tail of small features and tweaks on my todo list and in the issue tracker, but for v1.12 I'm likely going to indulge in a bit of page layout improvements. It would be great to have the layout be more customizable and for there to be a few alternatives to the default.

Other big features on the horizon are native text rendering on select platforms, a detached window for Preferences, and better tab management: reordering tabs, moving tabs to/between windows, and a tab organizer sidebar would all be quite useful.

📅 2022-03-02

🏷 Lagrange

CC-BY-SA 4.0