Saturday, September 19, 2009

Chronically Underrated: Undo

In the past years, software designers have done a lot of research not only of what a good user interface is supposed to look like, but also how it is supposed to behave. A key component (that to this day a lot of software still gets wrong) is to not bother users with dialogs, especially not those nasty modal ones, but to just do the right thing. Of course, the program can't always know what the right thing is supposed to be, so to accomodate for mistakes, the application should still shoot ahead, but offer an easy way to undo those actions again. The beautiful article "Never Use a Warning When you Mean Undo" by Aza Raskin should be a must-read for all UI developers.

Actually, this not only applies to graphical user interfaces, and clicking away dialog boxes, but also to command line interfaces. I've recently aliased rm with gvfs-trash on a few machines (including my own) for precisely that reason. Unfortunately, this alias does not work completely, but I am still hoping that I can habituate to its limitations.

Unfortunately, Claws Mail is a sinner in that respect, too. On the plus side, it makes it hard to actually loose work (so it's not guilty of Aza's worst software sin). However, in many cases it prevents data loss by distracting the user (by popping up dialog boxes), and makes it hard to revert an accidental operation (like digging up messages in the trash), so it is guilty of Aza's second and third worst software sins. Also, Claws Mail sadly doesn't come with Undo/Redo capabilities at all (well, apart from text entry in the compose window editor).

Some years ago, probably around 2004, I was looking around for a general purpose undo/redo stack that offered GObject integration for a pet project of mine. I was very disappointed to not find anything back then, so I rolled my own. It's a small class that offers undo/redo stacks (optionally with a limited stack size). Stack entries can be grouped, groups can be nested. Everything can have a description. As an optional viewer, I had a simple gtk+ widget to display undo/redo stack entry descriptions in a list (or tree, in case of groups), acting as the view in a MVC pattern. Anyways, in the end, I got distracted from the pet project, and never published it.

So, I thought I could break out the undo class from that old project, clean it up, streamline it a bit, and replace deprecated GObject/gtk+ stuff with shiny new technoligy. While doing that, I was looking around again at available undo frameworks, and was a little surprised to find one for Qt and another one for GObject, both of which I would assume to be older than my class (GUndo's ChangeLog dates back to late 2005, but some copyright headers speak of 1999). I wonder why I haven't found them earlier.. The funny thing is that both are kind of similar to what I did. Especially GUndo is (API-wise) crazily close to what I came up with (but of course, I still like mine better!). I guess there is only a limited amount of reasonable solutions to the undo/redo problem.

We'll see if it's feasible to hook up Claws Mail with an undo stack. It's usually hard to put undo capabilities into a program that hasn't been designed for that from the start. But maybe it'll be possible to put at least a few error-prone actions (like getting back a message that was falsely moved into the trash) in.


  1. This would be really great improvement!
    Thanks for this article and to move towards it, i think the undo/redo capabilities is definitely something to have, it happens several time to me to wrongly send messages in the trash and do not have a proper and easy way to restore them.
    Keep on!

  2. A simple (?) feature I'd like which is undo-related is to simply go back to the last message I viewed (like the back button in the web browser).

    When reading mailing list postings, I frequently go through the messages too fast and realise that maybe I should have read the last message when I've already moved to the next. With threading, it's sometimes surprisingly hard to find this message, and thus it would be quite nice to be able to go back to where I just came from.

    That feature would make claws mail pretty much perfect for me :-)