A Gemini browser widget for Gtk4
The gemini protocol is a simple, text oriented internet communication protocol. I don't want to go into too much detail about what Gemini is, I'll leave that to the reader to research if interested. This post is about a new project to create a freestanding gemini browser widget for gtk4, much like webkit2gtk is for the web, and a simple, nice browser which leverages it.
The browser widget in question is named simply GemView and is currently in a proof of concept state, but is already useable to browse geminispace itself, with some caveats. Now obviously, there are no shortage of gemini browsers, with the likes of Lagrange, Bombadillo, Castor, and Geopard all being excellent in their own ways. However, with the exception of Lagrange I feel that some of the other options all feel distinctly unfinished in one way or another. There are details like the lack of keyboard shortcuts, or tabs, or tooltips in the interface. Bombadillo is terminal based, and it's great, but not everyone wants a cli browser. And Lagrange, as good as it is, doesn't have a native look and feel due to using sdl rather than Gtk or Qt.
I once even started a project which was a fork of Castor, called Lem (named after the lunar module from the Apollo missions) which had progressed to having tabs, keyboard shortcuts and tooltips. It even had an icon. But there were going to be issues with reworking the history functionality to work with multiple tabs, as well as bringing it up to date (Castor was using a very old version of gtk-rs). Also, why not make the work re-usable? I mean, my idea of a great browser might not be someone else's idea of a great browser, and frankly if there were a nice gemini browser widget similar to what Webkitgtk is for the big web, then there could be a proliferation of browsers which leveraged it for their own purpose, just like we have Surf, Vimb, Titanium, DWB etc which are all just a nice interface around Webkit. Nothing like that existed, and I wanted to push deeper into the Gtk+ innards than I ever have before, so I started writing it a few days ago.
I took my cue from Castor, and I suspect that Geopard does the same, and started with the Gtk+ TextView widget. I then proceeded to subclass it into my new GemView widget and begin expanding it's functionality. The book Gui development with Rust and GTK 4 has been indispensible so far as it pretty much gives a step by step lesson on subclassing using the Rust interface. I also looked at code from a few other projects, notably Fractal-next, which showed me how to get custom signals connected when the instructions in the book failed.
The outlook so far is quite good I think. The widget can already fetch, load and render gemini pages and follow links. It keeps track of the current url and the fonts used to render the various elements, which can be set to whatever the user wants. There is as yet no history, but that will be handled eventually by the widget itself, and I'm planning to add support for at least Gopher and possibly Finger protocols. Because there are quite a large number of Gopher links in geminispace, so it makes no sense to not handle them honestly. There are four custom signals that get emitted when a page load starts, on redirect, and when a page either finishes loading or has failed to load, and it is possible to connect a closure to those signals. Lots to do yet, but it's a nice start.
Now, I didn't feel much like reinventing every part of the wheel here, because there are already a lot of Gemini protocol related crates on crates.io, so I settled on the nice and trim gmi crate to handle connecting to gemini services and parsing gemtext. It even has a nice subset of the Url specification baked in, which is more than enough for our use. It currently lacks two features, client certificates and TOFU (trust on first use) support, which are part of the gemini spec, but those features are planned and I have no doubt that they will be delivered.
Meet Eva, the browser
Eva (Ee Vee Ay) means extra vehicular activity in Nasa parlance, and the browser is named in honor of Nasa's first spacewalk, which was conducted by astronaut Ed White on June 3, 1965 during the Gimini 4 mission. Eva is just one possible interface over top of GemView, but I like to think it's a good one.
It should be pretty obvious from my two larger(ish) projects, Zterm and Gfret, that I am a fan or relatively simple and uncluttered interfaces. Nevertheless, a browser is an inherently complex thing, even for the Smolweb, so we've got to fit quite a lot in without making things look overly cluttered. I took a lot of design cues from Firefox and Midori here, and I like to think that the result should be nice and easily discoverable, while eventually (once everything that is planned has been implemented) having all of the nice little creature comforts and features that one might expect from a traditional browser. If you open up the menu the planned features are easily seen, including history, bookmarks, a preferences dialog and the ability to have multiple tabs or windows open at once. Nothing too advanced here, just a nice, simple browser that looks and works exactly as you would expect a browser to. In fact I dare say that one might mistake it for a traditional web browser just by looking at the main window.
I hope to have piqued some interest in my little project here. I plan to make GemView and Eva into something very nice and boring, that just does the job asked of it very well. I hope that GemView finds it's way into someone else's project somewhere along the way as well, because after all, I want it to be used, and I want to see what your idea of a great Gemini browser looks like. Pull requests are welcome, along with any feedback via Mastodon or feel free to file an issue on either project if you have any feature requests or issues using the code.2022-02-03