For the last chunk describing how Odysseus’s dependencies work, I’ll cover how it’s basic UI is built up around WebKit2GTK. And to start I’ll cover how GTK renders a window onscreen.
Please note that’ll be discuss GTK3 because that’s what I’m currently running.
GTK manages your UI as a hierarchy of rectangles, where the branches of this tree have their own superclass and are responsible for any layout. Layout, rendering, event dispatch, etc are all handled through a tree traversal you might be able to intuit.
A GTKWindow is a single-item branch (a “bin”) which mainly serves to hook these operations up to “GDK” whilst caching any properties, but it also manages relationships between windows, keyboard input globals for it’s subtree, etc.
Rendering involves a CSS engine and another library (for GTK3: Cairo, for GTK4: OpenGL via GSK) both of which deserves to be described on their own.
As for input events, they are received from GDK via a singular callback. Where it adjusts it for easier use in GTK and statically dispatches it to the appropriate methods (normally GTKWidget.event). As for which object receives the input that task is left entirely to the window manager & GDK, whilst GTK stores it’s objects in the GDK objects’ userdata.
As for the GDK Windows, unlike some of GDK’s other APIs it does a little bit more than simply communicating with the window manager. The specific subclass it instantiates is determined by the first display protocol it successfully opened in a specified sequence.
It has a fair bit of logic allowing both the client (itself) and server (window manager) to rerender only what has changed. And in what looks to me like an over-complication, it tracks the window hierarchy/focused-order so it can dispatch events to entirely clientside “windows”. And it constructs OpenGL and Cairo drawing surfaces for the window, with some help from the protocol-specific code.
Seperate implementations of these classes are provided per windowing protocol.
In Odysseus I take care to make it fully keyboard accessible, I’ve documented them all online, and I’ve documented most of them in relevent tooltips. This morning I want to briefly discuss how GTK implements keyboard shortcuts.
When the GtkWindow receives a keypress event, it first tries looking up and executing a keyboard shortcut. These are kept in sorted order so the lookup (and insertion/deletion) can be an efficient “binary search”.
The best way I know to explain the concept of a “binary search” is to refer to a simple number guessing game.
Say I’m thinking of a random number between 1 and 100 (inclusive), and for each guess I’ll tell you whether too high or low.
The best first guess is 50 because that divides the search space in half, and continuing that strategy it’ll only take you at most 7 guesses. This is great strategy for the computer to apply to many real-world problems!