Posts from October 2026

Rogallo v3.1.0

2 min read; 10 GFI

Rogallo v3.1.0 is now available. This release is in response to a recent user request.

Right from the start of the development of Rogallo, I ensured that any MIME types that the application couldn't handle were correctly handed off to the operating system, to allow it to work out what to do. While it is possible for me to do some work to allow images inline -- something I might explore at some point in the future -- Rogallo doesn't currently support this and, accordingly, when faced with image/jpeg or image/png, etc, it delegates to the wider environment.

The problem, of course, is that the user might not have a tool in their environment that's capable of taking over the duties of downloading an image from a gemini URI and displaying it. So the next best thing is that Rogallo itself offers to download the file for you. With v3.1.0 this is now an option.

If you encounter a MIME type that hasn't already been marked for always opening in an external tool, there's a new Download button.

Download as an option

If selected, you'll be asked for a location to save the file.

The download dialog

To augment this, I've also added downloading support for links in the viewer. It might be, for example, that you've already marked image/jpeg and image/png as MIME types that should always be handed off to the operating system (perhaps you have a GUI-based client such as Lagrange or Major Tom installed and it's configured to pick up the URI and handle it). In that case, you'd never be shown the dialog that would allow for downloading. So now, on the occasion that you do want to download within Rogallo, you can navigate to the link and press d. The download dialog will then appear, and you can save the content of the link that way.

ℹ️ Note

If you want to change the binding for the link-based download, you can use the recently added UI element binding facility to bind gemtext_link.download_link to something else.

For now, at least, the download process is pretty simple. It follows the same approach as acquiring the content of a URI for display purposes, but instead writes it to the file you picked. There's no "download manager" or similar and no sticky "download directory". These are things I might consider adding in the future.

Rogallo v3.0.0

3 min read; 10 GFI

It's been a while since I last published an update to Rogallo. In part this is because I've had other distractions, but also in part because I've not had a huge need to add any new features of late. For the most part I feel Rogallo is "done"1.

I haven't, however, been doing nothing with the code. On and off, over the last handful of weeks, I've been addressing something that I've wanted to tidy up since the early days of development: application configuration. The majority of my Textual-based applications use a simple JSON configuration file, and that's generally good enough. When I started Rogallo I used the same approach. Rogallo has since grown quite a lot and there's much that can be configured and so the "honking great pile-o-JSON" approach was starting to feel quite untidy.

So Rogallo v3.0.0 addresses this. The headline change is that the single JSON file has been replaced with a number of focused YAML files, and some items that were in the original configuration file have been moved out to either the data directory or the state directory, depending on their purpose.

Now for some details on the changes.

❗ Important

There are a lot of changes to how Rogallo is configured. As is mentioned at the end of this post, Rogallo will make a best effort to migrate your old configuration to the new format. However, as a precaution, you might want to think about making a backup copy of your configuration.json file before upgrading Rogallo.

Focused configuration files

As mentioned above, whereas before Rogallo kept all of its configuration in a single file, it now looks to a number of different YAML files that focus on a different aspect of configuration. These include:

General configuration

For the configuration items that remain, that aren't exactly focused on a particular Rogallo feature, the settings have moved to general.yaml.

Removal of some application commands

Rogallo's design is based around the idea of some "actions" being application-wide commands, and some actions being UI-control-specific. As I worked through the configuration changes I decided that it was time to "demote" some application-wide commands to either being UI-control-specific bindings or just simple configuration properties. With this in mind I've removed the following commands:

  • ChangeCommandLineLocation
  • StripeLinks
  • ToggleANSIEscapeSequenceHandling
  • ToggleCosyLinkNumbers
  • ToggleEmojiRemoval
  • ToggleLinkNumbers

All but ChangeCommandLineLocation are now keyboard shortcuts specific to the viewer widget itself (press F1 when the viewer has focus to get more details). ChangeCommandLineLocation is now a simple configuration property in general.yaml.

UI element action keyboard bindings

From the very start, Rogallo has supported some degree of control over keyboard bindings. As mentioned above, there's a split between "application-wide commands" and "UI-element-specific" actions. Until now it's always been possible to configure the bindings for the former, but never the latter.

In other words: you could always configure the binding for the HandOffToOperatingSystem application command (hands the URI of the currently-viewed document to your OS), but you couldn't change the in-viewer binding for the o key, which opens the URI of the focused link in the OS.

Rogallo v3.0.0 adds support for changing the bindings of the latter. So if you wanted to change o to b for opening a URI externally:

gemtext_link.open_link_externally: b

You can find the bindable IDs for each of the UI controls at the bottom of each page for each of the controls.

New Gophermap badges

Not directly a configuration setup change, but something I noticed while doing the work, was the fact that Rogallo (and the underlying Gophermap library) didn't handle PNG and RTF item types. They're now directly supported.

Conclusion

I believe all of the above changes make it easier to configure Rogallo, and more importantly easier to backup and share the configuration. Technically all of this is one huge breaking change -- everything that was in configuration.json now lives elsewhere. However, I've added some code to Rogallo that detects when you still have a pre-v3.0.0 configuration active, loads up the values, creates the new files, and then renames the old file to configuration.migrated.json. As mentioned near the start of this post, you might want to think about making a backup copy of configuration.json before upgrading.


  1. One last big thing I do want to add is support for tabs. Still to come. ↩

Virtual Fighter Maneuvers

2 min read; 9 GFI

I realise I've been a bit quiet on the blog front for a few days, in part because I've also been a bit quiet on the coding front too. Looking at my GitHub contribution graph, the previous three days where I didn't commit anything are the longest run of no-commit days I've had in about 10 months. There are a couple of reasons for this: the first is that I've reached a bit of a natural pause point with my work on Rogallo (there's a biggish update brewing, but I've been taking my time with it), the second is -- as I expected -- getting my hands on the Steam Frame.

I haven't been playing with it exclusively -- when I have a good amount of free time I am back to streaming -- but I have been dipping in on occasion, and some of those occasions would be moments where I'd reach for the MacBook and bang out some code.

I'm still not set up for full-on PCVR, but I have "discovered" a game that runs really well on the Steam Frame, and it's one that's related to a favourite of mine in VR: Virtual Fighter Maneuvers.

Simply put: it's a very cut-down version of VTOL VR, designed to run well on standalone headsets. Graphically it's simplistic, and from a gameplay point of view it's very focused. There's no single-player campaign. There's no multiplayer campaign. There's no story at all. You strap on your headset, fire up the game, jump into a lobby and off you go: dogfight time!

I love it for that. I've always loved flight sims, and they're even more fun in VR. I like the slow pace and the sense of immersion. But if you're going to fly in VR it takes a bit of time to get set up and plan things. This is the total opposite. I love that I can dive in for 30 minutes, have a fun experience, and then be done. It's ideal for quick, casual sessions.

That's not to say I only want to play for those short bursts -- I have played longer sessions -- it's more to point out that it's a game that combines perfectly with the low-activation-energy accessibility of the Steam Frame. It's a game that makes the Frame feel as easy to pick up as the Steam Deck.

Of course, being a mainly multiplayer game, your chances of having a good time are mixed1. I've been into a couple of lobbies that have been really fun, with a good mix of folk, who all seem to have joined to have a good time. I've also joined matches where it's just kids wanting to be edgelords on the Internet. Thankfully, so far, it's more the former than the latter. Sadly, though, there don't seem to be that many people playing it. In my (UK timezone) evenings there's normally, at most, four matches on the go that you might be able to join.

There also seems to be a 1v1 matchmaking service so you can get a ranking by battling folk at a similar level to you (I'm a newb to the game, of course); I've yet to actually get such a match going.

This one is a keeper and I can see myself diving into it often for a good while to come.


  1. It does have bot matches too, so you can do some limited single-player gameplay. ↩