Featured image for Dev Diary 9: Koto May Progress Report (B-side)

Dev Diary 9: Koto May Progress Report (B-side)

June 10, 2021

In this development diary, I provide an update on progress made on Koto in the second half of May 2021!

#Wrap Up

In Dev Diary 8, I highlighted the following goals for Koto development over various development sessions for the second half of May:
  1. Implement the most relevant aspects of the TOML-based configuration support, ranging from setting key changes to file saving.
  2. Update our database tracks to have a reference to the Koto Library it belongs to.
  3. Update our Koto library logic and start implementing support for multiple libraries.

#Goal: All Things Configuration

In Dev Diary 8, I discussed the start of the work I did on reading in various configuration values from our TOML-based configuration. This support leverages tomlc99 for reading in various values, however unfortunately it does not support any form of saving. One of the biggest goals for development these last couple weeks has been implementing configuration saving in a manner that reduces problems with scaling up our configuration options in the future. It took a couple attempts but in the end I am pretty happy with the end result. In terms of the implementation, we do the following:
  • When constructing our KotoConfig object, we define various GObject properties, such as what is shown in this document.
  • Our property names are specifically written in a consistent manner that facilitates our iteration during saving, so that "ui-theme" would actually result in the parser saving the value of that property to "theme" in the "ui" section. We do the same for the theme-override boolean, as was as playback preferences. Adding a new setting is as simple as updating the config read logic and a single property setting for our GObject-based KotoConfig class.
What this also allows us to do is make use of GObject's property change notification signal to update various parts of the user interface, or in the case of the theme it is literally changing the entire theme of the application dynamically. Changes made within the application are saved on quitting the application, and I will be refining this behavior further so that all of the actions except noisy events like volume changing (which would then save our "last-used-volume" in the config for volume persistence) are saved whenever they are modified. Of course, implementing the configuration saving does not matter much if the settings are not actually used in the first place. So alongside the "last-used-volume" setting, I implemented all of the settings I touched on in Dev Diary 8, such as:
  1. An option to enable the continuation of playback of a playlist after selecting to play a specific track in it. This also applies to albums.
  2. An option to maintain the shuffle throughout changes in the playlists (this is enabled by default). Building on this, I will be implementing per-Playlist shuffle configuration (which was requested in a Patreon survey), so our playback engine will take that into account as well.
  3. Theme settings for choosing between three built-in themes so far (wait whaaat) and disabling the theming outright. I'll be talking about this a bit in the Theming section. This will dynamically swap the CSS provider in the application or remove it entirely (if overriding).
So next up is library configuration as well as playlist configuration, both of which I will be implementing once multi-Library functionality is implemented.

#Goal: Work on Multi-Library support

Unfortunately I was not able to get around to updating our Koto library logic to the extent I wanted, however I did start on decoupling most of the application logic from the use of a specific (as in one) Koto Library as well as eliminating its tracking of indexed music artists. Now, when indexing a Koto Library, we will check if there are any KotoArtists in our "cartographer" (our struct of various key/value stores of artists, albums, and tracks) matching the artist name. If there is (such as coming from another library, or has already been indexed for this library), we will just use that existing Koto Artist. Otherwise, we will generate a new KotoArtist like previously and add it to the KotoCartographer map. Expanding on this, a bug we had where we were not generating album and disc views on initial indexing is fixed. Yay. Right now I am struggling to determine the best model for implementing indexing across multiple libraries. One approach is "top down", where we apply a KotoLibrary's type (audiobook, music, podcasts) to inner KotoArtists, which then understand how index operations should be performed based on the type (e.g. support albums / sub-folders for audiobooks or music, direct files under a KotoArtist for podcasts). Then it is a matter of determining where we should be doing the file indexing. The other approach is "bottom up", where we index all files, then work out way up to determine its parent folders (possibly album or artist) within a given Library. The intent of the multi-library support is to ensure we can account for scenarios where you have an artist in multiple libraries, no matter how niche or unlikely that is, across multiple directories, disks, and devices. The flexibility of a KotoLibrary could also then be exploited to more easily support libraries on removal devices like mobile phones and simplify syncing. So this is all something I am working on modeling via old fashion notebook paper and pencil before I spend more time on the code.


Across mostly the last development session for this month, I spent a fair bit of time refactoring our SASS styling to make it easier to develop "built-in" themes. To accomplish this, we use a fairly common approach of variable-based styling, where you define your color palette in a variables file and if necessary, any sort of custom mixins / functions (common in SASS and LESS). This is, by-and-large, how variants of GTK themes work, and it is the same model Koto follows (in fact, I used GTK4's changes to their built-in theming as a reference point). So like shown in the featured image and again above, we now have three built-in themes:
  1. Dark (default)
  2. Light - For those that like staring at the sun.
  3. Gruvbox - Inspired by Gruvbox theming in various IDEs and Ubuntu's old Ambiance / Human themes from the ol' days.
No matter the theme you use, we will be able to correctly apply out theming on top of it. This is the result of considerable work that was put in to overriding various GTK widget styling from themes, ranging from the trough / slider, GtkPopover background color, default button coloring, and more. This helps to create a consistent user experience no matter what global GTK theme you use (since you can only override an application's specific theme via an environment variable, not an application setting via GTK). However, if you use a theme that ends up implementing styling for Koto, it will be as trivial as enabling the "theme-override" option to get their experience with no CSS changes being applied by us. Ideally I would like to provide comprehensive layout and theme class documentation out of the gate with the first stable release to help promote theming by users and GTK theme developers alike. I want you to be able to go nuts and theme it how you like, make Koto feel like home.

#Coming Up

During the first couple weeks of June, my goals are:
  1. Settle on a model I am satisfied with for multi Koto Libraries and implement it. All of it.
  2. Implement per-Playlist settings such as randomization and model (moving that out of the database too).
  3. Implement a Solarized built-in theme, since that is a fairly popular stylistic choice. I would love to hear your ideas on additional themes too, even silly / fun ones!