diff --git a/Bustle/Application/Monad.hs b/Bustle/Application/Monad.hs
--- a/Bustle/Application/Monad.hs
+++ b/Bustle/Application/Monad.hs
@@ -58,24 +58,25 @@
   deriving (Functor, Monad, MonadIO)
 
 newtype BustleEnv config state =
-    BustleEnv { unBustleEnv :: IORef (config, state) }
+    BustleEnv { unBustleEnv :: (config, IORef state) }
 
 readConfig :: MonadIO m
            => BustleEnv config state
            -> m config
-readConfig = liftM fst . liftIO . readIORef . unBustleEnv
+readConfig = return . fst . unBustleEnv
 
 readState :: MonadIO m
           => BustleEnv config state
           -> m state
-readState  = liftM snd . liftIO . readIORef . unBustleEnv
+readState  = liftIO . readIORef . snd . unBustleEnv
 
 putState :: MonadIO m
          => state
          -> BustleEnv config state
          -> m ()
 putState new e = liftIO $ do
-    modifyIORef (unBustleEnv e) $ \(conf, _) -> (conf, new)
+    let (_, r) = unBustleEnv e
+    liftIO $ writeIORef r new
 
 instance MonadState state (Bustle config state) where
   get = B $ ask >>= readState
@@ -83,13 +84,9 @@
 
 instance MonadReader config (Bustle config state) where
     ask = B $ ask >>= readConfig
-    -- FIXME: I don't actually think it's possible to implement local without
-    -- keeping two refs or something. I guess I could make a temporary ioref,
-    -- and propagate any changes to the actual state part of the ref to the
-    -- outside world. This would break horribly in the face of threads. Or we
-    -- could do something like:
-    --   MVar (BConfig, MVar BState)
-    local = error "Sorry, Dave, I can't let you do that."
+    local f (B act) = B $ local (mapBustleEnv (\(e, r) -> (f e, r))) act
+      where
+        mapBustleEnv g = BustleEnv . g . unBustleEnv
 
 embedIO :: (BustleEnv config state -> IO a) -> Bustle config state a
 embedIO act = B $ do
@@ -101,5 +98,5 @@
 
 runB :: config -> state -> Bustle config state a -> IO a
 runB config s (B act) = do
-    r <- newIORef (config, s)
-    runReaderT act $ BustleEnv r
+    r <- newIORef s
+    runReaderT act $ BustleEnv (config, r)
diff --git a/Bustle/UI.hs b/Bustle/UI.hs
--- a/Bustle/UI.hs
+++ b/Bustle/UI.hs
@@ -95,7 +95,6 @@
 
 data BConfig =
     BConfig { debugEnabled :: Bool
-            , bustleIcon :: Maybe Pixbuf
             , methodIcon :: Maybe Pixbuf
             , signalIcon :: Maybe Pixbuf
             }
@@ -120,11 +119,10 @@
     -- FIXME: get a real option parser
     let debug = any isDebug args
 
-    [bustle, method, signal] <- mapM loadPixbuf
-        ["bustle.png", "dfeet-method.png", "dfeet-signal.png"]
+    [method, signal] <- mapM loadPixbuf
+        ["dfeet-method.png", "dfeet-signal.png"]
 
     let config = BConfig { debugEnabled = debug
-                         , bustleIcon = bustle
                          , methodIcon = method
                          , signalIcon = signal
                          }
@@ -339,10 +337,8 @@
   openTwoDialog <- embedIO $ \r ->
       setupOpenTwoDialog builder window $ \f1 f2 ->
           makeCallback (loadInInitialWindow (TwoLogs f1 f2)) r
-  withProgramIcon (windowSetIcon openTwoDialog)
 
   -- Set up the window itself
-  withProgramIcon (windowSetIcon window)
   embedIO $ onDestroy window . makeCallback maybeQuit
 
   -- File menu and related buttons
@@ -358,8 +354,7 @@
       onActivateLeaf openTwoItem $ widgetShowAll openTwoDialog
 
   -- Help menu
-  withProgramIcon $ \icon -> io $
-      onActivateLeaf aboutItem $ showAboutDialog window icon
+  io $ onActivateLeaf aboutItem $ showAboutDialog window
 
   m <- asks methodIcon
   s <- asks signalIcon
@@ -525,9 +520,6 @@
         updateDisplayedLog wi rr'
 
   return ()
-
-withProgramIcon :: (Maybe Pixbuf -> IO a) -> B a
-withProgramIcon f = asks bustleIcon >>= io . f
 
 loadPixbuf :: FilePath -> IO (Maybe Pixbuf)
 loadPixbuf filename = do
diff --git a/Bustle/UI/AboutDialog.hs b/Bustle/UI/AboutDialog.hs
--- a/Bustle/UI/AboutDialog.hs
+++ b/Bustle/UI/AboutDialog.hs
@@ -36,9 +36,8 @@
 
 
 showAboutDialog :: Window
-                -> Maybe Pixbuf
                 -> IO ()
-showAboutDialog window icon = do
+showAboutDialog window = do
     dialog <- aboutDialogNew
 
     license <- (Just `fmap` (readFile =<< getDataFileName "LICENSE"))
@@ -56,7 +55,7 @@
         when (resp == ResponseCancel) (widgetDestroy dialog)
     windowSetTransientFor dialog window
     windowSetModal dialog True
-    aboutDialogSetLogo dialog icon
+    aboutDialogSetLogoIconName dialog (Just "bustle")
 
     widgetShowAll dialog
 
diff --git a/INSTALL b/INSTALL
--- a/INSTALL
+++ b/INSTALL
@@ -2,17 +2,31 @@
 ====================
 
 First, make sure the Haskell Platform is installed, preferably along with the
-Gtk+ bindings for Haskell. On Debian-flavoured systems:
+Gtk+ bindings for Haskell, and some other dependencies. On Debian-flavoured
+systems, well, actually just `apt-get build-dep bustle`, but:
 
-    sudo apt-get install haskell-platform libghc-gtk-dev
+    sudo apt-get install \
+        pkg-config \
+        libdbus-1-dev \
+        libglib2.0-dev \
+        libpcap0.8-dev \
+        haskell-platform \
+        libghc-mtl-dev \
+        libghc-cairo-dev \
+        libghc-gtk-dev \
+        libghc-parsec3-dev \
+        libghc-glade-dev \
+        libghc-dbus-dev \
+        libghc-pcap-dev \
+        help2man
 
-If you can't get the Haskell Platform via your package manager, see
+(If you can't get the Haskell Platform via your package manager, see
 <http://hackage.haskell.org/platform/>. If you can't get the Gtk+ binding for
 Haskell via your package manager, you'll need to run:
 
     cabal install gtk2hs-buildtools
 
-and ensure that ~/.cabal/bin is in your PATH before continuing.
+and ensure that ~/.cabal/bin is in your PATH before continuing.)
 
 Got that? Great!
 
@@ -21,13 +35,14 @@
     # Build and install Bustle itself.
     cabal install --prefix=$PREFIX
 
-    # Build and install the stand-alone logger binary.
+    # Build and install the stand-alone logger binary, plus the icons, desktop
+    # file, etc. etc.
     make install PREFIX=$PREFIX
 
 If the Haskell Platform is not available on the platform you want to do
 some D-Bus profiling on, that's fine: the logger is written in C, and
 you can view logs generated on your fancy embedded hardware on your more
-pedestrian Linux laptop. The logger depends on a few widely-available
+pedestrian Linux laptop. The logger only depends on a few widely-available
 libraries:
 
     sudo apt-get install libglib2.0-dev libpcap-dev
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -15,8 +15,13 @@
 MANPAGE = bustle-pcap.1
 DESKTOP_FILE = bustle.desktop
 APPDATA_FILE = bustle.appdata.xml
+ICON_SIZES = 16x16 22x22 32x32 48x48 256x256
+ICONS = \
+	data/icons/scalable/bustle.svg \
+	$(foreach size,$(ICON_SIZES),data/icons/$(size)/bustle.png) \
+	$(NULL)
 
-all: $(BINARIES) $(MANPAGE) $(DESKTOP_FILE) $(APPDATA_FILE)
+all: $(BINARIES) $(MANPAGE) $(DESKTOP_FILE) $(APPDATA_FILE) $(ICONS)
 
 BUSTLE_PCAP_SOURCES = c-sources/pcap-monitor.c c-sources/bustle-pcap.c
 BUSTLE_PCAP_GENERATED_HEADERS = dist/build/autogen/version.h
@@ -51,17 +56,34 @@
 	cp $(DESKTOP_FILE) $(DATADIR)/applications
 	mkdir -p $(DATADIR)/appdata
 	cp $(APPDATA_FILE) $(DATADIR)/appdata
+	$(foreach size,$(ICON_SIZES),mkdir -p $(DATADIR)/icons/hicolor/$(size)/apps; )
+	$(foreach size,$(ICON_SIZES),cp data/icons/$(size)/bustle.png $(DATADIR)/icons/hicolor/$(size)/apps; )
+	$(MAKE) update-icon-cache
 
 uninstall:
 	rm -f $(BINDIR)/$(notdir $(BINARIES))
 	rm -f $(MAN1DIR)/$(MANPAGE)
 	rm -f $(DATADIR)/applications/$(DESKTOP_FILE)
 	rm -f $(DATADIR)/appdata/$(APPDATA_FILE)
+	$(foreach size,$(ICON_SIZES),rm -f $(DATADIR)/icons/hicolor/$(size)/apps/bustle.png)
+	$(MAKE) update-icon-cache
 
 clean:
 	rm -f $(BINARIES) $(MANPAGE) $(BUSTLE_PCAP_GENERATED_HEADERS) $(DESKTOP_FILE) $(APPDATA_FILE)
 	if test -d ./$(TARBALL_DIR); then rm -r ./$(TARBALL_DIR); fi
 	rm -f ./$(TARBALL)
+
+# Icon cache stuff
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(DATADIR)/icons/hicolor
+
+update-icon-cache:
+	@-if test -z "$(DESTDIR)"; then \
+		echo "Updating GTK+ icon cache."; \
+		$(gtk_update_icon_cache); \
+	else \
+		echo "*** Icon cache not updated.  After (un)install, run this:"; \
+		echo "***   $(gtk_update_icon_cache)"; \
+	fi
 
 # Binary tarball stuff. Please ignore this unless you're making a release.
 TOP := $(shell pwd)
diff --git a/bustle.cabal b/bustle.cabal
--- a/bustle.cabal
+++ b/bustle.cabal
@@ -1,6 +1,6 @@
 Name:           bustle
 Category:       Network, Desktop
-Version:        0.4.5
+Version:        0.4.6
 Cabal-Version:  >= 1.8
 Synopsis:       Draw pretty sequence diagrams of D-Bus traffic
 Description:    Draw pretty sequence diagrams of D-Bus traffic
@@ -8,8 +8,7 @@
 License-file:   LICENSE
 Author:         Will Thompson <will@willthompson.co.uk>
 Maintainer:     Will Thompson <will@willthompson.co.uk>
-Data-files:     data/bustle.png,
-                data/dfeet-method.png,
+Data-files:     data/dfeet-method.png,
                 data/dfeet-signal.png,
                 data/bustle.ui,
                 LICENSE
diff --git a/data/bustle.appdata.xml.in b/data/bustle.appdata.xml.in
--- a/data/bustle.appdata.xml.in
+++ b/data/bustle.appdata.xml.in
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2014 Philip Withnall <philip@tecnocode.co.uk> -->
 <application>
 	<id type="desktop">bustle.desktop</id>
-	<licence>CC BY-SA</licence>
+	<metadata_license>CC-BY-SA-3.0</metadata_license>
+	<project_license>LGPL-2.1+ and GPL-2.0+ and GPL-3.0</project_license>
 	<description>
 		<!-- Translators: These are the application description paragraphs in the AppData file. -->
 		<_p>Bustle draws sequence diagrams of D-Bus activity.</_p>
diff --git a/data/bustle.png b/data/bustle.png
deleted file mode 100644
Binary files a/data/bustle.png and /dev/null differ
diff --git a/data/bustle.ui b/data/bustle.ui
--- a/data/bustle.ui
+++ b/data/bustle.ui
@@ -5,6 +5,8 @@
     <property name="can_focus">False</property>
     <property name="default_width">900</property>
     <property name="default_height">700</property>
+    <property name="icon-name">bustle</property>
+    <property name="title" translatable="yes">Bustle</property>
     <child>
       <object class="GtkVBox" id="box1">
         <property name="visible">True</property>
@@ -52,7 +54,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="tooltip_text" translatable="yes">Display two logs—one for the session bus, one for the system bus—side by side.</property>
-                        <property name="label" translatable="yes">O_pen a pair of logs…</property>
+                        <property name="label" translatable="yes">O_pen a Pair of Logs…</property>
                         <property name="use_underline">True</property>
                       </object>
                     </child>
@@ -119,7 +121,7 @@
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">_Filter visible services…</property>
+                        <property name="label" translatable="yes">_Filter Visible Services…</property>
                         <property name="use_underline">True</property>
                         <accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </object>
@@ -224,7 +226,7 @@
                                   <object class="GtkLabel" id="balahah">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">Record a new log</property>
+                                    <property name="label" translatable="yes">Record a New Log</property>
                                   </object>
                                   <packing>
                                     <property name="expand">True</property>
@@ -270,7 +272,7 @@
                                   <object class="GtkLabel" id="balahah1">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
-                                    <property name="label" translatable="yes">Open an existing log</property>
+                                    <property name="label" translatable="yes">Open an Existing Log</property>
                                   </object>
                                   <packing>
                                     <property name="expand">True</property>
@@ -367,7 +369,7 @@
                       <object class="GtkLabel" id="label6">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Message frequencies</property>
+                        <property name="label" translatable="yes">Message Frequencies</property>
                       </object>
                       <packing>
                         <property name="tab_fill">False</property>
@@ -392,7 +394,7 @@
                       <object class="GtkLabel" id="label7">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Method durations</property>
+                        <property name="label" translatable="yes">Method Durations</property>
                       </object>
                       <packing>
                         <property name="position">1</property>
@@ -418,7 +420,7 @@
                       <object class="GtkLabel" id="label8">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Message sizes</property>
+                        <property name="label" translatable="yes">Message Sizes</property>
                       </object>
                       <packing>
                         <property name="position">2</property>
@@ -492,10 +494,11 @@
   <object class="GtkDialog" id="openTwoDialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
-    <property name="title" translatable="yes">Open a pair of logs</property>
+    <property name="title" translatable="yes">Open a Pair of Logs</property>
     <property name="resizable">False</property>
     <property name="modal">True</property>
     <property name="type_hint">dialog</property>
+    <property name="icon-name">bustle</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="visible">True</property>
