Brandon Invergo

Coredesktop

Note: this project is basically dead. What little code was written was taken out and turned into zeptodb.

Motivation

This project stems from the following thoughts:

  • Whenever you sit down to write some great new desktop application, probably less than 5% of that application idea is new or unique, while the rest is just reimplementing the same basic application machinery that's been written a million times before.
  • Most day-to-day desktop applications (i.e. not software specialized to a hyper-specific niche), despite being used for different user-level tasks, consist of many analogous underlying processes and sometimes even analogous GUIs.
  • It's frustrating to find software that looks the way you want but doesn't behave the way you want, or vice versa. Yet, mature desktop applications typically have huge code bases and complicated internal structure, making the task of changing some aspect of the software to suit your needs often more trouble than it's worth.
  • Related to the last point, huge code bases are a pain to maintain and, not surprisingly, tend not to attract new maintainers.

Description

The purpose of Coredesktop is to break down everyday desktop activities into their core steps, to provide software building blocks which perform these tasks, and then provide a variety of pre-built, generalized GUIs which allow constructing complex toolchains out of those building blocks to implement highly customized, modular desktop applications.

The Utilities

At the base of Coredesktop will be a set of small, fast command line tools written in C. Where GNU Coreutils provides the building blocks for system administration tasks, the Coredesktop utilities will provide the building blocks for desktop-related tasks. Of course, the key difference that we tend to attribute between system tasks and desktop tasks would be the presence a graphical environment. This particularly manifests itself in the rich data formats in use in desktop environments. System-level tasks require the direct editing of text; anything more would be superfluous. Desktop-level tasks often call for text formatting, image display, media playback, and so on.

Some of the most common types of application in use in desktop environments include: music library / player (Rhythmbox, Banshee), photo library (F-Spot, Shotwell), word processor (Abiword, LibreOffice Writer), spreadsheet (Gnumeric, LibreOffice Calc), email client (Evolution, Thunderbird), and the web browser (Firefox, Chromium). If we take these types of applications, we can find some commonalities between them, for example:

  • document database: music libraries (audio files), photo libraries (image files), email client (emails)
  • read/write metadata: music/photo/document libraries
  • convert file formats: office applications (ie doc -> odf), media applications (ie mp3 -> ogg, jpg -> png)
  • play/view/display/etc. a file: office applications, media applications, email client, web browser

...and so on. In some cases, the specific needs of one application are different than another: a word processor needs different file format conversion capabilities than a photo application. Nonetheless, the tasks are analogous. Furthermore, many of these tasks could be easily performed by small, dedicated tools, rather than being subject to the complicated internals of a large application. It is critical that these tools take input from stdin and ouput to stdout, allowing pipelines to be created, integrating with the powerful Coreutils tools to perform complex tasks.

The following are some ideas for specific utilities that will/could be written for Coredesktop (names subject to change, of course), along with some already- existing tools which may perform the same job. Some tools may be split into smaller ones as necessary.

  • dbm: for most basic document library applications, an SQL database is overkill. Some small tools for working with simple DBM databases will be provided. (already written: dbs (store), dbf (fetch) and dbr (remove)). Alternatives: sqlite3, mysql
  • tag: a swiss army knife for editing and retrieving metadata from the most common file types (ogg, mp3, flac, jpg, pdf, etc.). Alternatives: GNU extract
  • odf: convert rich document files to/from ODF format (initially support doc,pango markup). Alternatives: ?
  • img: convert image formats. Alternatives: imagemagick(?)
  • aud: convert audio formats. Alternatives: ?
  • aupd: audio playback daemon. Alternatives: mpd, xmms2
  • webd: web browsing daemon (manages browsing state, cookies, etc. for one or more HTML viewers). Alternatives: uzbl-core (sort of)
  • mail utilities: index/search mailboxes, list mailbox contents, etc. Many such tools already exist so this probably isn't necessary. MTAs and other aspects of mail delivery are considered system-level tasks and outside of the scope of Coredesktop. Alternatives: GNU Mailutils, emh, notmuch, and many more

The GUIs

(here things get a bit more speculative for the moment, until I look into them more) A couple of basic GUIs will be constructed using GTK3, possibly in Vala or Python. The idea will be to have a very generalized GUI built with a very broad set of tasks in mind. The specific layout of the GUI will be dynamically generated through the use of GtkBuilder. This way, the user can define exactly how they want the interface to look and respond. Each GUI will offer a limited and strictly defined subset of pre-built (so to speak) widgets which can be used in the GtkBuilder file. The GUI will also expose several predefined callbacks which can be used by the user as they wish. Customization of the GUI will take place through editing the GtkBuilder file and through an .ini-style configuration file.

Consider, as an example, a generalized interface for browsing a collection of files. Starting with this, I decide I want to make two different applications from it, a music library browser and an email client. In addition to populating a toolbar with buttons, I also have available to me a TreeView for hierarchical browsing of the collection, a set of three ListViews for Miller Column-style browsing of the collection, a single ListView, a TextView, a TextEntry, and an Image. I have callbacks available to me by a string name (note: store these in a hash table of name/functionpointer?), such as "fill- collection", "retrieve-selection", and so on. I also have a general function for invoking subprocesses.

For the music browser, I first lay out the interface in Glade. I dislike the iTunes format so I opt to put the TreeView on the left for browsing the library, with an Image for cover art below it. The ListView on the right for the playlist. In the toolbar I put the standard audio control buttons using Gtk's Stock Items. The GUI already has some default menu items for handling the collection, which are fine for now. In the config file, I then start assigning callbacks. The menu items controlling the collection are set up to use dbm to create and query a database consisting of a few different tables (separate files), for artist, album, songs, etc. For the control buttons, I hook them up to a pipeline that uses dbm to retrieve file info for the songs in the playlist and sends the data to aupd (or mpd) to play/stop/etc. the music.

For the email client, I'll be experimental and skip having a hierarchical view of my mailboxes in favor of Miller Columns. A ListView is beneath those for browsing the results of filtering or searching. Finally, a text view is beneath that for reading messages. Standard email buttons are added to the toolbar for sending, etc. The collection is filled via Mailutils programs. The buttons link up to toolchains for opening up a separate editor for composing messages, etc. Maybe I decide that the text view is a waste of vertical space, so I instead set up a toolchain to open the messages in an HTML viewer. Either way, the email first is routed through a program which parses the header and mimetypes and nicely formats the email for viewing. (this is all a bit rough but will be fleshed out soon)

Another possibility is that each GUI should make available a FIFO file in which other programs can control it (like Uzbl). Similarly, each GUI should accept input from stdin when it launches, to nicely integrate it with the rest of the tools.

Dogma

Just to be clear, I'm not dogmatic about thinking that this is the best way to design desktop applications. This is just a fun experiment that may turn out to have nice results or it might turn out to be an overly complicated mess. Perhaps the overhead of launching several small tools is still noticeably worse than just writing the functionality into your application, so that the performance won't be worth it. I don't know. But I'll go with it and see what happens.